Skip to content

HAL: Add a get_capabilities() function to ResetReason API #12139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 37 additions & 23 deletions TESTS/host_tests/reset_reason.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

DEFAULT_SYNC_DELAY = 4.0

MSG_VALUE_WATCHDOG_PRESENT = 'wdg_present'
MSG_VALUE_WATCHDOG_PRESENT = 1
MSG_VALUE_DUMMY = '0'
MSG_VALUE_RESET_REASON_GET = 'get'
MSG_VALUE_RESET_REASON_CLEAR = 'clear'
Expand Down Expand Up @@ -66,6 +66,7 @@ class ResetReasonTest(BaseHostTest):

def __init__(self):
super(ResetReasonTest, self).__init__()
self.device_reasons = None
self.device_has_watchdog = None
self.raw_reset_reasons = set()
self.sync_delay = DEFAULT_SYNC_DELAY
Expand All @@ -85,10 +86,13 @@ def setup(self):
def cb_device_ready(self, key, value, timestamp):
"""Request a raw value of the reset_reason register.

Additionally, save the device's watchdog status on the first call.
Additionally, save the device's reset_reason capabilities
and the watchdog status on the first call.
"""
if self.device_has_watchdog is None:
self.device_has_watchdog = (value == MSG_VALUE_WATCHDOG_PRESENT)
if self.device_reasons is None:
reasons, wdg_status = (int(i, base=16) for i in value.split(','))
self.device_has_watchdog = (wdg_status == MSG_VALUE_WATCHDOG_PRESENT)
self.device_reasons = [k for k, v in RESET_REASONS.items() if (reasons & 1 << int(v))]
self.send_kv(MSG_KEY_RESET_REASON_RAW, MSG_VALUE_RESET_REASON_GET)

def cb_reset_reason_raw(self, key, value, timestamp):
Expand Down Expand Up @@ -133,35 +137,45 @@ def test_steps(self):
__ignored_clear_ack = yield

# Request a NVIC_SystemReset() call.
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC)
__ignored_reset_ack = yield
time.sleep(self.sync_delay)
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
reset_reason = yield
raise_if_different(RESET_REASONS['SOFTWARE'], reset_reason, 'Wrong reset reason. ')
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
__ignored_clear_ack = yield
expected_reason = 'SOFTWARE'
if expected_reason not in self.device_reasons:
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
else:
# Request a NVIC_SystemReset() call.
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC)
__ignored_reset_ack = yield
time.sleep(self.sync_delay)
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
reset_reason = yield
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
__ignored_clear_ack = yield

# Reset the device using DAP.
self.reset()
__ignored_reset_ack = yield # 'reset_complete'
time.sleep(self.sync_delay)
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
reset_reason = yield
raise_if_different(RESET_REASONS['PIN_RESET'], reset_reason, 'Wrong reset reason. ')
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
__ignored_clear_ack = yield
expected_reason = 'PIN_RESET'
if expected_reason not in self.device_reasons:
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
else:
self.reset()
__ignored_reset_ack = yield # 'reset_complete'
time.sleep(self.sync_delay)
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
reset_reason = yield
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
__ignored_clear_ack = yield

# Start a watchdog timer and wait for it to reset the device.
if not self.device_has_watchdog:
self.log('DUT does not have a watchdog. Skipping this reset reason.')
expected_reason = 'WATCHDOG'
if expected_reason not in self.device_reasons or not self.device_has_watchdog:
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
else:
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_WATCHDOG)
__ignored_reset_ack = yield
time.sleep(self.sync_delay)
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
reset_reason = yield
raise_if_different(RESET_REASONS['WATCHDOG'], reset_reason, 'Wrong reset reason. ')
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')

# The sequence is correct -- test passed.
yield True
24 changes: 16 additions & 8 deletions TESTS/mbed_drivers/reset_reason/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
#include "mbed.h"

#if DEVICE_WATCHDOG
#include "hal/watchdog_api.h"

#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
#define WDG_TIMEOUT_MS 50UL

# include "hal/watchdog_api.h"
# define MSG_VALUE_WATCHDOG_STATUS 1
# define WDG_TIMEOUT_MS 50UL
#else
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
# define MSG_VALUE_WATCHDOG_STATUS 0
#endif

#define MSG_VALUE_DUMMY "0"
Expand Down Expand Up @@ -119,8 +117,18 @@ static cmd_status_t handle_command(const char *key, const char *value)

void test_reset_reason()
{
// Report readiness and watchdog status.
greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_WATCHDOG_STATUS);
reset_reason_capabilities_t rrcap = {};
hal_reset_reason_get_capabilities(&rrcap);
char msg_value[11];
int str_len = snprintf(msg_value, sizeof msg_value, "%08lx,%01x", rrcap.reasons, MSG_VALUE_WATCHDOG_STATUS);
if (str_len != (sizeof msg_value) - 1) {
printf("Failed to compose a value string to be sent to host.");
GREENTEA_TESTSUITE_RESULT(0);
return;
}

// Report readiness, capabilities and watchdog status.
greentea_send_kv(MSG_KEY_DEVICE_READY, msg_value);

cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
static char _key[MSG_KEY_LEN + 1] = { };
Expand Down
24 changes: 16 additions & 8 deletions TESTS/mbed_hal/reset_reason/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@
#include "mbed.h"

#if DEVICE_WATCHDOG
#include "hal/watchdog_api.h"

#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
#define WDG_TIMEOUT_MS 50UL

