Statistics
| Branch: | Tag: | Revision:

amiro-os / core / src / aos_main.cpp @ 3da12676

History | View | Annotate | Download (38.937 KB)

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

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

10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

    
19
/**
20
 * @file    aos_main.cpp
21
 * @brief   Main function.
22
 *
23
 * @addtogroup aos_system
24
 * @{
25
 */
26

    
27
#include <amiroos.h>
28

    
29
/*
30
 * hook to add further includes
31
 */
32
#if defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER)
33
#include AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER
34
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_INCLUDE_HEADER) */
35

    
36
/******************************************************************************/
37
/* LOCAL DEFINITIONS                                                          */
38
/******************************************************************************/
39

    
40
/**
41
 * @brief   Event mask to identify GPIO events.
42
 */
43
#define EVENTMASK_GPIO                          EVENT_MASK(0)
44

    
45
/**
46
 * @brief   Event mask to identify OS events.
47
 */
48
#define EVENTMASK_OS                            EVENT_MASK(1)
49

    
50
#if (AMIROOS_CFG_SSSP_ENABLE == true) || defined(__DOXYGEN__)
51

    
52

    
53
#if (AMIROOS_CFG_SSSP_MSI == true) || defined(__DOXYGEN__)
54

    
55
/**
56
 * @brief   Event mask to identify SSSP timeout events (MSI only).
57
 */
58
#define EVENTMASK_SSSPTIMEOUT                   EVENT_MASK(2)
59

    
60
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
61

    
62
/**
63
 * @brief   Event mask to identify SSSP delay events.
64
 */
65
#define EVENTMASK_SSSPDELAY                     EVENT_MASK(3)
66

    
67
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
68

    
69
/******************************************************************************/
70
/* EXPORTED VARIABLES                                                         */
71
/******************************************************************************/
72

    
73
/******************************************************************************/
74
/* LOCAL TYPES                                                                */
75
/******************************************************************************/
76

    
77
/******************************************************************************/
78
/* LOCAL VARIABLES                                                            */
79
/******************************************************************************/
80

    
81
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
82

    
83
/**
84
 * @brief   Name of the main thread.
85
 */
86
static const char _threadName[] = "control (main)";
87

    
88
#endif /* (CH_CFG_USE_REGISTRY == TRUE) */
89

    
90
/**
91
 * @brief   Listener object for GPIO events.
92
 */
93
static event_listener_t _eventListenerGPIO;
94

    
95
/**
96
 * @brief   Listener object for OS events.
97
 */
98
static event_listener_t _eventListenerOS;
99

    
100
#if defined(MODULE_HAL_PROGIF) || defined(__DOXYGEN__)
101

    
102
/**
103
 * @brief   I/O channel for the programmer interface.
104
 */
105
static AosIOChannel _stdiochannel;
106

    
107
#endif /* defined(MODULE_HAL_PROGIF) */
108

    
109
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
110

    
111
/**
112
 * @brief   I/O shell channel for the programmer interface.
113
 */
114
static AosShellChannel _stdshellchannel;
115

    
116
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
117

    
118
/*
119
 * hook to add further static variables
120
 */
121
#if defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES)
122
AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES
123
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_STATIC_VARIABLES) */
124

    
125
/******************************************************************************/
126
/* LOCAL FUNCTIONS                                                            */
127
/******************************************************************************/
128

    
129
/**
130
 * @brief   Prints an error message about an unexpected event.
131
 *
132
 * @param[in] mask    The event mask.
133
 * @param[in] flags   The event flags.
134
 */
135
static inline void _unexpectedEventError(const eventmask_t mask, const eventflags_t flags)
136
{
137
#if (AMIROOS_CFG_DBG == true)
138
  aosDbgPrintf("CTRL: unexpected/unknown event received. mask: 0x%08X; flags: 0x%08X\n", mask, flags);
139
#else /* (AMIROOS_CFG_DBG == true) */
140
  (void)(mask);
141
  (void)(flags);
142
#endif /* (AMIROOS_CFG_DBG == true) */
143
  return;
144
}
145

    
146
#if ((AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_RTC == TRUE)) || defined(__DOXYGEN__)
147
#if (AMIROOS_CFG_SSSP_MASTER == true) || defined(__DOXYGEN__)
148

    
149
/**
150
 * @brief   Converter function to encode a TM value to a single unsigned 64 bit integer.
151
 *
152
 * @details Contents of the TM struct are mapped as follows:
153
 *            bits  |63     62|61      53|52    50|49         26|25     22|21     17|16     12|11      6|5       0|
154
 *            #bits |       2 |        9 |      3 |          24 |       4 |       5 |       5 |       6 |       6 |
155
 *            value |   isdst |     yday |   wday |        year |     mon |    mday |    hour |     min |     sec |
156
 *            range | special | [0, 365] | [0, 6] | [1900, ...] | [0, 11] | [1, 31] | [0, 23] | [0, 59] | [0, 61] |
157
 *          The Daylight Saving Time Flag (isdsst) is encoded as follows:
158
 *            DST not in effect         -> 0
159
 *            DST in effect             -> 1
160
 *            no information available  -> 2
161
 *
162
 * @param[in] src   Pointer to the TM struct to encode.
163
 *
164
 * @return  An unsigned 64 bit integer, which holds the encoded time value.
165
 */
