mirror of https://github.com/ARMmbed/mbed-os.git
Watchdog refactoring to multithreaded thread.
-Added API to register muliple threads to watchdog drivers -Watchdog timeout reconfigures everytime whenever new register thread with longer timeout period -New APIs for watchdog wd_register(const osThreadId_t tid, const uint32_t timeout) to register to watchdog wd_unregister(const osThreadId_t tid) to unregister to watchdog kick(const osThreadId_t tid) to refresh the watchdogpull/10645/head
parent
f4e6966e14
commit
3cd52d4732
|
@ -20,6 +20,72 @@
|
|||
|
||||
namespace mbed {
|
||||
|
||||
uint32_t Watchdog::_is_initialized = 0;
|
||||
uint32_t Watchdog::_re_initialize = 0;
|
||||
uint32_t Watchdog::_bitmask = 0;
|
||||
uint32_t Watchdog::_kick_bitmask = 0;
|
||||
Watchdog::watchdog_usr_info Watchdog::_usr_info[MAX_THREAD_WATCHDOG_SUPPORT] = {0};
|
||||
rtos::Mutex Watchdog::_ThreadSafeLockMutex;
|
||||
mbed_error_status_t Watchdog::wd_register(const osThreadId_t tid, const uint32_t timeout)
|
||||
{
|
||||
int store_index = -1;
|
||||
watchdog_status_t sts;
|
||||
int i;
|
||||
_ThreadSafeLockMutex.lock();
|
||||
uint32_t conf_timeout = hal_watchdog_get_reload_value();
|
||||
if(_is_initialized) {
|
||||
if(timeout > conf_timeout) {
|
||||
_re_initialize = 1;
|
||||
hal_watchdog_stop();
|
||||
}
|
||||
|
||||
for(i =0 ; i < MAX_THREAD_WATCHDOG_SUPPORT; i++) {
|
||||
if(_bitmask & (1 << i))
|
||||
{
|
||||
if(_usr_info[i].tid == tid) {
|
||||
if(_re_initialize) {
|
||||
store_index = i;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(store_index < 0) {
|
||||
store_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
store_index = 0;
|
||||
}
|
||||
|
||||
if(store_index >= 0) {
|
||||
_usr_info[store_index].tid = tid;
|
||||
_usr_info[store_index].bit_idx = store_index;
|
||||
_bitmask |= (1 << store_index);
|
||||
store_index = -1;
|
||||
|
||||
if(!_is_initialized || _re_initialize ) {
|
||||
sts = start(timeout);
|
||||
if(sts != WATCHDOG_STATUS_OK ) {
|
||||
_is_initialized = 0;
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
_is_initialized = 1;
|
||||
_re_initialize = 0;
|
||||
}
|
||||
} else {
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_ERROR_OVERFLOW;
|
||||
}
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_SUCCESS;
|
||||
|
||||
}
|
||||
watchdog_status_t Watchdog::start(const uint32_t timeout)
|
||||
{
|
||||
if (timeout == 0) {
|
||||
|
@ -32,22 +98,75 @@ watchdog_status_t Watchdog::start(const uint32_t timeout)
|
|||
|
||||
watchdog_config_t config;
|
||||
config.timeout_ms = timeout;
|
||||
|
||||
return hal_watchdog_init(&config);
|
||||
}
|
||||
|
||||
|
||||
void Watchdog::kick()
|
||||
void Watchdog::kick(const osThreadId_t tid)
|
||||
{
|
||||
hal_watchdog_kick();
|
||||
int i;
|
||||
|
||||
_ThreadSafeLockMutex.lock();
|
||||
if(_is_initialized ) {
|
||||
for(i =0 ; i < MAX_THREAD_WATCHDOG_SUPPORT; i++) {
|
||||
if(_usr_info[i].tid == tid)
|
||||
{
|
||||
_kick_bitmask |= (1 << _usr_info[i].bit_idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!_re_initialize && _bitmask == _kick_bitmask) {
|
||||
hal_watchdog_kick();
|
||||
_kick_bitmask = 0;
|
||||
}
|
||||
}
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
watchdog_status_t Watchdog::stop()
|
||||
mbed_error_status_t Watchdog::stop()
|
||||
{
|
||||
return hal_watchdog_stop();
|
||||
watchdog_status_t sts;
|
||||
|
||||
if(_is_initialized ) {
|
||||
sts = hal_watchdog_stop();
|
||||
if(sts != WATCHDOG_STATUS_OK ) {
|
||||
return MBED_ERROR_ALREADY_IN_USE;
|
||||
}
|
||||
else
|
||||
{
|
||||
_is_initialized = 0;
|
||||
_kick_bitmask = 0;
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
return MBED_ERROR_OPERATION_PROHIBITED;
|
||||
}
|
||||
|
||||
mbed_error_status_t Watchdog::wd_unregister(const osThreadId_t tid)
|
||||
{
|
||||
int i;
|
||||
uint32_t tbit = _bitmask;
|
||||
_ThreadSafeLockMutex.lock();
|
||||
for(i =0 ; i < MAX_THREAD_WATCHDOG_SUPPORT; i++) {
|
||||
if(_usr_info[i].tid == tid) {
|
||||
_bitmask &= (~(1 << _usr_info[i].bit_idx));
|
||||
_kick_bitmask &= (~(1 << _usr_info[i].bit_idx));
|
||||
_usr_info[i].tid = 0;
|
||||
_usr_info[i].bit_idx = 0;
|
||||
}
|
||||
}
|
||||
if(_bitmask == tbit) {
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_ERROR_OPERATION_PROHIBITED;
|
||||
}
|
||||
if(_bitmask == 0) {
|
||||
stop();
|
||||
}
|
||||
_ThreadSafeLockMutex.unlock();
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
|
||||
uint32_t Watchdog::reload_value() const
|
||||
{
|
||||
|
|
|
@ -24,8 +24,18 @@
|
|||
|
||||
#include <cstdio>
|
||||
|
||||
#include "mbed_error.h"
|
||||
|
||||
#include "rtos/Mutex.h"
|
||||
|
||||
#include "rtos/Thread.h"
|
||||
|
||||
#define MAX_THREAD_WATCHDOG_SUPPORT 32
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
||||
|
||||
/** \addtogroup drivers */
|
||||
/** A system timer that will reset the system in the case of system failures or
|
||||
* malfunctions.
|
||||
|
@ -34,10 +44,10 @@ namespace mbed {
|
|||
* @code
|
||||
*
|
||||
* Watchdog watchdog = Watchdog();
|
||||
* watchdog.start(2000);
|
||||
* watchdog.register(tid, 2000);
|
||||
*
|
||||
* while (true) {
|
||||
* watchdog.kick();
|
||||
* watchdog.kick(tid);
|
||||
*
|
||||
* // Application code
|
||||
* }
|
||||
|
@ -49,17 +59,35 @@ public:
|
|||
Watchdog() {}
|
||||
|
||||
public:
|
||||
/** Start an independent watchdog timer with specified parameters
|
||||
|
||||
|
||||
|
||||
/** Register to watchdog timer with specified parameters,
|
||||
* This API is only to register to watchdog and Watchdog automatically starts
|
||||
* if atleast one user registered.
|
||||
*
|
||||
* @param timeout Timeout of the watchdog in milliseconds
|
||||
*
|
||||
* @param tid Thread id
|
||||
*
|
||||
* @return status MBED_SUCCESS if register to watchdog timer was succeeded
|
||||
* successfully. MBED_ERROR_INVALID_ARGUMENT if one of the input
|
||||
* parameters is out of range for the current platform.
|
||||
* MBED_ERROR_UNSUPPORTED if one of the enabled input
|
||||
* parameters is not supported by the current platform.
|
||||
*/
|
||||
mbed_error_status_t wd_register(const osThreadId_t tid, const uint32_t timeout);
|
||||
|
||||
/** Unregister from watchdog with specified parameters
|
||||
*
|
||||
* @param timeout Timeout of the watchdog in milliseconds
|
||||
* @param tid Thread id
|
||||
*
|
||||
* @return status WATCHDOG_STATUS_OK if the watchdog timer was started
|
||||
* successfully. WATCHDOG_INVALID_ARGUMENT if one of the input
|
||||
* parameters is out of range for the current platform.
|
||||
* WATCHDOG_NOT_SUPPORTED if one of the enabled input
|
||||
* parameters is not supported by the current platform.
|
||||
* @return status MBED_SUCCESS if register to watchdog timer was succeeded
|
||||
* successfully. MBED_ERROR_INVALID_ARGUMENT if tid is not registered
|
||||
* and try to do unregister
|
||||
*/
|
||||
watchdog_status_t start(const uint32_t timeout);
|
||||
mbed_error_status_t wd_unregister(const osThreadId_t tid);
|
||||
|
||||
|
||||
|
||||
/** Refreshes the watchdog timer.
|
||||
|
@ -84,7 +112,6 @@ public:
|
|||
*/
|
||||
watchdog_status_t stop();
|
||||
|
||||
|
||||
/** Get the watchdog timer refresh value
|
||||
*
|
||||
* This function returns the refresh timeout of the watchdog timer.
|
||||
|
@ -100,6 +127,47 @@ public:
|
|||
* platform in milliseconds
|
||||
*/
|
||||
static uint32_t max_timeout();
|
||||
protected :
|
||||
/** Start an independent watchdog timer with specified parameters
|
||||
*
|
||||
* @param timeout Timeout of the watchdog in milliseconds
|
||||
*
|
||||
* @return status WATCHDOG_STATUS_OK if the watchdog timer was started
|
||||
* successfully. WATCHDOG_INVALID_ARGUMENT if one of the input
|
||||
* parameters is out of range for the current platform.
|
||||
* WATCHDOG_NOT_SUPPORTED if one of the enabled input
|
||||
* parameters is not supported by the current platform.
|
||||
*/
|
||||
watchdog_status_t start(const uint32_t timeout);
|
||||
|
||||
/** Stops the watchdog timer
|
||||
*
|
||||
* Calling this function will attempt to disable any currently running
|
||||
* watchdog timers if supported by the current platform.
|
||||
*
|
||||
* @return Returns WATCHDOG_STATUS_OK if the watchdog timer was succesfully
|
||||
* stopped, or if the timer was never started. Returns
|
||||
* WATCHDOG_STATUS_NOT_SUPPORTED if the watchdog cannot be disabled
|
||||
* on the current platform.
|
||||
*/
|
||||
mbed_error_status_t stop();
|
||||
|
||||
private:
|
||||
static rtos::Mutex _ThreadSafeLockMutex;//Thread safe mutex for concurrent access protection
|
||||
|
||||
typedef struct
|
||||
{
|
||||
osThreadId_t tid;
|
||||
uint32_t bit_idx;
|
||||
}watchdog_usr_info ;
|
||||
|
||||
static watchdog_usr_info _usr_info[MAX_THREAD_WATCHDOG_SUPPORT];//Dats structure used to store the tid and their respective bit position of "_bitmask"
|
||||
|
||||
static uint32_t _bitmask; //Every bit is used to denote the registered threads/user
|
||||
static uint32_t _kick_bitmask;//Every bit is used to denote the registered threads/user called kick(tid)
|
||||
static uint32_t _is_initialized;//represents the watchdog initialized/un-initialized
|
||||
static uint32_t _re_initialize;//represents the watchdog reinitizliation
|
||||
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
Loading…
Reference in New Issue