Watchdog: keep it simple - providing simple driver functionality

No callbacks or tickers. User is handling kick() method directly based on timeout set.
VirtualWatchdog manages ticker and callback.
pull/10857/head
Martin Kojtal 2019-06-28 11:43:07 +01:00
parent 28398e6254
commit bb473d916e
4 changed files with 44 additions and 62 deletions

View File

@ -19,10 +19,20 @@
#include "drivers/VirtualWatchdog.h"
#include "drivers/Watchdog.h"
#define MS_TO_US(x) ((x) * 1000)
#define US_TO_MS(x) ((x) / 1000)
namespace mbed {
#if DEVICE_LPTICKER
SingletonPtr<LowPowerTicker> _ticker;
#else
SingletonPtr<Ticker> _ticker;
#endif
VirtualWatchdog *VirtualWatchdog::_first = NULL;
bool VirtualWatchdog::_is_hw_watchdog_running = false;
us_timestamp_t VirtualWatchdog::_ticker_timeout = 0;
VirtualWatchdog::VirtualWatchdog(uint32_t timeout, const char *const str): _name(str)
{
@ -37,7 +47,12 @@ VirtualWatchdog::VirtualWatchdog(uint32_t timeout, const char *const str): _name
MBED_MAKE_ERROR(MBED_MODULE_DRIVER_WATCHDOG, MBED_ERROR_INITIALIZATION_FAILED);
}
// we use default hw timeout provided by config
watchdog.start(&VirtualWatchdog::process, Watchdog::watchdog_timeout);
watchdog.start(Watchdog::watchdog_timeout);
_ticker_timeout = MS_TO_US(Watchdog::watchdog_timeout / 2);
if (_ticker_timeout == 0) {
_ticker_timeout = 1;
}
_ticker->attach_us(callback(this, &VirtualWatchdog::process), _ticker_timeout);
_is_hw_watchdog_running = true;
}
}
@ -104,14 +119,14 @@ void VirtualWatchdog::remove_from_list()
}
}
void VirtualWatchdog::process(uint32_t elapsed_ms)
void VirtualWatchdog::process()
{
VirtualWatchdog *cur_ptr = _first;
while (cur_ptr != NULL) {
if (cur_ptr->_current_count > cur_ptr->_timeout) {
system_reset();
} else {
cur_ptr->_current_count += elapsed_ms;
cur_ptr->_current_count += US_TO_MS(_ticker_timeout);
}
cur_ptr = cur_ptr->_next;
}

View File

@ -25,7 +25,8 @@
#include "platform/mbed_critical.h"
#include "platform/mbed_power_mgmt.h"
#include "platform/mbed_assert.h"
#include "platform/SingletonPtr.h"
#include "drivers/LowPowerTicker.h"
namespace mbed {
/** \addtogroup drivers */
@ -87,14 +88,6 @@ public:
*/
void kick();
/** Periodic callback method (runs by periodic call from ticker) used this API interface
* to go through all the registered user/threads of watchdog.
*
* @param elapsed_ms Elapsed milliseconds
*
* Otherwise, the system resets.
*/
static void process(uint32_t elapsed_ms);
protected :
/** Use add_to_list to store the registered user in the list.
@ -107,7 +100,14 @@ protected :
*
*/
void remove_from_list();
private:
/** Periodic ticker handler to go through all the registered user/threads of watchdog.
*
* Otherwise, the system resets.
*/
void process();
uint32_t _timeout; //_timeout initialized via constructor while creating instance of this class
const char *_name; //To store the details of user
uint32_t _current_count; //this parameter is used to reset everytime threads/user calls kick
@ -115,6 +115,17 @@ private:
static bool _is_hw_watchdog_running; // track we are the first owner of watchdog
static VirtualWatchdog *_first; //List to store the user/threads who called start
VirtualWatchdog *_next;
#if DEVICE_LPTICKER
/** Create singleton instance of LowPowerTicker for watchdog periodic call back of kick.
*/
static SingletonPtr<LowPowerTicker> _ticker;
#else
/** Create singleton instance of Ticker for watchdog periodic call back of kick.
*/
static SingletonPtr<Ticker> _ticker;
#endif
static us_timestamp_t _ticker_timeout;
};
} // namespace mbed

