commit 1678f27084400f39b41adccc3089d38a26b1597f
Author: Simon Welzel <simonwelzel@live.de>
Date:   Thu Jan 24 17:22:04 2019 +0100

    Re-Added files to a newer version of AMiRo-OS

diff --git a/README.txt b/README.txt
index 83fa2b4..3088068 100644
--- a/README.txt
+++ b/README.txt
@@ -4,7 +4,7 @@ embedded devices developed by Giovanni di Sirio; see <http://chibios.org>) as
 system kernel and extends it with platform specific configurations and further
 functionalities and abstractions.
 
-Copyright (C) 2016..2018  Thomas Schöpping et al.
+Copyright (C) 2016..2019  Thomas Schöpping et al.
 (a complete list of all authors is given below)
 
 This program is free software: you can redistribute it and/or modify
@@ -55,23 +55,28 @@ the source code, and flash it to the AMiRo modules.
 
 CONTENTS:
 
-  1  Required software
+  1  Required Software
     1.1  Git
     1.2  Bootloader & Tools
     1.3  System Kernel
     1.4  Low-Level Drivers
-  2  Recommended software
+  2  Recommended Software
     2.1  gtkterm and hterm
     2.2  QtCreator IDE
     2.3  Doxygen & Graphviz
-  3  Building and flashing
+  3  Building and Flashing
+  4  Developer Guides
+    4.1  Adding a New Module
+    4.2  Handling a Custom I/O Event in the Main Thread
+    4.3  Implementing a New Low-Level Driver
+    4.4  Writing a Unit Test
 
 ================================================================================
 
 
 
 1 - REQUIRED SOFTWARE
----------------------
+=====================
 
 In order to compile the source code, you need to install the GNU ARM Embedded
 Toolchain. Since this project uses GNU Make for configuring and calling the
@@ -107,8 +112,8 @@ Since AMiRo-OS uses ChibiOS as underlying system kernel, you need to acquire a
 copy of it as well. For the sake of compatibility, it is included in AMiRo-OS as
 a Git submodule. It is highly recommended to use the ./setup.sh script for
 initialization. Moreover, you have to apply the patches to ChibiOS in order to
-make AMiRo-OS work properly. It is recommended to use the .setup.sh script for this
-purpose.
+make AMiRo-OS work properly. It is recommended to use the .setup.sh script for
+this purpose.
 If you would like to use a different kernel, you can add a subfolder in the
 ./kernel/ directory and adapt the scripts and operating system source code.
 
@@ -116,16 +121,16 @@ If you would like to use a different kernel, you can add a subfolder in the
 1.4 Low-Level Drivers
 ---------------------
 
-Any required low-level drivers for the AMiRo hardware is available in an
+Any required low-level drivers for the AMiRo hardware are available in an
 additional project: AMiRo-LLD. It is included as a Git subodule and can be
 initialized via the ./setup.sh script.
 
 
 
 2 - RECOMMENDED SOFTWARE
-------------------------
+========================
 
-AMiRo-OS can take advanatge of an installed bootloader, which is recommended for
+AMiRo-OS can take advantage of an installed bootloader, which is recommended for
 the best experience. In order to use all features of AMiRo-OS it is also
 recommended to install either the 'hterm' or 'gtkterm' application for accessing
 the robot. To ease further development, this project offers support for the
@@ -157,6 +162,11 @@ For hterm you need to configure the tool analogously. With either tool the robot
 can be reset by toggling the RTS signal on and off again, and you can access the
 system shell of AMiRo-OS. If you need legacy support for older version of
 AMiRo-BLT, you can replace the port value by '/dev/ttyUSB0'.
+Advanced users can use several connections to multiple modules simultaneously.
+Each additional programmer will be available as '/dev/ttyAMiRo<N>' (and
+'/dev/USB<N>' respectively) with <N> being an integer number starting from zero.
+Please note: Those interfaces are ordered by the time when they have been
+detected by the operating system.
 
 
 2.2 - QtCreator IDE
@@ -178,7 +188,7 @@ default versions for your system. Ubuntu users should simply run
 
 
 3 - BUILDING AND FLASHING
--------------------------
+=========================
 
 Each time you modify any part of AMiRo-OS, you need to recompile the whole
 project for the according AMiRo module. Therefore you can use the ./Makefile by
@@ -198,5 +208,218 @@ either to the DiWheelDrive or the PowerManagement module for flashing the
 operating system. All other modules are powered off after reset so that only
 these two offer a running bootloader, which is required for flashing.
 
