Revision 8fd2fd44 README.txt

View differences:

README.txt
55 55

  
56 56
CONTENTS:
57 57

  
58
  1  Required software
58
  1  Required Software
59 59
    1.1  Git
60 60
    1.2  Bootloader & Tools
61 61
    1.3  System Kernel
62 62
    1.4  Low-Level Drivers
63
  2  Recommended software
63
  2  Recommended Software
64 64
    2.1  gtkterm and hterm
65 65
    2.2  QtCreator IDE
66 66
    2.3  Doxygen & Graphviz
67
  3  Building and flashing
67
  3  Building and Flashing
68
  4  Developer Guides
69
    4.1  Adding a New Module
70
    4.2  Handling a Custom I/O Event in the Main Thread
71
    4.3  Implementing a New Low-Level Driver
72
    4.4  Writing a Unit Test
68 73

  
69 74
================================================================================
70 75

  
71 76

  
72 77

  
73 78
1 - REQUIRED SOFTWARE
74
---------------------
79
=====================
75 80

  
76 81
In order to compile the source code, you need to install the GNU ARM Embedded
77 82
Toolchain. Since this project uses GNU Make for configuring and calling the
......
123 128

  
124 129

  
125 130
2 - RECOMMENDED SOFTWARE
126
------------------------
131
========================
127 132

  
128 133
AMiRo-OS can take advantage of an installed bootloader, which is recommended for
129 134
the best experience. In order to use all features of AMiRo-OS it is also
......
183 188

  
184 189

  
185 190
3 - BUILDING AND FLASHING
186
-------------------------
191
=========================
187 192

  
188 193
Each time you modify any part of AMiRo-OS, you need to recompile the whole
189 194
project for the according AMiRo module. Therefore you can use the ./Makefile by
......
203 208
operating system. All other modules are powered off after reset so that only
204 209
these two offer a running bootloader, which is required for flashing.
205 210

  
211

  
212

  
213
4 - DEVELOPER GUIDES
214
====================
215

  
216
Due to the complexity of AMiRo-OS it can be quite troublesome to get started
217
with the framework at the beginning. The guides in this chapter will help you
218
getting things done, without thorough knowledge of the software structure.
219
Whereas the textual descriptions of the guides provide additional informatio
220
about the underlying concepts and mechanisms, a short summary is provided at the
221
end of each chapter.
222

  
223

  
224
4.1  Adding a New Module
225
------------------------
226

  
227
The very first thing to do when adding a new module to support AMiRo-OS is to
228
create an according folder in the modules/ directory. The name of this folder
229
should be as unambiguous as possible (e.g. containing name and version number).
230
All files, which directly depent on the hardware, and thus are not portable,
231
belong here. Conversely, any code that can be reused on diferent hardware must
232
not be put in the module folder.
233

  
234
In a second step you have to initialize all requried files (see below) in the
235
newlly created module directory. It is recommended to use another module as
236
template for your configuration:
237
- alldconf.h
238
  Configuration header for the AMiRo-LLD project, which is part of AMiRo-OS.
239
- aosconf.h
240
  Configuration header for the AMiRo-OS project.
241
- board.h & board.c
242
  Contains definitions of GPIO names and initialization setting of those, as
243
  well as initialization functions.
244
- chconf.h
245
  Configuration header for the ChibiOS/RT system kernel. There are probably only
246
  very few configurations one here, since most settings depend on the content of
247
  aosconf.h and are handled module unspecific in modules/aos_chconf.h
248
- halconf.h
249
  Configuration header for ChibiOS/HAL (hardware abstraction layer).
250
- Makefile
251
  The GNU make script to build and flash AMiRo-OS for the module.
252
- mcuconf.h
253
  Configuration file for ChibiOS/JAL to initialize the microcontroller (MCU). It
254
  is recommended to check the kernel/ChibiOS/demos/ directory for an example
255
  using the according MCU and copy the mcuconf.h from there. Depending on your
256
  hardware you may have to modify it nevertheless, though.
257
- module.h & module.c
258
  These files act as some sort of container, where all module specific aliases
259
  for interfaces and GPIOs, configurations, hooks, low-level drivers, and unit
260
  tests are defined. These are most probably the most comprehensive files in the
261
  module folder.
262
- <mcu>.ld
263
  Linker script, defining the memory layout and region aliases. It is
