Revision 1678f270

View differences:

Makefile
1 1
################################################################################
2 2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3 3
# (AMiRo) platform.                                                            #
4
# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
4
# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
5 5
#                                                                              #
6 6
# This program is free software: you can redistribute it and/or modify         #
7 7
# it under the terms of the GNU General Public License as published by         #
......
26 26
define HELP_TEXT
27 27
################################################################################
28 28
#                                                                              #
29
# Copyright (c) 2016..2018  Thomas Schöpping                                   #
29
# Copyright (c) 2016..2019  Thomas Schöpping                                   #
30 30
#                                                                              #
31 31
# This is free software; see the source for copying conditions. There is NO    #
32 32
# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  #
......
48 48
  all:
49 49
      Builds the binaries for all modules.
50 50

  
51
  flash:
52
      Flashes all binaries to the hardware.
53
      If the binaries do not exist, they are created beforehand.
51
  <module>:
52
      Builds the binary only for the specified module.
53

  
54
  flash_<module>:
55
      Builds the binary for the specified module and flashes it to the hardware.
54 56

  
55 57
  clean:
56 58
      Deletes all temporary and binary files of all modules.
57 59

  
58
  <module>:
59
      Builds the binary only for the specified module.
60
  clean_<module>:
61
      Deletes all temporary and binary files of the specified module.
60 62

  
61 63

  
62 64
EXAMPLES:
......
69 71
      This command will generate the binary files for the two modules
70 72
      DiWheelDrive (version 1.1) and LightRing (version 1.0).
71 73

  
72
  >$$ make flash -j
73
      This command will first build all missing binary files and flash all
74
      modules as soon as the binaries are ready.
74
  >$$ make all -j
75
      This command will first build missing binary files for all modules that
76
      are found in the 'modules/' folder.
75 77
      By the additional argument '-j' the build process will be parallelized.
76 78

  
77
  >$$ make clean && make all && make flash
78
      This command will first clean all thee projects. In a second step the
79
      binaries for all modules are build from scratch. Finally all modules are
80
      updated with the latest software.
81
      The following command can be used as a shorter and faster version:
82
          >$$ make clean && make flash -j
79
  >$$ make flash_DiWheelDrive_1-1
80
      This command will build the binary for the DiWheelDrive module
81
      (version 1.1) only if required, and flash it to the hardware.
82

  
83
  >$$ make clean; make all; make flash_DiWheelDrive_1-1
84
      This command will first clean all projects. In a second step the binaries
85
      for all modules are build from scratch. Finally the DiWheelDrive module
86
      (version 1.1) is updated with the latest software.
83 87

  
84 88
################################################################################
85 89
endef
README.txt
4 4
system kernel and extends it with platform specific configurations and further
5 5
functionalities and abstractions.
6 6

  
7
Copyright (C) 2016..2018  Thomas Schöpping et al.
7
Copyright (C) 2016..2019  Thomas Schöpping et al.
8 8
(a complete list of all authors is given below)
9 9

  
10 10
This program is free software: you can redistribute it and/or modify
......
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
......
107 112
copy of it as well. For the sake of compatibility, it is included in AMiRo-OS as
108 113
a Git submodule. It is highly recommended to use the ./setup.sh script for
109 114
initialization. Moreover, you have to apply the patches to ChibiOS in order to
110
make AMiRo-OS work properly. It is recommended to use the .setup.sh script for this
111
purpose.
115
make AMiRo-OS work properly. It is recommended to use the .setup.sh script for
116
this purpose.
112 117
If you would like to use a different kernel, you can add a subfolder in the
113 118
./kernel/ directory and adapt the scripts and operating system source code.
114 119

  
......
116 121
1.4 Low-Level Drivers
117 122
---------------------
118 123

  
119
Any required low-level drivers for the AMiRo hardware is available in an
124
Any required low-level drivers for the AMiRo hardware are available in an
120 125
additional project: AMiRo-LLD. It is included as a Git subodule and can be
121 126
initialized via the ./setup.sh script.
122 127

  
123 128

  
124 129

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

  
128
AMiRo-OS can take advanatge of an installed bootloader, which is recommended for
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
130 135
recommended to install either the 'hterm' or 'gtkterm' application for accessing
131 136
the robot. To ease further development, this project offers support for the
......
157 162
can be reset by toggling the RTS signal on and off again, and you can access the
158 163
system shell of AMiRo-OS. If you need legacy support for older version of
159 164
AMiRo-BLT, you can replace the port value by '/dev/ttyUSB0'.
165
Advanced users can use several connections to multiple modules simultaneously.
166
Each additional programmer will be available as '/dev/ttyAMiRo<N>' (and
167
'/dev/USB<N>' respectively) with <N> being an integer number starting from zero.
168
Please note: Those interfaces are ordered by the time when they have been
169
detected by the operating system.
160 170

  
161 171

  
162 172
2.2 - QtCreator IDE
......
178 188

  
179 189

  
180 190
3 - BUILDING AND FLASHING
181
-------------------------
191
=========================
182 192

  
183 193
Each time you modify any part of AMiRo-OS, you need to recompile the whole
184 194
project for the according AMiRo module. Therefore you can use the ./Makefile by
......
198 208
operating system. All other modules are powered off after reset so that only
199 209
these two offer a running bootloader, which is required for flashing.
200 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

  
201 424
================================================================================
202 425

  
amiroos.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
bootloader/bootloader.mk
1 1
################################################################################
2 2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3 3
# (AMiRo) platform.                                                            #
4
# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
4
# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
5 5
#                                                                              #
6 6
# This program is free software: you can redistribute it and/or modify         #
7 7
# it under the terms of the GNU General Public License as published by         #
bootloader/bootloadersetup.sh
263 263
  return 0