# include "hal/watchdog_api.h"
# define MSG_VALUE_WATCHDOG_STATUS 1
# define WDG_TIMEOUT_MS 50UL
#else
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
# define MSG_VALUE_WATCHDOG_STATUS 0
#endif

#define MSG_VALUE_DUMMY "0"
Expand Down Expand Up @@ -126,8 +124,18 @@ static cmd_status_t handle_command(const char *key, const char *value)

void test_reset_reason()
{
// Report readiness and watchdog status.
greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_WATCHDOG_STATUS);
reset_reason_capabilities_t rrcap = {};
hal_reset_reason_get_capabilities(&rrcap);
char msg_value[11];
int str_len = snprintf(msg_value, sizeof msg_value, "%08lx,%01x", rrcap.reasons, MSG_VALUE_WATCHDOG_STATUS);
if (str_len != (sizeof msg_value) - 1) {
printf("Failed to compose a value string to be sent to host.");
GREENTEA_TESTSUITE_RESULT(0);
return;
}

// Report readiness, capabilities and watchdog status.
greentea_send_kv(MSG_KEY_DEVICE_READY, msg_value);

cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
static char _key[MSG_KEY_LEN + 1] = { };
Expand Down
14 changes: 13 additions & 1 deletion hal/mbed_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "i2c_api.h"
#include "spi_api.h"
#include "gpio_api.h"
#include "reset_reason_api.h"
#include "mbed_toolchain.h"

// To be re-implemented in the target layer if required
Expand Down Expand Up @@ -90,4 +91,15 @@ MBED_WEAK void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t
}
}

#endif
#endif

#if DEVICE_RESET_REASON
// To be re-implemented in the target layer if required
MBED_WEAK void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = (1 << RESET_REASON_PIN_RESET) | (1 << RESET_REASON_SOFTWARE);
#if DEVICE_WATCHDOG
cap->reasons |= 1 << RESET_REASON_WATCHDOG;
#endif
}
#endif
12 changes: 12 additions & 0 deletions hal/reset_reason_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ extern "C" {
* some other part of the application may have cleared the value. Therefore,
* though there may have been a reset reason in the registers when the system
* started, the reason may not be available when the user comes to check it.
* * The function ::hal_reset_reason_get_capabilities fills the given
* `reset_reason_capabilities_t` instance.
*
* # Undefined behavior
* * There is no guarantee that the function ::hal_reset_reason_get will
Expand Down Expand Up @@ -88,6 +90,12 @@ typedef enum {
RESET_REASON_UNKNOWN /**< Unknown or unreadable reset reason **/
} reset_reason_t;

/** Reset reason capabilities of the platform
*/
typedef struct {
uint32_t reasons; /**< Supported reset reasons. Each bit represents a corresponding reset_reason_t value.**/
} reset_reason_capabilities_t;

/** Fetch the reset reason for the last system reset.
*
* This function must return the contents of the system reset reason registers
Expand Down Expand Up @@ -137,6 +145,10 @@ uint32_t hal_reset_reason_get_raw(void);
*/
void hal_reset_reason_clear(void);

/** Fill the given reset_reason_capabilities_t instance according to platform capabilities.
*/
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap);

/**@}*/

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,23 @@ void hal_reset_reason_clear(void)
#endif
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_POWER_ON;
cap->reasons |= 1 << RESET_REASON_BROWN_OUT;
cap->reasons |= 1 << RESET_REASON_WATCHDOG;
cap->reasons |= 1 << RESET_REASON_PIN_RESET;
cap->reasons |= 1 << RESET_REASON_SOFTWARE;

#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) || \
(defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) || \
(defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) || \
(defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) || \
(defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) || \
(defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT)
cap->reasons |= 1 << RESET_REASON_PLATFORM;
#endif
}

#endif // DEVICE_RESET_REASON
7 changes: 7 additions & 0 deletions targets/TARGET_TOSHIBA/TARGET_TMPM066/reset_reason_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ reset_reason_t hal_reset_reason_get(void)
return ret;
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_POWER_ON;
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
}

static bool bit_status(uint32_t reg, uint8_t bit_no)
{
bool status = false;
Expand Down
7 changes: 7 additions & 0 deletions targets/TARGET_TOSHIBA/TARGET_TMPM3H6/reset_reason_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ reset_reason_t hal_reset_reason_get(void)
return ret;
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_POWER_ON;
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
}

static bool bit_status(uint32_t reg, uint8_t bit_no)
{
bool status = false;
Expand Down
7 changes: 7 additions & 0 deletions targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/reset_reason_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ reset_reason_t hal_reset_reason_get(void)
return ret;
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_POWER_ON;
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
}

static bool bit_status(uint32_t reg, uint8_t bit_no)
{
bool status = false;
Expand Down
6 changes: 6 additions & 0 deletions targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ reset_reason_t hal_reset_reason_get(void)
return ret;
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
}

static uint8_t set_bit_count(uint32_t reg)
{
uint8_t count = 0;
Expand Down
7 changes: 7 additions & 0 deletions targets/TARGET_TOSHIBA/TARGET_TMPM4G9/reset_reason_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ reset_reason_t hal_reset_reason_get(void)
return ret;
}

void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
{
cap->reasons = 1 << RESET_REASON_UNKNOWN;
cap->reasons |= 1 << RESET_REASON_POWER_ON;
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
}

static bool bit_status(uint32_t reg, uint8_t bit_no)
{
bool status = false;
Expand Down