264
  recommended to check ChibiOS (kernel/ChibiOS/os/common/startup/) whether a
265
  linker script for the according MCU already exists.
266

  
267
Since all these files are specific to the module hardware, youl will have to
268
modify the contents according to your setup in a third step. Most settings are
269
described in detail within the configuration files, but for others you will have
270
to consult the datasheet of your MCU and even take a closer look at how certain
271
settings are used in other modules.
272

  
273
Finally, you need to build and flash the project. The compiler might even help
274
you getting everything set up correctly. Take time to understand compilation
275
errors and warning and get rid of all of those (warnings should not be ignored
276
since they are hints that something might be amiss and the program will not act
277
as intended).
278

  
279
Summing up, you have to
280
1) create a module directory.
281
2) initialize all files (use an existing module or a ChibiOS demo as template).
282
3) configure all files according to your hardware setup and preferences.
283
4) compile, flash and check for issues.
284

  
285
4.2  Handling a Custom I/O Event in the Main Thread
286
---------------------------------------------------
287

  
288
In order to handle custom I/O events in the main thread, AMiRo-OS offers several
289
hooks to be used. First of all, you need to configure and enable the interrupt
290
in the according GPIO. This can be done by implementing the
291
MODULE_INIT_INTERRUPTS() hook in the module.h file. For information how to use
292
this hook, please have a look at existing modules. In the end, the interrupt
293
callback functions has to emit an I/O event with the according bit in the flags
294
mask set (like the _intCallback() function in aos_system.c). As result, whenever
295
a rising or falling edge (depends on configuration) is detected on that GPIO,
296
the interrupt service routine is executed and hence an I/O event is fired, which
297
can be catched by any thread in the system.
298

  
299
Next, you have to configure the main thread to whitelist the event flag (all I/O
300
events are blacklisted by default). While system relevant events like power down
301
are whitelisted by the OS, any custom events need to be added exl´plicitely.
302
This is done via the optional AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro, which
303
should be defined in the module.h file. Example:
304

  
305
  #define AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK                \
306
    (AOS_IOEVENT_FLAG(padX) | AOS_IOEVENT_FLAG(padY) | AOS_IOEVENT_FLAG(padZ))
307

  
308
When AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK has been defined correctly, the main
309
thread will be notified by the according events and execute its event handling
310
routine. Hence you have to implement another macro in module.h to handle the
311
custom event(s) appropriately: MODULE_MAIN_LOOP_IO_EVENT(eventflags). As you can
312
see, the variable 'eventflags' is propagated to the hook. This variable is a
313
mask, that allows to identify the GPIO pad(s), which caused the event, by the
314
bits set. Following the example above, you can check which GPIOs have caused
315
events by using if-clauses in the implementation of the hook:
316

  
317
  #define MODULE_MAIN_LOOP_IO_EVENT(eventflags) {           \
318
    if (eventflags & AOS_IOEVENT_FLAG(padX)) {              \
319
      /* handle event */                                    \
320
    }                                                       \
321
    if (eventflags & (AOS_IOEVENT_FLAG(padY) |              \
322
          AOS_IOEVENT_FLAG(padZ))) {                        \
323
      /* handle combined event */                           \
324
    }                                                       \
325
  }
326

  
327
Summing up, you have to
328
1) configure and enable the GPIO interrupt.
329
2) define the AMIROOS_CFG_MAIN_LOOP_IOEVENT_MASK macro.
330
3) implement the MODULE_MAIN_LOOP_IO_EVENT(eventflags) hook.
331

  
332
4.3  Implementing a New Low-Level Driver
333
----------------------------------------
334

  
335
In the AMiRo-OS framework, low-level drivers are located in the additional Git
336
project AMiRo-LLD, which is included in AMiRo-OS as Git submodule at
337
periphery-lld/AMiRo-LLD/ and acts similar to a static library. When adding a new
338
low-level driver to the framework, you have to implement it, providing a
339
(single) header file in periphery-lld/AMiRo-LLD/include/ and the required C
340
sources in periphery-lld/AMiRo-LLD/source/. By convention, all filenames use the
341
prefix 'alld_' to avoid ambiguities. Furthermore, files should be named by the
342
exact designation of the hardware (e.g. 'alld_vcnl4020' instead of
343
'alld_proximitysensor'). Since AMiRo-LLD is intended to be usable with other
344
operating systems than AMiRo-OS, it provides an interface for accessing
345
communication interfaces and basic functionalities of the operating system. On
346
the one hand, several types are defined in periphery-lld/AMiRo-LLD/periphALtypes.h.
347
The interface functions, on the other hand, are defined by AMiRo-LLD (cf.
348
periphery-lld/AMiRo-LLD/templates/periphAL.h), but implemented by the operating
349
system (cf. periphery-lld/periphAL.h). For the implementation of the driver, you
350
must only use those types and functions to interact with the operating system.
351
If you need further functionality, which is not provided by the interface yet,
352
you are encouraged to extend periphAL.
353

  
354
Furthermore, all files must define a guard, so that the whole driver is
355
disabled, when the guard is not set explicitely. These guard again are named
356
following a convention, but instead of explaning it here, just have a look at
357
one of the existing drivers and look for lines like
358

  
359
  #if defined(AMIROLLD_CFG_USE_VCNL4020) || defined(__DOXYGEN__)
