Statistics
| Branch: | Tag: | Revision:

amiro-os / README.md @ 8ba3c06b

History | View | Annotate | Download (24.292 KB)

1
About & License
2
===============
3

    
4
AMiRo-OS is an operating system for the base version of the Autonomous Mini
5
Robot (AMiRo) [1]. It utilizes ChibiOS (a real-time operating system for
6
embedded devices developed by Giovanni di Sirio; see <http://chibios.org>) as
7
system kernel and extends it with platform specific configurations and further
8
functionalities and abstractions.
9

    
10
Copyright (C) 2016..2020  Thomas Schöpping et al.
11
(a complete list of all authors is given below)
12

    
13
This program is free software: you can redistribute it and/or modify
14
it under the terms of the GNU General Public License as published by
15
the Free Software Foundation, either version 3 of the License, or (at
16
your option) any later version.
17

    
18
This program is distributed in the hope that it will be useful, but
19
WITHOUT ANY WARRANTY; without even the implied warranty of
20
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
General Public License for more details.
22

    
23
You should have received a copy of the GNU General Public License
24
along with this program.  If not, see <http://www.gnu.org/licenses/>.
25

    
26
This research/work was supported by the Cluster of Excellence
27
Cognitive Interaction Technology 'CITEC' (EXC 277) at Bielefeld
28
University, which is funded by the German Research Foundation (DFG).
29

    
30
Authors:
31

    
32
-   Thomas Schöpping (tschoepp@cit-ec.uni-bielefeld.de)
33
-   Marc Rothmann
34

    
35
References:
36

    
37
[1] S. Herbrechtsmeier, T. Korthals, T. Schopping and U. Rückert, "AMiRo: A
38
    modular & customizable open-source mini robot platform," 2016 20th
39
    International Conference on System Theory, Control and Computing (ICSTCC),
40
    Sinaia, 2016, pp. 687-692.
41

    
42
--------------------------------------------------------------------------------
43

    
44
Contents
45
========
46

    
47
1.  Required Software
48
    1.  Git
49
    2.  Bootloader & Tools (AMiRo-BLT)
50
    3.  System Kernel (ChibiOS)
51
    4.  Low-Level Drivers (AMiRo-LLD)
52
    5.  OpenOCD
53
2.  Recommended Software
54
    1.  gtkterm and hterm
55
    2.  PlantUML
56
    3.  Doxygen & Graphviz
57
    4.  QtCreator IDE
58
3.  Building and Flashing
59
4.  Developer Guides
60
    1.  Adding a Module
61
    2.  Adding a Shell Command
62
    3.  Handling a Custom I/O Event in the Main Thread
63
    4.  Implementing a Low-Level Driver
64
    5.  Writing a Test
65

    
66
--------------------------------------------------------------------------------
67

    
68
1 Required Software
69
===================
70

    
71
In order to compile the source code, you need to install the GNU ARM Embedded
72
Toolchain. Since this project uses GNU Make for configuring and calling the
73
compiler, this tool is requried too. AMiRo-OS uses ChibiOS as system kernel,
74
so you need a copy of that project as well.
75

    
76

    
77
1.1 Git
78
-------
79

    
80
Since all main- and subprojects are available as Git repositories, installing a
81
recent version of the tool is mandatory. Most Linux distributions like Ubuntu
82
provide a sufficient version in their software repositories.
83

    
84

    
85
1.2 Bootloader & Tools (AMiRo-BLT)
86
----------------------------------
87

    
88
AMiRo-OS can take advantage of an installed bootloader and provides an
89
interface. By default, AMiRo-BLT is included as Git submodule and can easily be
90
initialized via the provided `./setup.sh` script. Simply run
91

    
92
    >$ ./setup.sh
93

    
94
from a command line.
95

    
96
If requried, it is possible to replace the used bootloader by adding an
97
according subfolder in the `./bootloader/` directory. Note that you will have to
98
adapt the makefiles and scripts, and probably the operating system as well.
99

    
100
AMiRo-BLT furthermore has its own required and recommended software & tools as
101
described in its `README.md` file. Follow the instructions to initialize the
102
development environment manually or use the setup script.
103

    
104

    
105
1.3 System Kernel (ChibiOS)
106
---------------------------
107

    
108
Since AMiRo-OS uses ChibiOS as underlying system kernel, you need to acquire a
109
copy of it as well. For the sake of compatibility, it is included in AMiRo-OS as
110
Git submodule. It is highly recommended to use the setup script for
111
initialization. Moreover, you have to apply the patches to ChibiOS in order to
112
make AMiRo-OS work properly. It is recommended to use the setup script for this
113
purpose as well.
114

    
115
If you would like to use a different kernel, you can add a subfolder in the
116
`./kernel/` directory and adapt the scripts and operating system source code.
117

    
118

    
119
1.4 Low-Level Drivers (AMiRo-LLD)
120
---------------------------------
121

    
122
Any required low-level drivers for the AMiRo hardware are available in an
123
additional project: AMiRo-LLD. It is included as Git subodule and can be
124
initialized via the setup script. Since AMiRo-LLD is also used for
125
experimentation and prototyping, it contains drivers even for some hardware that
126
is not available on the AMiRo platform.
127

    
128

    
129
1.5 OpenOCD
130
-----------
131

    
132
When running AMiRo-OS on non-AMiRo modules (e.g. NUCLEO development boards),
133
those can be flashed using the OpenOCD toolchain (<http://openocd.org/>). It can
134
be either installed from the software repositories of your operating system
135
(reqiures root permissions) or built from source (no root required).  
136
For a list of supported boards, please refer to the OpcenOCD documentation.
137

    
138

    
139
2 Recommended Software
140
======================
141

    
142
The software tools named in this section are not essential for simply using or
143
further development of AMiRo-BLT, but are useful in both scenarios.
144

    
145

    
146
2.1 gtkterm and hterm
147
---------------------
148

    
149
Depending on your operating system, it is recommended to install `gtkterm` for
150
Linux (available in the Ubuntu repositories), or `hterm` for Windows. For
151
`gtkterm` you need to modify the configuration file `~/.gtktermrc` (generated
152
automatically when you start the application for the first time). For the AMiRo
153
modules the configuration is:
154

    
155
    [AMiRo]
156
    port	= /dev/ttyAMiRo0
157
    speed	= 115200
158
    bits	= 8
159
    stopbits	= 1
160
    parity	= none
161
    flow	= none
162
    wait_delay	= 0
163
    wait_char	= -1
164
    rs485_rts_time_before_tx	= 30
165
    rs485_rts_time_after_tx	= 30
166
    echo	= False
167
    crlfauto	= True
168

    
169
The according configuration for all NUCLEO boards is:
170

    
171
    [NUCLEO]
172
    port	= /dev/ttyACM0
173
    speed	= 115200
174
    bits	= 8
175
    stopbits	= 1
176
    parity	= none
177
    flow	= none
178
    wait_delay	= 0
179
    wait_char	= -1
180
    rs485_rts_time_before_tx	= 30
181
    rs485_rts_time_after_tx	= 30
182
    echo	= False
183
    crlfauto	= True
184

    
185
When running `gtkterm` from the command line, you can select a defined
186
configuration via the `-c` option:
187

    
188
    >$ gtkterm -c AMiRo
189
    >$ gtkterm -c NUCLEO
190

    
191
For `hterm` you need to configure the tool analogously. With either tool the
192
robot can be reset by toggling the RTS signal on and off again, and you can
193
access the system shell of AMiRo-OS.  
194
If you are using an old version of AMiRo-BLT, the `/dev/ttyAMiRo#` devices might
195
not be available. In order to enable legacy support, replace the port value by
196
`/dev/ttyUSB0`.
197

    
198
The configurations above use the first matching port (i.e. `/dev/ttyAMiRo0`,
199
`/dev/ttyUSB0` or `/dev/ttyACM0`). If you have connected multiple devices to
200
your system, those will be listed with increasing numbers in their identifiers.
201
Furthermore, other USB devices (also internal components) might be listed as
202
such as well. In those cases you can either adapt the configuration, or specify
203
the correct port manually. For gtkterm the according call on the command line
204
would be:
205

    
206
    >$ gtkterm -c AMiRo -p=/dev/ttyAMiRo#
207

    
208
where you have to replace the trailing `#` with the according integer.  
209
Note that those interfaces are ordered by the time when they have been detected
210
by the operating system, so detaching a cable and plugging it in again may
211
result in a different port name.
212

    
213

    
214
2.2 PlantUML
215
------------
216

    
217
PlantUML is a free and open source Java tool to generate UML diagrams via scrips
218
(see <https://plantuml.com>). AMiRo-OS provides according scripts in the
219
`./doc/` directory. Please refer to the PlantUML documentation for how to
220
generate figures from these script files.
221

    
222

    
223
2.3 Doxygen & Graphviz
224
----------------------
225

    
226
In order to generate the documentation from the source code, Doxygen and
227
Graphviz are requried. It is recommended to install these tools using the
228
default versions for your system. Ubuntu users should simply run
229

    
230
    >$ sudo apt-get install doxygen graphviz
231

    
232

    
233
2.4 QtCreator IDE
234
-----------------
235

    
236
AMiRo-OS provides support for the QtCreator IDE. In order to setup according
237
projects, use the setup script and follow the instructions. It will
238
automatically generate the required files and you can import the projects by
239
opening the `.creator` files with QtCreator IDE.  
240
Please note that you will need to recompile the AMiRo-OS source code after each
241
project generation, since the generator runs a compiler call.
242

    
243
Further instructions for a more advanced configuration of the IDE are provided
244
in the `./tools/qtcreator/README.txt` file.
245

    
246

    
247

    
248
3 Building and Flashing
249
=======================
250

    
251
Each time you modify any part of AMiRo-OS, you need to recompile the whole
252
project for the according AMiRo module. Therefore you can use the `./Makefile`
253
by simply executing `make` and follow the instructions:
254

    
255
    >$ cd /path/to/AMiRo-OS/root/
256
    >$ make
257

    
258
Alternatively, you can either use the makefiles provided per module in
259
`./modules/<module_to_compile>/` or the makefile in the `./modules/` folder.
260
After the build process has finished successfully, you always have to flash the
261
generated program to the module. Therefore you need an appropriate tool, such as
262
`SerialBoot` for the AMiRo base modules (provided by AMiRo-BLT) or OpenOCD.
263
Similar to the compilation procedure as described above, you can flash either
264
each module individually, or all modules at once by using the same makefiles.
265

    
266
When using `SerialBoot`, please note that you must connect the programming cable
267
either to the _DiWheelDrive_ or the _PowerManagement_ module for flashing the
268
operating system. All other modules are powered off after reset so that only
269
these two offer a running bootloader, which is required for flashing.
270

    
271
As already described for the serial connection via gtkterm or hterm, all scripts
272
use the first matching port (i.e. `/dev/ttyAMiRo0`, `/dev/ttyUSB0` or
273
`/dev/ttyACM0`) by default. If you need to specify a custom port, you can do so
274
by passing an additional argument to the make call:
275

    
276
    >$ make flash FLASH_PORT=/dev/ttyAMiRo#
277

    
278
where you have to replace the trailing `#` with the according integer.
279

    
280

    
281
4 Developer Guides
282
==================
283

    
284
Due to the complexity of AMiRo-OS it can be quite troublesome to get started
285
with the framework at the beginning. The guides in this chapter will help you
286
getting things done, without thorough knowledge of the software structure.
287
Whereas the textual descriptions of the guides provide in-depth information
288
about the underlying concepts and mechanisms, a short summary is provided at the
289
end of each chapter.
290

    
291

    
292
4.1 Adding a Module
293
-------------------
294

    
295
The very first thing to do when adding a new module to support AMiRo-OS, is to
296
create an according folder in the `./modules/` directory. The name of this
297
folder should be as unambiguous as possible (e.g. containing name and version
298
number). All files, which directly depent on the hardware, and thus are not
299
portable, belong here. Conversely, any code that can be reused on diferent
300
hardware should not be placed in this module folder.
301

    
302
In a second step you have to initialize all requried files (see below) in the
303
newly created module directory. It is recommended to use another module as
304
template for your configuration:
305

    
306
*   alldconf.h  
307
    Configuration header for the AMiRo-LLD project, which is part of AMiRo-OS.
308
    There are probably only very few configurations done here, since most
309
    settings depend on the content of aosconf.h and are handled module
310
    unspecifically in the `./modules/aos_alldconf.h` file.
311
*   aosconf.h  
312
    Configuration header for the AMiRo-OS project. Existing cofiguration files
313
    are well documented and name all available settings.
314
*   board.h & board.c  
315
    Contains definitions of GPIO names and initialization settings of those, as
316
    well as initialization functions. These configurations highly depend on the
317
    hardware setup. For further information, please refer to the ChibiOS
318
    documentation. ChibiOS also provides demo code for various devices.
319
*   chconf.h  
320
    Configuration header for the ChibiOS/RT system kernel. There are probably
321
    only very few configurations done here, since most settings depend on the
322
    content of aosconf.h and are handled module unspecifically in the
323
    `./modules/aos_chconf.h` file.
324
*   halconf.h  
325
    Configuration header for ChibiOS/HAL (hardware abstraction layer). Existing
326
    files are well documented and name all available settings. Please refer to
327
    ChibiOS for further details.
328
*   Makefile  
329
    The GNU make script to build and flash AMiRo-OS for the module.
330
*   mcuconf.h  
331
    Configuration file for ChibiOS/HAL to initialize the microcontroller (MCU).
332
    It is recommended to check the `./kernel/ChibiOS/demos/` directory for an
333
    example using the according MCU and copy the mcuconf.h from there. Depending
334
    on your hardware setup you may have to modify it nevertheless, though.
335
*   module.h & module.c  
336
    These files act as some sort of container, where all module specific aliases
337
    for interfaces and GPIOs, configurations, hooks, low-level drivers, and
338
    tests are defined. These are the most comprehensive files in the module
339
    folder.
340
*   <mcu\>.ld  
341
    Linker script, defining the memory layout and region aliases. It is
342
    recommended to check ChibiOS (`./kernel/ChibiOS/os/common/startup/`) whether
343
    a linker script for the according MCU already exists.
344

    
345
Since all these files are specific to the module hardware, you will have to
346
modify the contents according to your setup in a third step. Most settings are
347
described in detail within the configuration files, but for others you will have
348
to consult the datasheet of your MCU and even take a closer look at how certain
349
settings are used in other modules.
350

    
351
Finally, you need to build and flash the project. The compiler might even help
352
you getting everything set up correctly. Take the time needed to understand
353
compilation errors and warnings and get rid of all of those (warnings should not
354
be ignored since they are hints that something might be amiss and the program
355
will not act as intended).
356

    
357
As you will probably notice, for most modules there is an additional `test/`
358
folder. This folder contains module specific wrapper code for tests (e.g. for
359
hardware devices). Since tests are not essential but a more advanced feature,
360
a separate guide describes how to write a test in section 4.5.
361

    
362
**Summing up, you have to**
363

    
364
1.  create a module directory.
365
2.  initialize all files (use an existing module or a ChibiOS demo as template).
366
3.  configure all files according to your hardware setup and preferences.
367
4.  compile, flash and check for issues.
368

    
369

    
370
4.2 Adding a Shell Command
371
--------------------------
372

    
373
Before going into the technical details, how a new shell command is initialized
374
and registered to a shell, some basic concepts of the AMiRo shell should be
375
covered first. Most fundamentally, although for most use cases a single shell
376
instance on a module will suffice, there can be an arbitrary number of shells.
377
Each shell runs in its own thread and has an exclusive list of shell commands.
378
That said, each shell command can be registered to only one (or none) shell.  
379
Another important aspect of the AMiRo shell are the I/O streams. Each shell
380
reads and writes from/to a shell stream. Such a stream may again contain an
381
arbitrary number of channels. Whilst only one of those channels can be selected
382
as input, each and all channels can be configured as output. As a result, if a
383
hardware module features multiple I/O interfaces, according configuration of the
384
shell stream and its channels allows to still use only a single shell instance.
385
If not disabled in the aosconf.h file, AMiRo-OS already runs a system shell in
386
a thread with minimum priority.
387

    
388
Depending on the configuration, several commands are registered to the system
389
shell by default (e.g. `kernel:test`, `module:info`), which are defined in the
390
AMiRo-OS core. In order to add additional custom commands, those should be
391
defined in the module.h and module.c files. First you need to _declare_ the
392
shell command - an instance of the memory structure representing a command - in
393
the module.h file. Second, you have to _define_ that structure in the module.c
394
file via the `AOS_SHELL_COMMAND(var, name, callback)` macro function. This macro
395
takes three arguments:
396

    
397
1.  `var`  
398
    Name of the variable (must be identical to the _declaration_).
399
2.  `name`  
400
    Command string which will be shown and used in the shell. By convention,
401
    command names follow a colon notation, e.g. `module:info`, where the first
402
    part denotes the scope of the command (e.g. kernel, module, tests, etc.) and
403
    the second part specifies the command in this scope.
404
3.  `callback`  
405
    Callback function to be executed by the command.
406

    
407
The callback function is typically defined right before the
408
`AOS_SHELL_COMMAND()` macro is called and should be a mere wrapper, calling
409
another function. Keep in mind, though, that those callbacks are executed within
410
the shell thread and thus inherit its (typically very low) priority and there is
411
no way to call a command in a non-blocking manner. If you want to use a shell
412
command to start/stop other components in your system, those should be
413
implemented in dedicated threads and the shell command callbacks have to use
414
inter process communication to manage and interface those components.
415

    
416
Finally, you have to register the command to a shell. This is very important and
417
a common mistake, but naturally a shell can only access commands, which are
418
known to it. Registration is done via the `aosShellAddCommand()` function,
419
preferably before the shell thread is started. Since test commands are the most
420
common use case, AMiRo-OS provides the hook `MODULE_INIT_TESTS()`, which is
421
defined in each module.h file.
422

    
423
**Summing up, you have to**
424

    
425
1.  declare and define a command.
426
2.  implement a callback function.
427
3.  register the command to a shell.
428

    
429

    
430
4.3 Handling a Custom I/O Event in the Main Thread
431
--------------------------------------------------
432

    
433
In order to handle custom I/O events in the main thread, AMiRo-OS offers several
434
hooks to be used. First of all, you need to configure and enable the interrupt
435
for the according GPIO. This can be done by implementing the
436
`MODULE_INIT_INTERRUPTS()` hook in the module.h file. For information how to use
437
this hook, please have a look at existing modules. In the end, the according
438
interrupt callback function has to emit an I/O event with the according bit in
439
the flags mask set (such as the `_gpioCallback()` function in
440
`./core/src/aos_system.c`). As result, whenever a rising or falling edge
441
(depends on configuration) is detected on that particular GPIO, the interrupt
442
service routine is executed and hence an I/O event is emitted, which can be
443
received by any thread in the system.
444

    
445
Next, you have to explicitely whitelist the event flag for the main thread,
446
because it ignores all I/O events other than power down and such by default.
447
This is done via the optional `AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK` macro,
448
which should be defined in the module.h file, for example:
449

    
450
    #define AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK         \
451
            (AOS_GPIOEVENT_FLAG(padX) | AOS_GPIOEVENT_FLAG(padY) | AOS_GPIOEVENT_FLAG(padZ))
452

    
453
When `AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK` has been defined correctly, the
454
main thread will be notified by the according events and execute its event
455
handling routine. Hence you have to implement another macro in module.h to
456
handle the custom event(s) appropriately:
457
`MODULE_MAIN_LOOP_GPIOEVENT(eventflags)`. As you can see, the variable
458
`eventflags` is propagated to the hook. This variable is a mask, that allows to
459
identify the GPIO pad(s), which caused the event, by the individually set bits.
460
Following the example above, you can check which GPIOs have caused events by
461
using if-clauses in the implementation of the hook:
462

    
463
    #define MODULE_MAIN_LOOP_GPIOEVENT(eventflags) {          \
464
      if (eventflags & AOS_GPIOEVENT_FLAG(padX)) {            \
465
        /* handle event */                                    \
466
      }                                                       \
467
      if (eventflags & (AOS_IOEVENT_FLAG(padY) |              \
468
            AOS_GPIOEVENT_FLAG(padZ))) {                      \
469
        /* handle combined event */                           \
470
      }                                                       \
471
    }
472

    
473
**Summing up, you have to**
474

    
475
1.  configure and enable the GPIO interrupt.
476
2.  define the AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK macro.
477
3.  implement the MODULE_MAIN_LOOP_GPIOEVENT(eventflags) hook.
478

    
479

    
480
4.4 Implementing a Low-Level Driver
481
-----------------------------------
482

    
483
In the AMiRo-OS framework, low-level drivers are located in the additional Git
484
project AMiRo-LLD, which is included in AMiRo-OS as Git submodule at
485
`./periphery-lld/AMiRo-LLD/` and acts similar to a static library. When adding a
486
new low-level driver to the framework, you first have to implement it of course.
487
For details how to do so, please follow the instructions given in the
488
`README.md` file in the AMiRo-LLD root directory.
489

    
490
Now that the new driver is available, it can be enbled by simply including the
491
driver's make script in the makefile of the module, you are working on. In order
492
to make actual use of the driver, you have to add according memory structures to
493
the module.h and module.c files - just have a look at existing modules how this
494
is done. In some cases you will have to configure additional interrupts and/or
495
alter the configuration of a communication interface (e.g. I2C). Once again, you
496
should take a look at existing modules and search the module.h for the hooks
497
`MODULE_INIT_INTERRUPTS()`, `MODULE_INIT_PERIPHERY_IF()` and
498
`MODULE_SHUTDOWN_PERIPHERY_IF()`.
499

    
500
Finally, you will probably want to validate your implementation via a test. How
501
this can be done is explained in detail in the next guide.
502

    
503
**Summing up, you have to**
504

    
505
1.  implement the driver in AMiRo-LLD using periphAL only.
506
2.  add the driver to a module (Makefile, module.h and module.c).
507
3.  configure interrupts and interfaces as required.
508
4.  write a test to verify your setup.
509

    
510

    
511
4.4 Writing a Test
512
------------------
513

    
514
AMiRo-OS provides a test framework for conventient testing and the ability to
515
opt-out all tests via the aosconf.h configuration file. There is also a
516
dedicated folder, where all test code belongs to. In case you want to implement
517
a test for a newly developed low-level driver, you should have a look at the
518
folder `./test/periphery-lld/`. As with the low-level drivers, tests are placed
519
in individual subfolders (e.g. `./test/periphery-lld/DEVICE1234_v1`) and all
520
files should use the prefix `aos_test_` in their name. Moreover, all code must
521
be fenced by guards that disable it completely if the `AMIROOS_CFG_TESTS_ENABLE`
522
flag is set to false in the aosconf.h configuration file.
523

    
524
Now you have to add the test to a specific module. Therefore, you should create
525
a `test/` directory in the module folder, if such does not exist yet. In this
526
directory, you create another subfolder, e.g. `DEVICE1234/` and three additional
527
files in there:
528

    
529
*   module_test_DEVICE1234.mk
530
*   module_test_DEVICE1234.h
531
*   module_test_DEVICE1234.c
532

    
533
The make script is not required, but recommended to achieve maintainable code.
534
This script should add the folder to the `MODULE_INC` variable and all C source
535
files to `MODULE_CSRC`. The header and source files furthermore define module
536
specific data structures and a test function. In order to clearly indicate that
537
these files are module specific wrappers, their names should begin with the
538
`module_test_` prefix.
539

    
540
In order to be able to call such test function as a command via the AMiRo-OS
541
shell, you need to add an according shell command to the module.h and module.c
542
files. Whereas the command itself is typically very simple, just calling the
543
callback function defined in the
544
`./test/DEVICE1234/module_test_DEVICE1234.h`/`.c` files, you have to add the
545
command to a shell. In order to make the command available in a shell so a user
546
can run it, it has to be associated with the shell. AMiRo-OS provides the hook
547
`MODULE_INIT_TESTS()` for this purpose, which has to be implemented in the
548
module.h file. Once again it is recommended to have a look at an existing
549
module, how to use this hook. Furthermore, there is more detailled guide on
550
adding shell commands.
551

    
552
**Summing up, you have to**
553

    
554
1.  implement the common test in the `./test/` folder.
555
2.  implement a module specific wrapper in the `./modules/<module>/test/`
556
    folder.
557
3.  associate the shell command to a shell via the `MODULE_INIT_TESTS()` hook in
558
    module.h.
559