Simplify system watchdog API

This commit is contained in:
Henrik Stickann 2023-01-20 15:40:14 +01:00
parent 1c8e427bc3
commit 04b2303a3a
5 changed files with 107 additions and 149 deletions

View File

@ -5,8 +5,6 @@
#ifndef STA_RTOS_SYSTEM_WATCHDOG_HPP
#define STA_RTOS_SYSTEM_WATCHDOG_HPP
#include <sta/rtos/system/names.hpp>
/**
* @defgroup STA_RTOS_Watchdog Watchdog task
@ -37,61 +35,10 @@
#endif // !STA_RTOS_WATCHDOG_TIMER_PERIOD
/**
* @def STA_RTOS_WATCHDOG_TIMER_NAME
* @brief Set name of watchdog timer.
*
* @ingroup STA_RTOS_BuildConfig
*/
#ifndef STA_RTOS_WATCHDOG_TIMER_NAME
# define STA_RTOS_WATCHDOG_TIMER_NAME heartbeat
#endif // !STA_RTOS_WATCHDOG_TIMER_NAME
/**
* @def STA_RTOS_WATCHDOG_TIMER_HANDLE
* @brief Set variable name of heartbeat timer handle.
*
* @ingroup STA_RTOS_BuildConfig
*/
#ifndef STA_RTOS_WATCHDOG_TIMER_HANDLE
# define STA_RTOS_WATCHDOG_TIMER_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TIMER_NAME)
#endif // !STA_RTOS_WATCHDOG_TIMER_HANDLE
/**
* @def STA_RTOS_WATCHDOG_TIMER_CALLBACK
* @brief Set name of heartbeat timer callback function.
*
* @ingroup STA_RTOS_BuildConfig
*/
#ifndef STA_RTOS_WATCHDOG_TIMER_CALLBACK
# define STA_RTOS_WATCHDOG_TIMER_CALLBACK STA_RTOS_MAKE_CALLBACK_NAME(STA_RTOS_WATCHDOG_TIMER_NAME)
#endif // !STA_RTOS_WATCHDOG_TIMER_CALLBACK
/**
* @def STA_RTOS_WATCHDOG_TASK_NAME
* @brief Set name of watchdog task.
*
* @ingroup STA_RTOS_BuildConfig
*/
#ifndef STA_RTOS_WATCHDOG_TASK_NAME
# define STA_RTOS_WATCHDOG_TASK_NAME watchdog
#endif // !STA_RTOS_WATCHDOG_TASK_NAME
/**
* @def STA_RTOS_WATCHDOG_ENTRY_FUNCTION
* @brief Set name of watchdog task entry function.
*
* @ingroup STA_RTOS_BuildConfig
*/
#ifndef STA_RTOS_WATCHDOG_ENTRY_FUNCTION
# define STA_RTOS_WATCHDOG_ENTRY_FUNCTION STA_RTOS_MAKE_ENTRY_NAME(STA_RTOS_WATCHDOG_TASK_NAME)
#endif // !STA_RTOS_WATCHDOG_ENTRY_FUNCTION
#include <sta/config.hpp>
#ifdef STA_RTOS_WATCHDOG_ENABLE
#include <cstdint>
@ -111,11 +58,12 @@ namespace sta
namespace rtos
{
/**
* @brief Start heartbeat timer for watchdog.
* @brief Initialize system watchdog.
*
* @ingroup STA_RTOS_Watchdog
*/
void startWatchdogTimer();
void initWatchdog();
/**
* @brief Send notification to watchdog task.
*

103
src/system/watchdog.cpp Normal file
View File

@ -0,0 +1,103 @@
#include <sta/rtos/system/watchdog.hpp>
#ifdef STA_RTOS_WATCHDOG_ENABLE
#include <sta/assert.hpp>
#include <sta/lang.hpp>
#include <sta/rtos/defs.hpp>
#include <sta/rtos/system/system_event.hpp>
#include <cmsis_os2.h>
#include <FreeRTOS.h>
namespace
{
StaticTask_t watchdogCB;
StaticTimer_t watchdogTimerCB;
osThreadId_t watchdogTaskHandle = nullptr;
osTimerId_t watchdogTimerHandle = nullptr;
// Static stack memory
uint32_t stackBuffer[256];
}
extern "C"
{
void watchdogTask(void * arg);
void watchdogTimerCallback(void *);
}
namespace sta
{
namespace rtos
{
void initWatchdog()
{
// Create thread using static allocation
const osThreadAttr_t taskAttributes = {
.name = "sysWatchdog",
.cb_mem = &watchdogCB,
.cb_size = sizeof(watchdogCB),
.stack_mem = &stackBuffer[0],
.stack_size = sizeof(stackBuffer),
.priority = (osPriority_t) osPriorityLow,
};
watchdogTaskHandle = osThreadNew(watchdogTask, NULL, &taskAttributes);
STA_ASSERT_MSG(watchdogTaskHandle != nullptr, "System watchdog task initialization failed");
// Create timer using static allocation
const osTimerAttr_t timerAttributes = {
.name = "sysWatchdogTimer",
.attr_bits = 0, // Reserved, must be set to 0
.cb_mem = &watchdogTimerCB,
.cb_size = sizeof(watchdogTimerCB)
};
watchdogTimerHandle = osTimerNew(watchdogTimerCallback, osTimerPeriodic, nullptr, &timerAttributes);
STA_ASSERT_MSG(watchdogTimerHandle != nullptr, "System watchdog timer initialization failed");
osTimerStart(watchdogTimerHandle, STA_RTOS_WATCHDOG_TIMER_PERIOD);
}
void notifyWatchdog(uint32_t flags)
{
STA_ASSERT_MSG(watchdogTaskHandle != nullptr, "System watchdog not initialized");
osThreadFlagsSet(watchdogTaskHandle, flags);
}
STA_WEAK void watchdogEventHandler(void * arg, uint32_t flags)
{}
} // namespace rtos
} // namespace sta
void watchdogTask(void * arg)
{
sta::rtos::waitForStartupEvent();
while (true)
{
// Wait for any flag to be set
uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, osWaitForever);
// Call event handler
sta::rtos::watchdogEventHandler(arg, flags);
}
}
void watchdogTimerCallback(void *)
{
// Notify watchdog task to send heartbeat message
// Required because blocking in a timer callback is not allowed
osThreadFlagsSet(watchdogTaskHandle, STA_WATCHDOG_FLAG_HEARTBEAT);
}
#endif // STA_RTOS_WATCHDOG_ENABLE

View File

@ -1,18 +0,0 @@
#ifndef STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP
#define STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP
#include <sta/rtos/system/watchdog.hpp>
#include <cmsis_os2.h>
#define WATCHDOG_TASK_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TASK_NAME)
#define WATCHDOG_TIMER_HANDLE STA_RTOS_MAKE_HANDLE_NAME(STA_RTOS_WATCHDOG_TIMER_NAME)
// Access handles from freertos.c
extern osThreadId_t WATCHDOG_TASK_HANDLE;
extern osTimerId_t WATCHDOG_TIMER_HANDLE;
#endif // STA_RTOS_SYSTEM_WATCHDOG_HANDLES_HPP

View File

@ -1,32 +0,0 @@
#include <sta/rtos/system/watchdog.hpp>
#ifdef STA_RTOS_WATCHDOG_ENABLE
#include "handles.hpp"
namespace sta
{
namespace rtos
{
void startWatchdogTimer()
{
osTimerStart(WATCHDOG_TIMER_HANDLE, STA_RTOS_WATCHDOG_TIMER_PERIOD);
}
} // namespace rtos
} // namespace sta
// Declare with C linkage
extern "C"
{
void STA_RTOS_WATCHDOG_TIMER_CALLBACK(void *)
{
// Notify watchdog task to send heartbeat message
// Required because blocking in a timer callback is not allowed
osThreadFlagsSet(WATCHDOG_TASK_HANDLE, STA_WATCHDOG_FLAG_HEARTBEAT);
}
}
#endif // STA_RTOS_WATCHDOG_ENABLE

View File

@ -1,43 +0,0 @@
#include <sta/rtos/system/watchdog.hpp>
#ifdef STA_RTOS_WATCHDOG_ENABLE
#include <sta/rtos/defs.hpp>
#include <sta/rtos/system/system_event.hpp>
#include "handles.hpp"
namespace sta
{
namespace rtos
{
void notifyWatchdog(uint32_t flags)
{
osThreadFlagsSet(WATCHDOG_TASK_HANDLE, flags);
}
} // namespace rtos
} // namespace sta
// Declare with C linkage
extern "C"
{
void STA_RTOS_WATCHDOG_ENTRY_FUNCTION(void * arg)
{
sta::rtos::waitForStartupEvent();
while (true)
{
// Wait for any flag to be set
uint32_t flags = osThreadFlagsWait(STA_RTOS_THREAD_FLAGS_VALID_BITS, osFlagsWaitAny, osWaitForever);
// Call event handler
sta::rtos::watchdogEventHandler(arg, flags);
}
}
}
#endif // STA_RTOS_WATCHDOG_ENABLE