166
static inline uint64_t _TM2U64(struct tm* src)
167
{
168
  aosDbgCheck(src != NULL);
169

    
170
  return (((uint64_t)(src->tm_sec  & 0x0000003F) << (0))               |
171
          ((uint64_t)(src->tm_min  & 0x0000003F) << (6))               |
172
          ((uint64_t)(src->tm_hour & 0x0000001F) << (12))              |
173
          ((uint64_t)(src->tm_mday & 0x0000001F) << (17))              |
174
          ((uint64_t)(src->tm_mon  & 0x0000000F) << (22))              |
175
          ((uint64_t)(src->tm_year & 0x00FFFFFF) << (26))              |
176
          ((uint64_t)(src->tm_wday & 0x00000007) << (50))              |
177
          ((uint64_t)(src->tm_yday & 0x000001FF) << (53))              |
178
          ((uint64_t)((src->tm_isdst == 0) ? 0 : (src->tm_isdst > 0) ? 1 : 2) << (62)));
179
}
180

    
181
/**
182
 * @brief   Serializes 64 bit unsigned integer input and stores it in a byte array.
183
 * @details Serialization is performed in big-endian fashion.
184
 *
185
 * @param[out]  dst   Pointer to the output buffer.
186
 * @param[in]   src   Data to be serialized.
187
 */
188
static inline void _serializeU64(uint8_t* dst, const uint64_t src)
189
{
190
  aosDbgCheck(dst != NULL);
191

    
192
  for (uint8_t byte = 0; byte < sizeof(uint64_t); ++byte) {
193
    dst[byte] = ((src >> ((sizeof(uint64_t) - (byte+1)) * 8)) & 0xFF);
194
  }
195

    
196
  return;
197
}
198

    
199
#endif /* (AMIROOS_CFG_SSSP_MASTER == true) */
200
#if (AMIROOS_CFG_SSSP_MASTER != true) || defined(__DOXYGEN__)
201

    
202
/**
203
 * @brief   Deserialize 64 bit unsigned integer data from a buffer.
204
 * @details Data is assumed to be serialized in big-endian fashion.
205
 *
206
 * @param[in] src   Pointer to the buffer of data to be deserialzed.
207
 *
208
 * @return    Deserialized 64 bit data.
209
 */
210
static inline uint64_t _deserializeU64(uint8_t* src)
211
{
212
  aosDbgCheck(src != NULL);
213

    
214
  uint64_t result = 0;
215
  for (uint8_t byte = 0; byte < sizeof(uint64_t); ++byte) {
216
    result |= ((uint64_t)src[byte] << ((sizeof(uint64_t) - (byte+1)) * 8));
217
  }
218

    
219
  return result;
220
}
221

    
222
/**
223
 * @brief   Converter functiomn to retrieve the encoded TM value from an unsigned 64 bit integer.
224
 *
225
 * @details For information on the encoding, please refer to @p _TM2U64 function.
226
 *
227
 * @param[out] dst  The TM struct to fill with the decoded values.
228
 * @param[in]  src  Unsigned 64 bit integer holding the encoded TM value.
229
 */
230
static inline void _U642TM(struct tm* dst, const uint64_t src)
231
{
232
  aosDbgCheck(dst != NULL);
233

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

    
244
  return;
245
}
246

    
247
#endif /* (AMIROOS_CFG_SSSP_MASTER != true) */
248
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) && (HAL_USE_RTC == TRUE) */
249

    
250
/**
251
 * @brief   Application entry point.
252
 */