360

  
361
With these guards in place, the driver will be omitted by default and needs to
362
be enabled explicitely. In order to do so, you need to add an according #define
363
in the alldconf.h file of any module, which shall use the new driver.
364

  
365
Now the new driver is available and enabled, but not actually used yet.
366
Therefore you have to add according memory structures to the module.h and
367
module.c files - just have a look at existing modules how this is done. In some
368
cases you will have to configure additional interrupts and/or alter the
369
configuration of a communication interface (e.g. I²C). Once again, you should
370
take a look at existing modules and search the module.h for the hooks
371
MODULE_INIT_INTERRUPTS() and MODULE_INIT_PERIPHERY_COMM().
372

  
373
Finally, you will probably want to validate your implementation via a unit test.
374
How this can be done is explained in detail in the next guide.
375

  
376
Summing up, you have to
377
1) implement the driver in AMiRo-LLD using periphAL only.
378
2) fence all code in all files by a guard.
379
3) set the guard in alldconf.h to enable the driver.
380
4) add the driver to a module.
381
5) configure interrupts and interfaces as required.
382
6) write a unit test.
383

  
384
4.4  Writing a Unit Test
385
------------------------
386

  
387
AMiRo-OS provides a unit test framework for conventient testing and the ability
388
to opt-out all unit tests via the aosconf.h configuration file. There is also a
389
dedicated folder, where all unit test code belongs to. In case you want to
390
implement a unit test for a newly developed low-level driver, you should use the
391
folders unittests/periphery-lld/inc and unittests/periphery-lld/src
392
respectively. As with the low-level drivers, unit test files should use a prefix
393
in their name, namely 'ut_' and all code should be fenced via guards that
394
disable it by default (have a look at existing unit tests). Before you implement
395
a vast test, however, it is highly recommended to start with some sceleton code
396
(just copy an existing unit test, scoop out the test function, and rename
397
according variables etc.) and make it compile and run.
398

  
399
After you have initialized the unit test sceleton, you have to add the according
400
aos_unittest_t (cf. core/inc/aos_unittest.h) object to the module.h and module.c
401
files. These objects again require an shell command, so the unit test can be run
402
via the AMiRo-OS shell. As with existing unit tests, this shell command callback
403
function as well as any further required data should be implemented directly in
404
module.c, so it not accessable from any other context. In most cases this
405
callback function is trivial, anyway.
406

  
407
In order to make the shell command, which executes the unit test, available in
408
shell so a user can run it, it has to be associated with the shell. AMiRo-OS
409
provides the hook MODULE_INIT_TESTS() for this purpose, which has to be
410
implemented in the module.h file. Once again I recommend to have a look at an
411
existing module, how to use this hook.
412

  
413
Since the execution pipeline is set up now, you can fille your unit test with
414
life. Remember that the test is executed by the shell thread, so you can access
415
any functionality of the system, but might encounter race conditions, depending
416
on what other applications run concurrently.
417

  
418
Summing up, you have to
419
1) initialize a unit test sceleton in the unittests/ folder.
420
2) introduce an according object and configuration in module.h and module.c.
421
3) associate the shell command to a shell via the hook in module.h.
422
4) implement the full unit test in the prevously created sceleton files.
423

  
206 424
================================================================================
207 425

  

Also available in: Unified diff