Add startup and watchdog modules

This commit is contained in:
Henrik Stickann 2022-03-31 18:03:37 +02:00
parent 5fe44ddecf
commit 9b3e3efc8b
8 changed files with 207 additions and 5 deletions

View File

@ -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)

13
include/sta/os2.hpp Normal file
View File

@ -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

View File

@ -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
#endif // STA_SYSTEM_EVENT_HPP

26
include/sta/watchdog.hpp Normal file
View File

@ -0,0 +1,26 @@
#ifndef STA_WATCHDOG_HPP
#define STA_WATCHDOG_HPP
#include <sta/config.hpp>
#ifdef STA_WATCHDOG_ENABLE
#include <stdint.h>
// 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

44
src/startup.cpp Normal file
View File

@ -0,0 +1,44 @@
#include <sta/config.hpp>
#ifdef STA_STARTUP_TASK_ENABLE
#include <sta/lang.hpp>
#include <sta/system_event.hpp>
#include <sta/watchdog.hpp>
#include <main.h>
#include <cmsis_os2.h>
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

View File

@ -5,6 +5,7 @@
#include <cmsis_os2.h>
// Access handles from freertos.c
extern osEventFlagsId_t systemEventHandle;
@ -34,4 +35,4 @@ namespace sta
} // namespace sta
#endif // STA_SYSTEM_EVENT_ENABLE
#endif // STA_SYSTEM_EVENT_ENABLE

View File

@ -0,0 +1,38 @@
#include <sta/watchdog.hpp>
#ifdef STA_WATCHDOG_ENABLE
#include <cmsis_os2.h>
#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

50
src/watchdog/watchdog.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <sta/watchdog.hpp>
#ifdef STA_WATCHDOG_ENABLE
#include <sta/lang.hpp>
#include <sta/os2.hpp>
#include <sta/system_event.hpp>
#include <main.h>
#include <cmsis_os2.h>
// 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