253
int main(void)
254
{
255
  // local variables
256
  eventmask_t eventmask = 0;
257
  eventflags_t eventflags = 0;
258
  aos_shutdown_t shutdown = AOS_SHUTDOWN_NONE;
259
#if defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES)
260
  AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES
261
#endif /* defined(AMIROOS_CFG_MAIN_EXTRA_THREAD_VARIABLES) */
262

    
263
  /*
264
   * ##########################################################################
265
   * # system initialization                                                  #
266
   * ##########################################################################
267
   */
268

    
269
  /* hardware, kernel, and operating system initialization */
270
  // ChibiOS/HAL and custom hal additions (if any)
271
  halInit();
272
#if defined(MODULE_INIT_HAL_EXTRA)
273
  MODULE_INIT_HAL_EXTRA();
274
#endif /* defined(MODULE_INIT_HAL_EXTRA) */
275

    
276
  // ChibiOS/RT kernel and custom kernel additions (if any)
277
  chSysInit();
278
#if defined(MODULE_INIT_KERNEL_EXTRA)
279
  MODULE_INIT_KERNEL_EXTRA();
280
#endif /* defined(MODULE_INIT_KERNEL_EXTRA) */
281
#if (CH_CFG_USE_REGISTRY == TRUE)
282
  currp->name = _threadName;
283
#endif /* (CH_CFG_USE_REGISTRY == TRUE) */
284

    
285
  // AMiRo-OS, additional interrupts and custom OS additions (if any)
286
#if (AMIROOS_CFG_SHELL_ENABLE == true)
287
  aosSysInit(moduleShellPrompt);
288
#else /* (AMIROOS_CFG_SHELL_ENABLE == true) */
289
  aosSysInit(NULL);
290
#endif /* (AMIROOS_CFG_SHELL_ENABLE == true) */
291
#if defined(MODULE_INIT_INTERRUPTS)
292
  MODULE_INIT_INTERRUPTS();
293
#endif
294
#if defined(MODULE_INIT_OS_EXTRA)
295
  MODULE_INIT_OS_EXTRA();
296
#endif /* defined(MODULE_INIT_OS_EXTRA) */
297

    
298
  /* event associations */
299
#if (AMIROOS_CFG_SSSP_ENABLE == true)
300
  {
301
    eventflags_t flagsmask = AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK | moduleSsspEventflagPD() | moduleSsspEventflagS();
302
#if (AMIROOS_CFG_SSSP_MSI == true)
303
#if (AMIROOS_CFG_SSSP_STACK_START != true)
304
    flagsmask |= moduleSsspEventflagDN();
305
#endif /* (AMIROOS_CFG_SSSP_STACK_START != true) */
306
#if (AMIROOS_CFG_SSSP_STACK_END != true)
307
    flagsmask |= moduleSsspEventflagUP();
308
#endif /* (AMIROOS_CFG_SSSP_STACK_END != true) */
309
#endif /* (AMIROOS_CFG_SSSP_MSI == true) */
310
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, flagsmask);
311
  }
312
#else /* (AMIROOS_CFG_SSSP_ENABLE == true) */
313
  if (AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK) {
314
    chEvtRegisterMaskWithFlags(&aos.events.gpio, &_eventListenerGPIO, EVENTMASK_GPIO, AMIROOS_CFG_MAIN_LOOP_GPIOEVENT_FLAGSMASK);
315
  }
316
#endif /* (AMIROOS_CFG_SSSP_ENABLE == true) */
317
  chEvtRegisterMask(&aos.events.os, &_eventListenerOS, EVENTMASK_OS);
318

    
319
#if (AMIROOS_CFG_SSSP_ENABLE == true) && (AMIROOS_CFG_SSSP_STARTUP == true)
320

    
321
  /* perform SSSP basic initialization stage */
322

    
323
#if defined(MODULE_SSSP_BASICINIT_HOOK)
324
#if defined(MODULE_SSSP_BASICINIT_HOOK_ARGS)
325
  MODULE_SSSP_BASICINIT_HOOK(MODULE_SSSP_BASICINIT_HOOK_ARGS);
326
#else /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
327
  MODULE_SSSP_BASICINIT_HOOK();
328
#endif /* defined(MODULE_SSSP_BASICINIT_HOOK_ARGS) */
329
#endif /* defined(MODULE_SSSP_BASICINIT_HOOK) */
330

    
331
  // proceed to startup stage 1.2
332
#if (AMIROOS_CFG_SSSP_MASTER == true)
333
  while ((shutdown == AOS_SHUTDOWN_NONE) && (aosSsspProceed(NULL, EVENTMASK_SSSPDELAY, &eventmask) != AOS_SUCCESS)) {
334
    /*
335
     * This code is executed if the received event was not about the delay.
336
     * The received event could be casued by any listener.
337
     */
338
    // GPIO event
339
    if (eventmask & _eventListenerGPIO.events) {
340
      eventflags = chEvtGetAndClearFlags(&_eventListenerGPIO);
341
      // PD event
342
      if (eventflags & moduleSsspEventflagPD()) {
343
        shutdown = AOS_SHUTDOWN_PASSIVE;
344
      } else {
345
#if defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK)
346
        MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK(eventmask, eventflags);
347
#else /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
348
        /* silently ignore any other GPIO events */
349
#endif /* defined(MODULE_SSSP_STARTUP_1_1_GPIOEVENT_HOOK) */
350
      }
351
    }