AMiRo-OS is an operating system for the base version of the Autonomous Mini Robot (AMiRo) [1]. It utilizes ChibiOS (a real-time operating system for embedded devices developed by Giovanni di Sirio; see ) as system kernel and extends it with platform specific configurations and further functionalities and abstractions. Copyright (C) 2016..2020 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 it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . This research/work was supported by the Cluster of Excellence Cognitive Interaction Technology 'CITEC' (EXC 277) at Bielefeld University, which is funded by the German Research Foundation (DFG). Authors: - Thomas Schöpping - Marc Rothmann References: [1] S. Herbrechtsmeier, T. Korthals, T. Schopping and U. Rückert, "AMiRo: A modular & customizable open-source mini robot platform," 2016 20th International Conference on System Theory, Control and Computing (ICSTCC), Sinaia, 2016, pp. 687-692. ################################################################################ # # # RRRRRRRR EEEEEEEE AAA DDDDDDDD MM MM EEEEEEEE # # RR RR EE AA AA DD DD MMM MMM EE # # RR RR EE AA AA DD DD MMMM MMMM EE # # RRRRRRRR EEEEEE AA AA DD DD MM MMM MM EEEEEE # # RR RR EE AAAAAAAAA DD DD MM MM EE # # RR RR EE AA AA DD DD MM MM EE # # RR RR EEEEEEEE AA AA DDDDDDDD MM MM EEEEEEEE # # # ################################################################################ This file will help you to setup all required software on your system, compile the source code, and flash it to the AMiRo modules. ================================================================================ CONTENTS: 1 Required Software 1.1 Git 1.2 Bootloader & Tools 1.3 System Kernel 1.4 Low-Level Drivers 2 Recommended Software 2.1 gtkterm and hterm 2.2 QtCreator IDE 2.3 Doxygen & Graphviz 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 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 compiler, this tool is requried too. AMiRo-OS uses ChibiOS as system kernel, so you need a copy of that project as well. 1.1 - Git --------- Since all main- and subprojects are available as Git repositories, installing a recent version of the tool is mandatory. 1.2 Bootloader & Tools ---------------------- AMiRo-OS can take advantage of an installed bootloader if such exists and provides an interface. By default, AMiRo-BLT is included as a Git submodule and can easily be initialized via the ./setup.sh script. If requried, you can replace the used bootloader by adding an according subfolder in the ./bootloader directory. Note that you will have to adapt the makefiles and scripts, and probably the operating system as well. AMiRo-BLT furthermore has its own required and recommended software tools as described in its README.txt file. Follow the instructions to initialize the development environment manually or use the ./setup.sh script. 1.3 System Kernel ----------------- 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. 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. 1.4 Low-Level Drivers --------------------- 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 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 QtCreator IDE. 2.1 - gtkterm and hterm ----------------------- Depending on your operating system it is recommended to install 'gtkterm' for Linux (available in the Ubuntu repositories), or 'hterm' for Windows. For gtkterm you need to modify the configuration file ~/.gtktermrc (generated automatically when you start the application for the first time). For the AMiRo modules the configuration is: port = /dev/ttyAMiRo0 speed = 115200 bits = 8 stopbits = 1 parity = none flow = none wait_delay = 0 wait_char = -1 rs485_rts_time_before_tx = 30 rs485_rts_time_after_tx = 30 echo = False crlfauto = True The according configuration for all NUCLEO boards is: port = /dev/ttyACM0 speed = 115200 bits = 8 stopbits = 1 parity = none flow = none wait_delay = 0 wait_char = -1 rs485_rts_time_before_tx = 30 rs485_rts_time_after_tx = 30 echo = False crlfauto = True 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' (and '/dev/ttyUSB' respectively) with 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, so detaching a cable and plugging it in again may result in a different port name. 2.2 - QtCreator IDE ------------------- In order to setup QtCreator projects any supported module, you can use the provided ./setup.sh script. Further instructions for a more advanced configuration of the IDE are provided in the ./tools/qtcreator/README.txt file. 2.3 Doxygen & Graphviz ----------------------- In order to generate the documentation from the source code, Doxygen and Graphviz are requried. It is recommended to install these tool using the default versions for your system. Ubuntu users should simply run >$ sudo apt-get install doxygen graphviz 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 simply executing 'make' and follow the instructions. Alternatively, you can either use the makefiles provided per module in ./os/modules/ or - if you want to compile all modules at once - the makefile in the ./os/modules folder. After the build process has finished successfully, you always have to flash the generated program to the module. Therefore you need an appropriate tool, such as stm32flash (if you don't use a bootloader) or SerialBoot (highly recommended; provided by AMiRo-BLT). Similarly to the compilation procedure as described above, you can flash either each module separately, or all modules at once by executing 'make flash' from the according directory. When using SerialBoot, please note that you must connect the programming cable 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 information 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 this module folder. In a second step you have to initialize all requried files (see below) in the newly 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. There are probably only very few configurations done here, since most setting depend on the content of aosconf.h and are handled modue unspecifically in in modules/aos_alldconf.h - 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 done here, since most settings depend on the content of aosconf.h and are handled module unspecifically 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/HAL 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. - .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 the time needed to understand compilation errors and warnings 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 for 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 _gpioCallback() function in aos_system.c). As result, whenever a rising or falling edge (depends on configuration) is detected on that particular 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 imlicitely whitelisted by the OS, any custom events need to be added exlplicitely. This is done via the optional AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK macro, which should be defined in the module.h file. Example: #define AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK \ (AOS_GPIOEVENT_FLAG(padX) | AOS_GPIOEVENT_FLAG(padY) | AOS_GPIOEVENT_FLAG(padZ)) When AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK 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_GPIOEVENT(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 individually set bits. 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_GPIOEVENT(eventflags) { \ if (eventflags & AOS_GPIOEVENT_FLAG(padX)) { \ /* handle event */ \ } \ if (eventflags & (AOS_IOEVENT_FLAG(padY) | \ AOS_GPIOEVENT_FLAG(padZ))) { \ /* handle combined event */ \ } \ } Summing up, you have to 1) configure and enable the GPIO interrupt. 2) define the AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK macro. 3) implement the MODULE_MAIN_LOOP_GPIOEVENT(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, following the instructions given in periphery-lld/AMiRo-LLD/README.txt Now the new driver is available and can be enbled by simply including the driver's makefile script in the module makefile. In order to make actuale use of the driver 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(), MODULE_INIT_PERIPHERY_IF and MODULE_SHUTDOWN_PERIPHERY_IF(). Finally, you will probably want to validate your implementation via a 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. 4) add the driver to a module (Makefile, module.h and module.c). 5) configure interrupts and interfaces as required. 6) write a test. 4.4 Writing a Test ------------------------ AMiRo-OS provides a test framework for conventient testing and the ability to opt-out all tests via the aosconf.h configuration file. There is also a dedicated folder, where all test code belongs to. In case you want to implement a test for a newly developed low-level driver, you should have a look at the folder test/periphery-lld/. As with the low-level drivers, tests are placed in individual subfolders (e.g. test/periphery-lld/DEVICE1234_v1) and all should use the prefix 'aos_test_' in their name. Moreover, all code must be fenced by guards that disable it completely if the AMIROOS_CFG_TESTS_ENABLE flag is set to false in the aosconf.h configuration file. Now you will need to add the test to a specific module. Therefore, you should create a new test/ directory in the module folder, if such does not exist yet. In this directory, you create another subfolder, e.g. DEVICE1234/ and three additional files in there: - module_test_DEVICE1234.mk - module_test_DEVICE1234.h - module_test_DEVICE1234.c The makefile script is not required, but recommended to achieve maintainable code. This script file should add the folder to the MODULE_INC variable and all C source files to MODULE_CSRC. The .h and .c files furthermore define module specific data structures and a test function. In order to be able to call this function as a command via the AMiRo-OS shell, you need to add an according shell command to the module.h and module.c files. Whereas the command itself is typically very simple, just calling the callback function defined in the test/DEVICE1234/module_test_DEVICE1234.h/.c files, you have to add the command to a shell. In order to make the shell command, which executes the test, available in a 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. Summing up, you have to 1) implement the test in the test/ folder. 2) implement a module specific wrapper in the module/test/ folder. 3) associate the shell command to a shell via the hook in module.h. ================================================================================