+
+
+4 - DEVELOPER GUIDES
+====================
+
+Due to the complexity of AMiRo-OS it can be quite troublesome to get started
+with the framework at the beginning. The guides in this chapter will help you
+getting things done, without thorough knowledge of the software structure.
+Whereas the textual descriptions of the guides provide additional informatio
+about the underlying concepts and mechanisms, a short summary is provided at the
+end of each chapter.
+
+
+4.1  Adding a New Module
+------------------------
+
+The very first thing to do when adding a new module to support AMiRo-OS is to
+create an according folder in the modules/ directory. The name of this folder
+should be as unambiguous as possible (e.g. containing name and version number).
+All files, which directly depent on the hardware, and thus are not portable,
+belong here. Conversely, any code that can be reused on diferent hardware must
+not be put in the module folder.
+
+In a second step you have to initialize all requried files (see below) in the
+newlly created module directory. It is recommended to use another module as
+template for your configuration:
+- alldconf.h
+  Configuration header for the AMiRo-LLD project, which is part of AMiRo-OS.
+- aosconf.h
+  Configuration header for the AMiRo-OS project.
+- board.h & board.c
+  Contains definitions of GPIO names and initialization setting of those, as
+  well as initialization functions.
+- chconf.h
+  Configuration header for the ChibiOS/RT system kernel. There are probably only
+  very few configurations one here, since most settings depend on the content of
+  aosconf.h and are handled module unspecific in modules/aos_chconf.h
+- halconf.h
+  Configuration header for ChibiOS/HAL (hardware abstraction layer).
+- Makefile
+  The GNU make script to build and flash AMiRo-OS for the module.
+- mcuconf.h
+  Configuration file for ChibiOS/JAL to initialize the microcontroller (MCU). It
+  is recommended to check the kernel/ChibiOS/demos/ directory for an example
+  using the according MCU and copy the mcuconf.h from there. Depending on your
+  hardware you may have to modify it nevertheless, though.
+- module.h & module.c
+  These files act as some sort of container, where all module specific aliases
+  for interfaces and GPIOs, configurations, hooks, low-level drivers, and unit
+  tests are defined. These are most probably the most comprehensive files in the
+  module folder.
+- <mcu>.ld
+  Linker script, defining the memory layout and region aliases. It is
+  recommended to check ChibiOS (kernel/ChibiOS/os/common/startup/) whether a
+  linker script for the according MCU already exists.
+
+Since all these files are specific to the module hardware, youl will have to
+modify the contents according to your setup in a third step. Most settings are
+described in detail within the configuration files, but for others you will have
+to consult the datasheet of your MCU and even take a closer look at how certain
+settings are used in other modules.
+
+Finally, you need to build and flash the project. The compiler might even help
+you getting everything set up correctly. Take time to understand compilation
+errors and warning and get rid of all of those (warnings should not be ignored
+since they are hints that something might be amiss and the program will not act
+as intended).
+
+Summing up, you have to
+1) create a module directory.
+2) initialize all files (use an existing module or a ChibiOS demo as template).
+3) configure all files according to your hardware setup and preferences.
+4) compile, flash and check for issues.
+
+4.2  Handling a Custom I/O Event in the Main Thread
+---------------------------------------------------
+
+In order to handle custom I/O events in the main thread, AMiRo-OS offers several
+hooks to be used. First of all, you need to configure and enable the interrupt
+in the according GPIO. This can be done by implementing the
+MODULE_INIT_INTERRUPTS() hook in the module.h file. For information how to use
+this hook, please have a look at existing modules. In the end, the interrupt
+callback functions has to emit an I/O event with the according bit in the flags
+mask set (like the _intCallback() function in aos_system.c). As result, whenever
+a rising or falling edge (depends on configuration) is detected on that GPIO,
+the interrupt service routine is executed and hence an I/O event is fired, which
+can be catched by any thread in the system.
+
+Next, you have to configure the main thread to whitelist the event flag (all I/O
+events are blacklisted by default). While system relevant events like power down
+are whitelisted by the OS, any custom events need to be added exl´plicitely.
+This is done via the optional AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro, which
+should be defined in the module.h file. Example:
+
+  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK                \
+    (AOS_IOEVENT_FLAG(padX) | AOS_IOEVENT_FLAG(padY) | AOS_IOEVENT_FLAG(padZ))
+
+When AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK has been defined correctly, the main
+thread will be notified by the according events and execute its event handling
+routine. Hence you have to implement another macro in module.h to handle the
+custom event(s) appropriately: MODULE_MAIN_LOOP_IO_EVENT(eventflags). As you can
+see, the variable 'eventflags' is propagated to the hook. This variable is a
+mask, that allows to identify the GPIO pad(s), which caused the event, by the
+bits set. Following the example above, you can check which GPIOs have caused
+events by using if-clauses in the implementation of the hook:
+
+  #define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {           \
+    if (eventflags & AOS_IOEVENT_FLAG(padX)) {              \
+      /* handle event */                                    \
+    }                                                       \
+    if (eventflags & (AOS_IOEVENT_FLAG(padY) |              \
+          AOS_IOEVENT_FLAG(padZ))) {                        \
+      /* handle combined event */                           \
+    }                                                       \
+  }
+
+Summing up, you have to
+1) configure and enable the GPIO interrupt.
+2) define the AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro.
+3) implement the MODULE_MAIN_LOOP_IO_EVENT(eventflags) hook.
+
+4.3  Implementing a New Low-Level Driver
+----------------------------------------
+
+In the AMiRo-OS framework, low-level drivers are located in the additional Git
+project AMiRo-LLD, which is included in AMiRo-OS as Git submodule at
+periphery-lld/AMiRo-LLD/ and acts similar to a static library. When adding a new
+low-level driver to the framework, you have to implement it, providing a
+(single) header file in periphery-lld/AMiRo-LLD/include/ and the required C
+sources in periphery-lld/AMiRo-LLD/source/. By convention, all filenames use the
+prefix 'alld_' to avoid ambiguities. Furthermore, files should be named by the
+exact designation of the hardware (e.g. 'alld_vcnl4020' instead of
+'alld_proximitysensor'). Since AMiRo-LLD is intended to be usable with other
+operating systems than AMiRo-OS, it provides an interface for accessing
+communication interfaces and basic functionalities of the operating system. On
+the one hand, several types are defined in periphery-lld/AMiRo-LLD/periphALtypes.h.
+The interface functions, on the other hand, are defined by AMiRo-LLD (cf.
+periphery-lld/AMiRo-LLD/templates/periphAL.h), but implemented by the operating
+system (cf. periphery-lld/periphAL.h). For the implementation of the driver, you
+must only use those types and functions to interact with the operating system.
+If you need further functionality, which is not provided by the interface yet,
+you are encouraged to extend periphAL.
+
+Furthermore, all files must define a guard, so that the whole driver is
+disabled, when the guard is not set explicitely. These guard again are named
+following a convention, but instead of explaning it here, just have a look at
+one of the existing drivers and look for lines like
+
+  #if defined(AMIROLLD_CFG_USE_VCNL4020) || defined(__DOXYGEN__)
+
+With these guards in place, the driver will be omitted by default and needs to
+be enabled explicitely. In order to do so, you need to add an according #define
+in the alldconf.h file of any module, which shall use the new driver.
+
+Now the new driver is available and enabled, but not actually used yet.
+Therefore you have to add according memory structures to the module.h and
+module.c files - just have a look at existing modules how this is done. In some
+cases you will have to configure additional interrupts and/or alter the
+configuration of a communication interface (e.g. I²C). Once again, you should
+take a look at existing modules and search the module.h for the hooks
+MODULE_INIT_INTERRUPTS() and MODULE_INIT_PERIPHERY_COMM().
+
+Finally, you will probably want to validate your implementation via a unit test.
+How this can be done is explained in detail in the next guide.
+
+Summing up, you have to
+1) implement the driver in AMiRo-LLD using periphAL only.
+2) fence all code in all files by a guard.
+3) set the guard in alldconf.h to enable the driver.
+4) add the driver to a module.
+5) configure interrupts and interfaces as required.
+6) write a unit test.
+
+4.4  Writing a Unit Test
+------------------------
+
+AMiRo-OS provides a unit test framework for conventient testing and the ability
+to opt-out all unit tests via the aosconf.h configuration file. There is also a
+dedicated folder, where all unit test code belongs to. In case you want to
+implement a unit test for a newly developed low-level driver, you should use the
+folders unittests/periphery-lld/inc and unittests/periphery-lld/src
+respectively. As with the low-level drivers, unit test files should use a prefix
+in their name, namely 'ut_' and all code should be fenced via guards that
+disable it by default (have a look at existing unit tests). Before you implement
+a vast test, however, it is highly recommended to start with some sceleton code
+(just copy an existing unit test, scoop out the test function, and rename
+according variables etc.) and make it compile and run.
+
+After you have initialized the unit test sceleton, you have to add the according
+aos_unittest_t (cf. core/inc/aos_unittest.h) object to the module.h and module.c
+files. These objects again require an shell command, so the unit test can be run
+via the AMiRo-OS shell. As with existing unit tests, this shell command callback
+function as well as any further required data should be implemented directly in
+module.c, so it not accessable from any other context. In most cases this
+callback function is trivial, anyway.
+
+In order to make the shell command, which executes the unit test, available in
+shell so a user can run it, it has to be associated with the shell. AMiRo-OS
+provides the hook MODULE_INIT_TESTS() for this purpose, which has to be
+implemented in the module.h file. Once again I recommend to have a look at an
+existing module, how to use this hook.
+
+Since the execution pipeline is set up now, you can fille your unit test with
+life. Remember that the test is executed by the shell thread, so you can access
+any functionality of the system, but might encounter race conditions, depending
+on what other applications run concurrently.
+
+Summing up, you have to
+1) initialize a unit test sceleton in the unittests/ folder.
+2) introduce an according object and configuration in module.h and module.c.
+3) associate the shell command to a shell via the hook in module.h.
+4) implement the full unit test in the prevously created sceleton files.
+
 ================================================================================
 