View File

@ -18,11 +18,9 @@
#include "drivers/Watchdog.h"
#define MS_TO_US(x) ((x) * 1000) //macro to convert millisecond to microsecond
namespace mbed {
Watchdog::Watchdog() : _running(false), _callback(NULL)
Watchdog::Watchdog() : _running(false)
{
}
@ -30,13 +28,11 @@ Watchdog::~Watchdog()
{
}
bool Watchdog::start(Callback<void(uint32_t)> func, uint32_t timeout)
bool Watchdog::start(uint32_t timeout)
{
MBED_ASSERT(timeout < get_max_timeout());
core_util_critical_section_enter();
// we update callback always, to be able to register new hook if needed
_callback = func;
if (_running) {
core_util_critical_section_exit();
return false;
@ -48,14 +44,6 @@ bool Watchdog::start(Callback<void(uint32_t)> func, uint32_t timeout)
_running = true;
}
core_util_critical_section_exit();
if (_running) {
_ticker_timeout = MS_TO_US(timeout / 2);
if (_ticker_timeout == 0) {
_ticker_timeout = 1;
}
_ticker->attach_us(callback(this, &Watchdog::timeout_handler), _ticker_timeout);
}
return _running;
}
@ -70,9 +58,7 @@ bool Watchdog::stop()
if (sts != WATCHDOG_STATUS_OK) {
msts = false;
} else {
_ticker->detach();
_running = false;
_callback = NULL;
}
} else {
@ -89,14 +75,6 @@ void Watchdog::kick()
core_util_critical_section_exit();
}
void Watchdog::timeout_handler()
{
kick();
if (_callback) {
_callback(_ticker_timeout / 1000);
}
}
bool Watchdog::is_running() const
{
return _running;

View File

@ -25,8 +25,6 @@
#include "platform/mbed_critical.h"
#include "hal/watchdog_api.h"
#include "platform/NonCopyable.h"
#include "platform/SingletonPtr.h"
#include "drivers/LowPowerTicker.h"
#include <cstdio>
namespace mbed {
@ -67,16 +65,13 @@ public:
/** Start the watchdog timer
*
* If watchdog is already running, only callback is being updated (timeout can't be set to watchdog neither ticker).
*
* @param func Callback to be invoked after timeout, it has the argument - time elapsed in milliseconds
* @param timeout Ticker timeout to be kicking the watchdog
* @param timeout Watchdog timeout
*
* @return status true if the watchdog timer was started
* successfully. assert if one of the input parameters is out of range for the current platform.
* false if watchdog timer was not started
*/
bool start(Callback<void(uint32_t)> func = NULL, uint32_t timeout = watchdog_timeout);
bool start(uint32_t timeout = watchdog_timeout);
/** Stops the watchdog timer
*
@ -106,14 +101,13 @@ public:
/** Check if watchdog is already running
*
* @return Maximum refresh value supported by the watchdog for the current
* platform in milliseconds
* @return true if watchdog is running, false otherwise
*/
bool is_running() const;
/** Kick watchdog
*
* This method is useful to control kicking by application
* This method is useful to control kicking by application in ticker callback periodically
*/
void kick();
@ -121,23 +115,7 @@ private:
Watchdog();
~Watchdog();
/** Ticker invokes this handler when it timeouts - kicking watchdog periodically
*/
void timeout_handler();
bool _running;
Callback<void(uint32_t)> _callback;
us_timestamp_t _ticker_timeout;
#if DEVICE_LPTICKER
/** Create singleton instance of LowPowerTicker for watchdog periodic call back of kick.
*/
SingletonPtr<LowPowerTicker> _ticker;
#else
/** Create singleton instance of Ticker for watchdog periodic call back of kick.
*/
SingletonPtr<Ticker> _ticker;
#endif
};
} // namespace mbed