diff --git a/README.md b/README.md index f4a02c2..54ff2a6 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,39 @@ Library using cmsis_os2.h functionality for RTOS projects. +Modules are enabled via defines set in `sta/config.hpp` provided by the application. ## System events -Enable via `STA_SYSTEM_EVENT_ENABLE` defined in `sta/config.hpp`. +Enable: `STA_SYSTEM_EVENT_ENABLE` -Requires setup of a `systemEvent` EventFlag in the project. +Requirements: +* EventFlag: `systemEvent` + + +## Watchdog + +Watchdog task gets woken periodically (every `STA_WATCHDOG_TIMER_PERIOD` ticks) or via `sta::nofityWatchdog(uint32_t)` calls +and calls `sta::watchdogEventHandler(void *, uint32_t)`. Applications *must* implement `sta::watchdogEventHandler(void *, uint32_t)`. + + +Enable: `STA_WATCHDOG_ENABLE` + +Requirements: +* Task: `watchdog` +* Timer: `heartbeat` + +Configuration: +* Heartbeat timer period: `STA_WATCHDOG_TIMER_PERIOD` (defaults to `1000`). + + +## Startup task + +Startup task calls `sta::startupTaskExtras(void *)`, starts the watchdog timer if enabled and terminates the thread. +`sta::startupTaskExtras(void *)` may be overridden by the application. + +Enable: `STA_STARTUP_TASK_ENABLE` + +Requirements: +* Task: `startupTask` (alternative: call manually in freertos.c default task) diff --git a/include/sta/os2.hpp b/include/sta/os2.hpp new file mode 100644 index 0000000..3fcb761 --- /dev/null +++ b/include/sta/os2.hpp @@ -0,0 +1,13 @@ +#ifndef STA_OS2_HPP +#define STA_OS2_HPP + + +// See limits defined in cmsis_os2.c +#define STA_OS2_MAX_BITS_TASK_NOTIFY 31U +#define STA_OS2_MAX_BITS_EVENT_GROUPS 24U + +#define STA_OS2_THREAD_FLAGS_VALID_BITS ((1UL << STA_OS2_MAX_BITS_TASK_NOTIFY) - 1U) +#define STA_OS2_EVENT_FLAGS_VALID_BITS ((1UL << STA_OS2_MAX_BITS_EVENT_GROUPS) - 1U) + + +#endif // STA_OS2_HPP diff --git a/include/sta/system_event.hpp b/include/sta/system_event.hpp index 990322b..68e82b9 100644 --- a/include/sta/system_event.hpp +++ b/include/sta/system_event.hpp @@ -11,7 +11,7 @@ // System event flags // -#define STA_SYSTEM_EVENT_STARTUP 0x00100000U +#define STA_SYSTEM_EVENT_STARTUP 0x100000U namespace sta @@ -32,6 +32,7 @@ namespace sta */ void waitForSystemEvents(uint32_t flags, uint32_t options, uint32_t timeout); + /** * @brief Signal startup system event */ @@ -48,4 +49,4 @@ namespace sta #endif // STA_SYSTEM_EVENT_ENABLE -#endif // STA_SYSTEM_EVENT_HPP \ No newline at end of file +#endif // STA_SYSTEM_EVENT_HPP diff --git a/include/sta/watchdog.hpp b/include/sta/watchdog.hpp new file mode 100644 index 0000000..def86b2 --- /dev/null +++ b/include/sta/watchdog.hpp @@ -0,0 +1,26 @@ +#ifndef STA_WATCHDOG_HPP +#define STA_WATCHDOG_HPP + +#include + +#ifdef STA_WATCHDOG_ENABLE + +#include + + +// Watchdog task flags +// + +#define STA_WATCHDOG_FLAG_HEARTBEAT 0x00001000U + + +namespace sta +{ + void startWatchdogTimer(); + void notifyWatchdog(uint32_t flags); +} // namespace sta + + +#endif // STA_WATCHDOG_ENABLE + +#endif // STA_WATCHDOG_HPP diff --git a/src/startup.cpp b/src/startup.cpp new file mode 100644 index 0000000..4c67e0a --- /dev/null +++ b/src/startup.cpp @@ -0,0 +1,44 @@ +#include + +#ifdef STA_STARTUP_TASK_ENABLE + +#include +#include +#include + +#include + +#include + + +namespace sta +{ + // Weak noop to be overridden by application if required + STA_WEAK void startupTaskExtras(void *) {} +} // namespace sta + + +// Declare with C linkage +extern "C" +{ + void startupTask(void * arg) + { + // Call further initialization code + sta::startupTaskExtras(arg); + + +#ifdef STA_WATCHDOG_ENABLE + // Start timers + sta::startWatchdogTimer(); +#endif + + // Wake tasks + sta::signalStartupEvent(); + + // Terminate task + osThreadExit(); + } +} + + +#endif // STA_STARTUP_TASK_ENABLE diff --git a/src/system_event.cpp b/src/system_event.cpp index fbd1649..419f6e3 100644 --- a/src/system_event.cpp +++ b/src/system_event.cpp @@ -5,6 +5,7 @@ #include +// Access handles from freertos.c extern osEventFlagsId_t systemEventHandle; @@ -34,4 +35,4 @@ namespace sta } // namespace sta -#endif // STA_SYSTEM_EVENT_ENABLE \ No newline at end of file +#endif // STA_SYSTEM_EVENT_ENABLE diff --git a/src/watchdog/heartbeat.cpp b/src/watchdog/heartbeat.cpp new file mode 100644 index 0000000..778a489 --- /dev/null +++ b/src/watchdog/heartbeat.cpp @@ -0,0 +1,38 @@ +#include + +#ifdef STA_WATCHDOG_ENABLE + +#include + + +#ifndef STA_WATCHDOG_TIMER_PERIOD +# define STA_WATCHDOG_TIMER_PERIOD 1000 +#endif // STA_WATCHDOG_TIMER_PERIOD + + +// Access handles from freertos.c +extern osTimerId_t heartbeatHandle; + + +namespace sta +{ + void startWatchdogTimer() + { + osTimerStart(heartbeatHandle, STA_WATCHDOG_TIMER_PERIOD); + } +} // namespace sta + + +// Declare with C linkage +extern "C" +{ + void heartbeatCallback(void *) + { + // Notify watchdog task to send heartbeat message + // Required because blocking in a timer callback is not allowed + sta::notifyWatchdog(STA_WATCHDOG_FLAG_HEARTBEAT); + } +} + + +#endif // STA_WATCHDOG_ENABLE diff --git a/src/watchdog/watchdog.cpp b/src/watchdog/watchdog.cpp new file mode 100644 index 0000000..9441ddd --- /dev/null +++ b/src/watchdog/watchdog.cpp @@ -0,0 +1,50 @@ +#include + +#ifdef STA_WATCHDOG_ENABLE + +#include +#include +#include + +#include + +#include + + +// Access handles from freertos.c +extern osThreadId_t watchdogHandle; + + +namespace sta +{ + void notifyWatchdog(uint32_t flags) + { + osThreadFlagsSet(watchdogHandle, flags); + } + + + // Handler for watchdog events + extern void watchdogEventHandler(void * arg, uint32_t flags); +} // namespace sta + + +// Declare with C linkage +extern "C" +{ + STA_WEAK void watchdogTask(void * arg) + { + sta::waitForStartupEvent(); + + while (true) + { + // Wait for any flag to be set + uint32_t flags = osThreadFlagsWait(STA_OS2_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, osWaitForever); + + // Call event handler + sta::watchdogEventHandler(arg, flags); + } + } +} + + +#endif // STA_WATCHDOG_ENABLE