264 264
}
265 265

  
266
### check whether commands are available #######################################
267
# Checks whether the specified commands are available and can be executed.
268
#
269
# usage:      checkCommand [<command> <command> ...]
270
# arguments:  <command>
271
#                 Name of the command to check.
272
# return:     0
273
#                 All requested commands are available.
274
#             >0
275
#                 Number of requested commands that were not found.
276
#             -1
277
#                 No argument given.
278
#
279
function checkCommands {
280
  local status=0
281

  
282
  # return if no argument was specified
283
  if [ $# -eq 0 ]; then
284
    return -1
285
  fi
286

  
287
  # check all specified commands
288
  while [ $# -gt 0 ]; do
289
    command -v $1 &>/dev/null
290
    if [ $? -ne 0 ]; then
291
      printWarning "Command '$1' not available.\n"
292
      status=$((status + 1))
293
    fi
294
    shift 1
295
  done
296

  
297
  return $status
298
}
299

  
266 300
################################################################################
267 301
# SPECIFIC FUNCTIONS                                                           #
268 302
################################################################################
......
329 363
#                 Warning: Arborted by user.
330 364
#             -1
331 365
#                 Error: Unexpected user input.
366
#             -2
367
#                 Error: Missing dependencies.
332 368
#
333 369
function initAmiroBlt {
334 370
  printInfo "initializing AMiRo-BLT submodule...\n"
......
354 390
    esac
355 391
  fi
356 392

  
393
  # check dependencies
394
  checkCommands git
395
  if [ $? -ne 0 ]; then
396
    printError "Missing dependencies detected.\n"
397
    return -2
398
  fi
399

  
357 400
  # initialize submodule to default branch
358 401
  cd $bootloaderdir
359 402
  git submodule update --init $amirobltdir 2>&1 | tee -a $LOG_FILE
......
412 455
#
413 456
# usage:      wipeAmiroBlt
414 457
# arguments:  n/a
415
# return:     n/a
458
# return:     0
459
#                 No error or warning occurred.
460
#             1
461
#                 Warning: AMiRo-BLT Git submodule already empty
462
#             2
463
#                 Warning: Aborted by user.
464
#             -1
465
#                 Error: Unexpected input occurred
466
#             -2
467
#                 Error: Missing dependencies.
468
#
416 469
function wipeAmiroBlt {
417 470
  printInfo "reset and wipe Git submodule $amirobltdir\n"
418 471
  local userdir=$(pwd)
419 472
  local bootloaderdir=$(dirname $(realpath ${BASH_SOURCE[0]}))
420 473
  local amirobltdir=${bootloaderdir}/AMiRo-BLT
421 474

  
475
  # check dependencies
476
  checkCommands git
477
  if [ $? -ne 0 ]; then
478
    printError "Missing dependencies detected.\n"
479
    return -2
480
  fi
481

  
422 482
  # if the AMiRo-BLT folder is empty
423 483
  if [ -z "$(ls -A $amirobltdir)" ]; then
424 484
    printWarning "$amirobltdir is already empty\n"
core/core.mk
1 1
################################################################################
2 2
# AMiRo-OS is an operating system designed for the Autonomous Mini Robot       #
3 3
# (AMiRo) platform.                                                            #
4
# Copyright (C) 2016..2018  Thomas Schöpping et al.                            #
4
# Copyright (C) 2016..2019  Thomas Schöpping et al.                            #
5 5
#                                                                              #
6 6
# This program is free software: you can redistribute it and/or modify         #
7 7
# it under the terms of the GNU General Public License as published by         #
......
30 30
AMIROOSCOREINC = $(AMIROOS_CORE_DIR)inc
31 31

  
32 32
# C source files
33
AMIROOSCORECSRC = $(AMIROOS_CORE_DIR)src/aos_debug.c \
34
                  $(AMIROOS_CORE_DIR)src/aos_iostream.c \
35
                  $(AMIROOS_CORE_DIR)src/aos_shell.c \
36
                  $(AMIROOS_CORE_DIR)src/aos_system.c \
37
                  $(AMIROOS_CORE_DIR)src/aos_thread.c \
38
                  $(AMIROOS_CORE_DIR)src/aos_time.c \
39
                  $(AMIROOS_CORE_DIR)src/aos_timer.c \
40
                  $(AMIROOS_CORE_DIR)src/aos_unittest.c
33
AMIROOSCORECSRC = $(wildcard $(AMIROOS_CORE_DIR)src/*.c)
41 34

  
42 35
# C++ source files
43
AMIROOSCORECPPSRC = $(AMIROOS_CORE_DIR)src/aos_main.cpp
36
AMIROOSCORECPPSRC = $(wildcard $(AMIROOS_CORE_DIR)src/*.c?*)
44 37

  
core/inc/aos_confcheck.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
......
49 49
  #error "AMIROOS_CFG_MAIN_LOOP_TIMEOUT not defined in aosconf.h"
50 50
#endif
51 51

  
52
#if (AMIROOS_CFG_SSSP_ENABLE == true)
53

  
54 52
/*
55 53
 * SSSP parameters and options
56 54
 */
57 55

  
58
#ifndef AMIROOS_CFG_SSSP_MASTER
59
  #error "AMIROOS_CFG_SSSP_MASTER not defined in aosconf.h"
56
#ifndef AMIROOS_CFG_SSSP_ENABLE
57
  #error "AMIROOS_CFG_SSSP_ENABLE not defined in aosconf.h"
60 58
#endif
61 59

  
62
#ifndef AMIROOS_CFG_SSSP_STACK_START
63
  #error "AMIROOS_CFG_SSSP_STACK_START not defined in aosconf.h"
64
#endif
60
# if (AMIROOS_CFG_SSSP_ENABLE == true)
65 61

  
66
#ifndef AMIROOS_CFG_SSSP_STACK_END
67
  #error "AMIROOS_CFG_SSSP_STACK_END not defined in aosconf.h"
68
#endif
62
  #ifndef AMIROOS_CFG_SSSP_MASTER
63
    #error "AMIROOS_CFG_SSSP_MASTER not defined in aosconf.h"
64
  #endif
69 65

  
70
#if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
71
  #warning "AMIROOS_CFG_SSSP_STACK_START and AMIROOS_CFG_SSSP_STACK_END both enabled in aosconf.h"
72
  #if (AMIROOS_CFG_SSSP_MASTER != true)
73
    #error "AMIROOS_CFG_SSSP_MASTER must be enabled in this case"
66
  #ifndef AMIROOS_CFG_SSSP_STACK_START
67
    #error "AMIROOS_CFG_SSSP_STACK_START not defined in aosconf.h"
74 68
  #endif
75
#endif
76 69

  
77
#ifndef AMIROOS_CFG_SSSP_SIGNALDELAY
78
  #error "AMIROOS_CFG_SSSP_SIGNALDELAY not defined in aosconf.h"
79
#endif
70
  #ifndef AMIROOS_CFG_SSSP_STACK_END
71
    #error "AMIROOS_CFG_SSSP_STACK_END not defined in aosconf.h"
72
  #endif
80 73

  
81
#ifndef AMIROOS_CFG_SSSP_SYSSYNCPERIOD
82
  #error "AMIROOS_CFG_SSSP_SYSSYNCPERIOD not defined in aosconf.h"
83
#endif
74
  #if (AMIROOS_CFG_SSSP_STACK_START == true) && (AMIROOS_CFG_SSSP_STACK_END == true)
75
    #warning "AMIROOS_CFG_SSSP_STACK_START and AMIROOS_CFG_SSSP_STACK_END both enabled in aosconf.h"
76
    #if (AMIROOS_CFG_SSSP_MASTER != true)
77
      #error "AMIROOS_CFG_SSSP_MASTER must be enabled in this case"
78
    #endif
79
  #endif
80

  
81
  #ifndef AMIROOS_CFG_SSSP_SIGNALDELAY
82
    #error "AMIROOS_CFG_SSSP_SIGNALDELAY not defined in aosconf.h"
83
  #endif
84

  
85
  #ifndef AMIROOS_CFG_SSSP_SYSSYNCPERIOD
86
    #error "AMIROOS_CFG_SSSP_SYSSYNCPERIOD not defined in aosconf.h"
87
  #endif
84 88

  
85 89
#endif
90

  
86 91
/*
87 92
 * System shell options
88 93
 */
core/inc/aos_debug.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/inc/aos_iostream.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/inc/aos_shell.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/inc/aos_system.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
......
27 27
#ifndef _AMIROOS_SYSTEM_H_
28 28
#define _AMIROOS_SYSTEM_H_
29 29

  
30
#include <time.h>
30 31
#include <aos_iostream.h>
31 32
#include <amiro-lld.h>
32 33
#include <aos_shell.h>
......
63 64
 */
64 65
#define AOS_SYSTEM_EVENTFLAGS_RESTART           (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 4))
65 66

  
66
#if (AMIROOS_CFG_SSSP_ENABLE == true)
67
/**
68
 * @brief   Enumerator to identify shutdown types.
69
 */
70
typedef enum aos_shutdown {
71
  AOS_SHUTDOWN_NONE,            /**< Default value if no shutdown action was initiated */
72
  AOS_SHUTDOWN_PASSIVE,         /**< Passive shutdown (initiated by another module). */
73
  AOS_SHUTDOWN_HIBERNATE,       /**< Active shutdown to hibernate mode. */
74
  AOS_SHUTDOWN_DEEPSLEEP,       /**< Active shutdown to deepsleep mode. */
75
  AOS_SHUTDOWN_TRANSPORTATION,  /**< Active shutdown to transportation mode. */
76
  AOS_SHUTDOWN_RESTART,         /**< Active saystem restart request. */
77
} aos_shutdown_t;
78

  
79
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
67 80

  
68 81
/**
69 82
 * @brief   Major version of the implemented SSSP.
......
81 94
 */
82 95
#define AOS_SYSTEM_SSSP_TIMEOUT                 (10 * AMIROOS_CFG_SSSP_SIGNALDELAY)
83 96

  
84
#endif
85

  
86
/**
87
 * @brief   Enumerator to identify shutdown types.
88
 */
89
typedef enum aos_shutdown {
90
  AOS_SHUTDOWN_NONE,            /**< Default value if no shutdown action was initiated */
91
  AOS_SHUTDOWN_PASSIVE,         /**< Passive shutdown (initiated by another module). */
92
  AOS_SHUTDOWN_HIBERNATE,       /**< Active shutdown to hibernate mode. */
93
  AOS_SHUTDOWN_DEEPSLEEP,       /**< Active shutdown to deepsleep mode. */
94
  AOS_SHUTDOWN_TRANSPORTATION,  /**< Active shutdown to transportation mode. */
95
  AOS_SHUTDOWN_RESTART,         /**< Active saystem restart request. */
96
} aos_shutdown_t;
97

  
98
#if (AMIROOS_CFG_SSSP_ENABLE == true)
99

  
100 97
/**
101 98
 * @brief   Enumerator of the several stages of SSSP.
102 99
 */
......
119 116
  AOS_SSSP_SHUTDOWN_3   = 0x38, /**< Identifier of SSSP shutdown phase stage 3. */
120 117
} aos_ssspstage_t;
121 118

  
122
#endif
123

  
124
#if (AMIROOS_CFG_SSSP_ENABLE == true)
125 119
/**
126 120
 * @brief   Type to represent module IDs.
127 121
 */
128 122
typedef uint16_t aos_ssspmoduleid_t;
129
#endif
130 123

  
124
#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
131 125

  
132 126
/**
133 127
 * @brief   AMiRo-OS base system structure.
134 128
 */
135 129
typedef struct aos_system {
136
#if (AMIROOS_CFG_SSSP_ENABLE == true)
130
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
137 131
  /**
138 132
   * @brief   SSSP relevant data.
139 133
   */
......
150 144
     */
151 145
    aos_ssspmoduleid_t moduleId;
152 146
  } sssp;
153
#endif
147
#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
148

  
154 149
  /**
155 150
   * @brief   System I/O stream.
156 151
   */
......
202 197
  void aosSysInit(void);
203 198
#endif
204 199
  void aosSysStart(void);
205
  #if (AMIROOS_CFG_SSSP_ENABLE == true)
200
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined (__DOXYGEN__)
206 201
  eventmask_t aosSysSsspStartupOsInitSyncCheck(event_listener_t* syncEvtListener);
207 202
#endif
208 203
  void aosSysGetUptimeX(aos_timestamp_t* ut);
core/inc/aos_thread.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
......
99 99
extern "C" {
100 100
#endif
101 101
  void aosThdSleepUntilS(const aos_timestamp_t* t);
102
#if (CH_DBG_FILL_THREADS == TRUE)
102
#if (AMIROOS_CFG_DBG == true) && (CH_DBG_FILL_THREADS == TRUE)
103 103
  size_t aosThdGetStackPeakUtilization(thread_t* thread);
104 104
#endif
105 105
#ifdef __cplusplus
......
240 240
  return;
241 241
}
242 242

  
243
#if (AMIROOS_CFG_DBG == true) || defined(__DOXYGEN__)
244

  
243 245
/**
244 246
 * @brief   Retrieve the stack size of a specific thread in bytes.
245 247
 *
......
263 265
         ((size_t)PORT_GUARD_PAGE_SIZE + sizeof(struct port_intctx) + sizeof(struct port_extctx) + (size_t)PORT_INT_REQUIRED_STACK);
264 266
}
265 267

  
268
#endif /* AMIROOS_CFG_DBG == true */
269

  
266 270
#endif /* _AMIROOS_THREAD_H_ */
267 271

  
268 272
/** @} */
core/inc/aos_time.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/inc/aos_timer.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/inc/aos_types.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
......
28 28
#define _AMIROOS_TYPES_H_
29 29

  
30 30
/**
31
 * @brief   Converts a GPIO pad number to a unique event flag.
32
 */
33
#define AOS_IOEVENT_FLAG(pad)                   ((eventflags_t)1 << pad)
34

  
35
/**
31 36
 * @brief   Error codes used in AMiRo-OS.
32 37
 */
33 38
typedef enum {
core/inc/aos_unittest.h
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/src/aos_debug.c
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/src/aos_iostream.c
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
core/src/aos_main.cpp
1 1
/*
2 2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
3
Copyright (C) 2016..2019  Thomas Schöpping et al.
4 4

  
5 5
This program is free software: you can redistribute it and/or modify
6 6
it under the terms of the GNU General Public License as published by
......
61 61
 */
62 62
#define DELAYEVENT_MASK                         EVENT_MASK(4)
63 63

  
64
#if (AMIROOS_CFG_SSSP_ENABLE == true)
64
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
65 65

  
66 66
/**
67 67
 * @brief   CAN message identifier for initialization of the SSSP stack initialization sequence.
......
78 78
 */
79 79
#define SSSP_STACKINIT_CANMSGID_ABORT           0x001
80 80

  
81
#endif
81
#else /* AMIROOS_CFG_SSSP_ENABLE == false */
82

  
83
/**
84
 * @brief   Default shutdown mode if SSSP is unavailable.
85
 */
86
#define AOS_SHUTDOWN_DEFAULT                    AOS_SHUTDOWN_DEEPSLEEP
87

  
88
#endif /* AMIROOS_CFG_SSSP_ENABLE */
82 89

  
83 90
/**
84 91
 * @brief   CAN message identifier for calender synchronization message.
......
106 113
 * @brief   I/O shell channel for the programmer interface.
107 114
 */
108 115
static AosShellChannel _stdshellchannel;
109
#endif
110
#endif
116
#endif /* AMIROOS_CFG_SHELL_ENABLE == true */
117
#endif /* defined(MODULE_HAL_PROGIF) */
111 118

  
112 119
/*
113 120
 * hook to add further static variables
......
125 132
static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
126 133
{
127 134
#if (AMIROOS_CFG_DBG == true)
128
    aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
135
  aosprintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
129 136
#else
130
    (void)(mask);
131
    (void)(flags);
137
  (void)(mask);
138
  (void)(flags);
132 139
#endif
133
    return;
140
  return;
134 141
}
135 142

  
136

  
137
#if (AMIROOS_CFG_SSSP_ENABLE == true)
143
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
138 144
/**
139 145
 * @brief   Callback function to be used during SSSP stack initialization sequence.
140 146
 *
......
142 148
 */
143 149
static void _ssspTimerCallback(void* par)
144 150
{
145
    aosDbgCheck(par != NULL);
151
  aosDbgCheck(par != NULL);
146 152

  
147
    chSysLockFromISR();
148
    chEvtBroadcastI((event_source_t*)par);
149
    chSysUnlockFromISR();
153
  chSysLockFromISR();
154
  chEvtBroadcastI((event_source_t*)par);
155
  chSysUnlockFromISR();
150 156

  
151
    return;
157
  return;
152 158
}
153
#endif
159
#endif /* AMIROOS_CFG_SSSP_ENABLE == true */
160

  
154 161
/**
155 162
 * @brief   Helper function to serialize data.
156 163
 *
......
160 167
 */
161 168
inline void _serialize(uint8_t* dst, const uint64_t src, const uint8_t n)
162 169
{
163
    aosDbgCheck(dst != NULL);
164
    aosDbgCheck(n > 0 && n <= 8);
170
  aosDbgCheck(dst != NULL);
171
  aosDbgCheck(n > 0 && n <= 8);
165 172

  
166
    for (uint8_t byte = 0; byte < n; ++byte) {
167
        dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
168
    }
173
  for (uint8_t byte = 0; byte < n; ++byte) {
174
    dst[byte] = (uint8_t)((src >> (byte * 8)) & 0xFF);
175
  }
169 176

  
170
    return;
177
  return;
171 178
}
172 179

  
173 180
/**
......
180 187
 */
181 188
inline uint64_t _deserialize(uint8_t* src, const uint8_t n)
182 189
{
183
    aosDbgCheck(src != NULL);
184
    aosDbgCheck(n > 0 && n <= 8);
190
  aosDbgCheck(src != NULL);
191
  aosDbgCheck(n > 0 && n <= 8);
185 192

  
186
    uint64_t result = 0;
187
    for (uint8_t byte = 0; byte < n; ++byte) {
188
        result |= ((uint64_t)src[byte]) << (byte * 8);
189
    }
193
  uint64_t result = 0;
194
  for (uint8_t byte = 0; byte < n; ++byte) {
195
    result |= ((uint64_t)src[byte]) << (byte * 8);
196
  }
190 197

  
191
    return result;
198
  return result;
192 199
}
193 200

  
194 201
/**
......
210 217
 */
211 218
inline uint64_t _TM2U64(struct tm* src)
212 219
{
213
    aosDbgCheck(src != NULL);
214

  
215
    return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
216
            ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
217
            ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
218
            ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
219
            ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
220
            ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
221
            ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
222
            ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
223
            ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
220
  aosDbgCheck(src != NULL);
221

  
222
  return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
223
          ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
224
          ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
225
          ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
226
          ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
227
          ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
228
          ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
229
          ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
230
          ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
224 231
}
225 232

  
226 233
/**
......
233 240
 */
234 241
inline void _U642TM(struct tm* dst, const uint64_t src)
235 242
{
236
    aosDbgCheck(dst != NULL);
237

  
238
    dst->tm_sec  = (src >> 0)  & 0x0000003F;
239
    dst->tm_min  = (src >> 6)  & 0x0000003F;
240
    dst->tm_hour = (src >> 12) & 0x0000001F;
241
    dst->tm_mday = (src >> 17) & 0x0000001F;
242
    dst->tm_mon  = (src >> 22) & 0x0000000F;
243
    dst->tm_year = (src >> 26) & 0x00FFFFFF;
244
    dst->tm_wday = (src >> 50) & 0x00000007;
245
    dst->tm_yday = (src >> 53) & 0x000001FF;
246
    dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
247

  
248
    return;
243
  aosDbgCheck(dst != NULL);
244

  
245
  dst->tm_sec  = (src >> 0)  & 0x0000003F;
246
  dst->tm_min  = (src >> 6)  & 0x0000003F;
247
  dst->tm_hour = (src >> 12) & 0x0000001F;
248
  dst->tm_mday = (src >> 17) & 0x0000001F;
249
  dst->tm_mon  = (src >> 22) & 0x0000000F;
250
  dst->tm_year = (src >> 26) & 0x00FFFFFF;
251
  dst->tm_wday = (src >> 50) & 0x00000007;
252
  dst->tm_yday = (src >> 53) & 0x000001FF;
253
  dst->tm_isdst = (((src >> 62) & 0x03) == 0) ? 0 : (((src >> 62) & 0x03) > 0) ? 1 : -1;
254

  
255
  return;
249 256
}
250
#if (AMIROOS_CFG_SSSP_ENABLE == true)
257

  
258
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
251 259
/**
252 260
 * @brief   Implementation of the SSSP module stack initialization sequence (startup phase 3).
253 261
 *
......
257 265
 */
258 266
aos_shutdown_t _ssspModuleStackInitialization(void)
259 267
{
260
    // local types
261
    /**
268
  // local types
269
  /**
262 270
   * @brief   States for the internal state machine to implement SSSP startup stage 3.
263 271
   */
264
    typedef enum {
265
        STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
266
        STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
267
        STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
268
        STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
269
        STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
270
        STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
271
        STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
272
        STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
273
    } sssp_modulestackinitstage_t;
274

  
275
    typedef struct {
276
        bool loop     : 1;
277
        bool wfe      : 1;
278
        bool wfe_next : 1;
279
    } flags_t;
280

  
281
    // local variables
282
    aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
283
    sssp_modulestackinitstage_t stage = STAGE_3_1;
284
    eventmask_t eventmask = 0;
285
    eventflags_t ioflags;
286
    event_source_t eventSourceTimeout;
287
    event_source_t eventSourceDelay;
288
    event_listener_t eventListenerTimeout;
289
    event_listener_t eventListenerDelay;
290
    event_listener_t eventListenerCan;
291
    virtual_timer_t timerTimeout;
292
    virtual_timer_t timerDelay;
293
    CANTxFrame canTxFrame;
294
    CANRxFrame canRxFrame;
272
  typedef enum {
273
    STAGE_3_1,                  /**< Initiation of SSSP startup stage 3. */
274
    STAGE_3_2,                  /**< Starting the sequence and broadcasting the first ID. */
275
    STAGE_3_3_WAITFORFIRSTID,   /**< Waiting for first ID after initiation. */
276
    STAGE_3_3_WAITFORIDORSIG,   /**< Waiting for next ID or activation of neighbor signal. */
277
    STAGE_3_3_WAITFORID,        /**< Waiting for next ID (after the module has set its own ID). */
278
    STAGE_3_4_FINISH,           /**< Successful finish of stage 3. */
279
    STAGE_3_4_ABORT_ACTIVE,     /**< Aborting stage 3 (active). */
280
    STAGE_3_4_ABORT,            /**< Aborting stage 3 (passive). */
281
  } sssp_modulestackinitstage_t;
282

  
283
  typedef struct {
284
    bool loop     : 1;
285
    bool wfe      : 1;
286
    bool wfe_next : 1;
287
  } flags_t;
288

  
289
  // local variables
290
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
291
  sssp_modulestackinitstage_t stage = STAGE_3_1;
292
  eventmask_t eventmask = 0;
293
  eventflags_t ioflags = 0;
294
  event_source_t eventSourceTimeout;
295
  event_source_t eventSourceDelay;
296
  event_listener_t eventListenerTimeout;
297
  event_listener_t eventListenerDelay;
298
  event_listener_t eventListenerCan;
299
  virtual_timer_t timerTimeout;
300
  virtual_timer_t timerDelay;
301
  CANTxFrame canTxFrame;
302
  CANRxFrame canRxFrame;
295 303
#if (AMIROOS_CFG_SSSP_STACK_START != true) || (AMIROOS_CFG_DBG == true)
296
    aos_ssspmoduleid_t lastid = 0;
297
#endif
298
    flags_t flags;
299

  
300
    // initialize local varibles
301
    chEvtObjectInit(&eventSourceTimeout);
302
    chEvtObjectInit(&eventSourceDelay);
303
    chVTObjectInit(&timerTimeout);
304
    chVTObjectInit(&timerDelay);
305
    canTxFrame.RTR = CAN_RTR_DATA;
306
    canTxFrame.IDE = CAN_IDE_STD;
307
    flags.loop = true;
308
    flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
309
    flags.wfe_next = true;
310

  
311
    // initialize system variables
312
    aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
313
    aos.sssp.moduleId = 0;
314

  
315
    // listen to events (timout, delay, CAN receive)
316
    chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
317
    chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
318
    chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
319

  
320
    /*
304
  aos_ssspmoduleid_t lastid = 0;
305
#endif
306
  flags_t flags;
307
  aos_timestamp_t uptime;
308

  
309
  // initialize local varibles
310
  chEvtObjectInit(&eventSourceTimeout);
311
  chEvtObjectInit(&eventSourceDelay);
312
  chVTObjectInit(&timerTimeout);
313
  chVTObjectInit(&timerDelay);
314
  canTxFrame.RTR = CAN_RTR_DATA;
315
  canTxFrame.IDE = CAN_IDE_STD;
316
  flags.loop = true;
317
  flags.wfe = false; // do not wait for events in the initial iteration of the FSM loop
318
  flags.wfe_next = true;
319

  
320
  // initialize system variables
321
  aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
322
  aos.sssp.moduleId = 0;
323

  
324
  // listen to events (timout, delay, CAN receive)
325
  chEvtRegisterMask(&eventSourceTimeout, &eventListenerTimeout, TIMEOUTEVENT_MASK);
326
  chEvtRegisterMask(&eventSourceDelay, &eventListenerDelay, DELAYEVENT_MASK);
327
  chEvtRegisterMask(&MODULE_HAL_CAN.rxfull_event, &eventListenerCan, CANEVENT_MASK);
328

  
329
  /*
321 330
   * FSM in a loop.
322 331
   *
323 332
   * This is a fully event-based FSM for the module stack initialization
......
344 353
   *  delays:     Depending on the current state, delays are required by SSSP
345 354
   *              for timing of the sequential activation of signals.
346 355
   */
347
    aosDbgPrintf("SSSP stack initialization sequence:\n");
348
    while (flags.loop) {
356
  aosDbgPrintf("SSSP stack initialization sequence:\n");
357
  while (flags.loop) {
349 358
#if (AMIROOS_CFG_DBG == true)
350
        switch (stage) {
351
        case STAGE_3_1:
352
            aosDbgPrintf(">>> 3-1\n");
353
            break;
354
        case STAGE_3_2:
355
            aosDbgPrintf(">>> 3-2\n");
356
            break;
357
        case STAGE_3_3_WAITFORFIRSTID:
358
            aosDbgPrintf(">>> 3-3 (1st ID)\n");
359
            break;
360
        case STAGE_3_3_WAITFORIDORSIG:
361
            aosDbgPrintf(">>> 3-3 (ID/sig)\n");
362
            break;
363
        case STAGE_3_3_WAITFORID:
364
            aosDbgPrintf(">>> 3-3 (ID)\n");
365
            break;
366
        case STAGE_3_4_FINISH:
367
            aosDbgPrintf(">>> 3-4 (finish)\n");
368
            break;
369
        case STAGE_3_4_ABORT_ACTIVE:
370
            aosDbgPrintf(">>> 3-4 (active abort)\n");
371
            break;
372
        case STAGE_3_4_ABORT:
373
            aosDbgPrintf(">>> 3-4 (abort)\n");
374
            break;
375
        }
359
    switch (stage) {
360
      case STAGE_3_1:
361
        aosDbgPrintf(">>> 3-1\n");
362
        break;
363
      case STAGE_3_2:
364
        aosDbgPrintf(">>> 3-2\n");
365
        break;
366
      case STAGE_3_3_WAITFORFIRSTID:
367
        aosDbgPrintf(">>> 3-3 (1st ID)\n");
368
        break;
369
      case STAGE_3_3_WAITFORIDORSIG:
370
        aosDbgPrintf(">>> 3-3 (ID/sig)\n");
371
        break;
372
      case STAGE_3_3_WAITFORID:
373
        aosDbgPrintf(">>> 3-3 (ID)\n");
374
        break;
375
      case STAGE_3_4_FINISH:
376
        aosDbgPrintf(">>> 3-4 (finish)\n");
377
        break;
378
      case STAGE_3_4_ABORT_ACTIVE:
379
        aosDbgPrintf(">>> 3-4 (active abort)\n");
380
        break;
381
      case STAGE_3_4_ABORT:
382
        aosDbgPrintf(">>> 3-4 (abort)\n");
383
        break;
384
    }
376 385
#endif
377 386

  
378
        // reset wfe flag for the next iteration
379
        flags.wfe_next = true;
387
    // reset wfe flag for the next iteration
388
    flags.wfe_next = true;
380 389

  
381
        // waiting for events may be skipped
382
        if (flags.wfe) {
383
            // wait for any event to occur
384
            aosDbgPrintf("WFE...");
385
            eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
386
            aosDbgPrintf("\t0x%08X", eventmask);
387
        } else {
388
            aosDbgPrintf("WFE skipped");
389
        }
390
        aos_timestamp_t uptime;
391
        aosSysGetUptime(&uptime);
392
        aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / 1000));
390
    // waiting for events (may be skipped)
391
    if (flags.wfe) {
392
      // wait for any event to occur
393
      aosDbgPrintf("WFE...");
394
      eventmask = chEvtWaitAnyTimeout(ALL_EVENTS, chTimeUS2I(AOS_SYSTEM_SSSP_TIMEOUT));
395
      aosDbgPrintf("\t0x%08X", eventmask);
396
    } else {
397
      aosDbgPrintf("WFE skipped");
398
      eventmask = 0;
399
    }
400
    aosSysGetUptime(&uptime);
401
    aosDbgPrintf("\t%04ums\n", (uint32_t)(uptime / MICROSECONDS_PER_MILLISECOND));
393 402

  
394
        /*
403
    /*
395 404
     * execute some general tasks and high priority events
396 405
     */
397
        // no event occurred at all
398
        if ((flags.wfe) && (eventmask == 0)) {
399
            aosDbgPrintf("ERR: no evt\n");
400
            // enforce timeout event
401
            chEvtBroadcast(&eventSourceTimeout);
402
            continue;
403
        }
404
        // if an IO event occurred
405
        if (eventmask & _eventListenerIO.events) {
406
            ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
407
            aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
408
            // a power-down event occurred
409
            if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
410
                aosDbgPrintf("PD evt\n");
411
                // deactivate S and UP
412
                apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
406
    // no event occurred at all
407
    if ((flags.wfe) && (eventmask == 0)) {
408
      aosDbgPrintf("ERR: no evt\n");
409
      // enforce timeout event
410
      chEvtBroadcast(&eventSourceTimeout);
411
      continue;
412
    }
413
    // if an IO event occurred
414
    if (eventmask & _eventListenerIO.events) {
415
      ioflags = chEvtGetAndClearFlags(&_eventListenerIO);
416
      aosDbgPrintf("INFO: IO evt (0x%08X)\n", ioflags);
417
      // a power-down event occurred
418
      if (ioflags & MODULE_SSSP_EVENTFLAGS_PD) {
419
        aosDbgPrintf("PD evt\n");
420
        // deactivate S and UP
421
        aosDbgPrintf("disabling S\n");
422
        apalControlGpioSet(&moduleSsspGpioSync, APAL_GPIO_OFF);
413 423
#if (AMIROOS_CFG_SSSP_STACK_END != true)
414
                apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
415
#endif
416
                // set shutdown flag and exit the loop
417
                shutdown = AOS_SHUTDOWN_PASSIVE;
418
                break;
419
            }
420
            // the S signal was deactivated
421
            if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
422
                apalControlGpioState_t sstate;
423
                apalControlGpioGet(&moduleSsspGpioSync, &sstate);
424
                if (sstate == APAL_GPIO_OFF) {
425
                    aosDbgPrintf("-S evt\n");
426
                    // either finish or abort
427
                    if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
428
                        stage = STAGE_3_4_FINISH;
429
                    } else if (stage != STAGE_3_4_ABORT) {
430
                        stage = STAGE_3_4_ABORT_ACTIVE;
431
                    }
432
                }
433
            }
424
        aosDbgPrintf("disabling UP\n");
425
        apalControlGpioSet(&moduleSsspGpioUp, APAL_GPIO_OFF);
426
#endif
427
        // set shutdown flag and exit the loop
428
        shutdown = AOS_SHUTDOWN_PASSIVE;
429
        break;
430
      }
431
      // the S signal was deactivated
432
      if (ioflags & MODULE_SSSP_EVENTFLAGS_SYNC) {
433
        apalControlGpioState_t sstate;
434
        apalControlGpioGet(&moduleSsspGpioSync, &sstate);
435
        if (sstate == APAL_GPIO_ON) {
436
          aosDbgPrintf("S evt (enabled)\n");
437
        } else {
438
          aosDbgPrintf("S evt (disabled)\n");
439
          // either finish or abort
440
          if ((stage == STAGE_3_3_WAITFORID) && (aos.sssp.moduleId != 0)) {
441
            stage = STAGE_3_4_FINISH;
442
          } else if (stage != STAGE_3_4_ABORT) {
443
            stage = STAGE_3_4_ABORT_ACTIVE;
444
          }
434 445
        }
435
        // an OS event occurred
436
        if (eventmask & _eventListenerOS.events) {
437
            aosDbgPrintf("WARN: OS evt\n");
438
            // get the flags
439
            eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
440
            // there should be no OS events at this point
446
      }
447
    }
448
    // an OS event occurred
449
    if (eventmask & _eventListenerOS.events) {
450
      aosDbgPrintf("WARN: OS evt\n");
451
      // get the flags
452
      eventflags_t oseventflags = chEvtGetAndClearFlags(&_eventListenerOS);
453
      // there should be no OS events at this point
441 454
#ifdef MODULE_SSSP_STARTUP_3_OSEVENT_HOOK
442
            MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
455
      MODULE_SSSP_STARTUP_3_OSEVENT_HOOK(eventmask, eventflags);
443 456
#else
444
            _unexpectedEventError(eventmask, oseventflags);
457
      _unexpectedEventError(eventmask, oseventflags);
445 458
#endif
446
        }
447
        // if a CAN event occurred
448
        if ((eventmask & eventListenerCan.events)) {
449
            // fetch message
450
            if (flags.wfe) {
451
                canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
452
                aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
453
            }
454
            // identify and handle abort messgaes
455
            if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
456
                stage = STAGE_3_4_ABORT;
457
            }
458
            // warn if a unexpected message was received
459
            else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
460
                     (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
461
                aosDbgPrintf("WARN: unknown msg\n");
462
            }
463
            // any further pending messages are fetched at the end of the loop
464
        }
465
        // if a timeout event occurred
466
        if (eventmask & eventListenerTimeout.events) {
467
            // is handled at the end of the loop (or must be cleared by FSM)
468
        }
469
        // if a delay event occurred
470
        if (eventmask & eventListenerDelay.events) {
471
            // is handled by FSM
472
        }
459
    }
460
    // if a CAN event occurred
461
    if ((eventmask & eventListenerCan.events)) {
462
      aosDbgPrintf("CAN evt\n");
463
      // fetch message
464
      if (flags.wfe) {
465
        canReceiveTimeout(&MODULE_HAL_CAN, CAN_ANY_MAILBOX, &canRxFrame, TIME_IMMEDIATE);
466
        aosDbgPrintf("CAN <- 0x%03X\n", canRxFrame.SID);
467
      }
468
      // identify and handle abort messgaes
469
      if (canRxFrame.SID == SSSP_STACKINIT_CANMSGID_ABORT) {
470
        stage = STAGE_3_4_ABORT;
471
      }
472
      // warn if a unexpected message was received
473
      else if ((canRxFrame.SID != SSSP_STACKINIT_CANMSGID_INIT) &&
474
               (canRxFrame.SID != SSSP_STACKINIT_CANMSGID_MODULEID)) {
475
        aosDbgPrintf("WARN: unknown msg\n");
476
      }
477
      // any further pending messages are fetched at the end of the loop
478
    }
479
    // if a timeout event occurred
480
    if (eventmask & eventListenerTimeout.events) {
481
      aosDbgPrintf("timeout evt\n");
482
      // is handled at the end of the loop (or must be cleared by FSM)
483
    }
484
    // if a delay event occurred
485
    if (eventmask & eventListenerDelay.events) {
486
      aosDbgPrintf("delay evt\n");
487
      // is handled by FSM
488
    }
473 489

  
474
        /*
490
    /*
475 491
     * this is the actual FSM
476 492
     */
477
        switch (stage) {
478
        case STAGE_3_1:
479
        {
480
            aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
493
    switch (stage) {
494
      case STAGE_3_1:
495
      {
496
        aos.sssp.stage = AOS_SSSP_STARTUP_3_1;
481 497

  
482
            // there was no event at all (skipped wfe)
483
            if (eventmask == 0 && flags.wfe == false) {
498
        // there was no event at all (skipped wfe)
499
        if (eventmask == 0 && flags.wfe == false) {
484 500
#if (AMIROOS_CFG_SSSP_MASTER == true)
485
                // initialize the stage by transmitting an according CAN message
486
                aosDbgPrintf("CAN -> init\n");
487
                canTxFrame.DLC = 0;
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff