Skip to content

Commit 31988d8

Browse files
authored
Merge pull request #12139 from fkjagodzinski/hal-reset_reason-get_capabilities
HAL: Add a get_capabilities() function to ResetReason API
2 parents cbaa9bd + a958199 commit 31988d8

File tree

11 files changed

+147
-40
lines changed

11 files changed

+147
-40
lines changed

TESTS/host_tests/reset_reason.py

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
DEFAULT_SYNC_DELAY = 4.0
2121

22-
MSG_VALUE_WATCHDOG_PRESENT = 'wdg_present'
22+
MSG_VALUE_WATCHDOG_PRESENT = 1
2323
MSG_VALUE_DUMMY = '0'
2424
MSG_VALUE_RESET_REASON_GET = 'get'
2525
MSG_VALUE_RESET_REASON_CLEAR = 'clear'
@@ -66,6 +66,7 @@ class ResetReasonTest(BaseHostTest):
6666

6767
def __init__(self):
6868
super(ResetReasonTest, self).__init__()
69+
self.device_reasons = None
6970
self.device_has_watchdog = None
7071
self.raw_reset_reasons = set()
7172
self.sync_delay = DEFAULT_SYNC_DELAY
@@ -85,10 +86,13 @@ def setup(self):
8586
def cb_device_ready(self, key, value, timestamp):
8687
"""Request a raw value of the reset_reason register.
8788
88-
Additionally, save the device's watchdog status on the first call.
89+
Additionally, save the device's reset_reason capabilities
90+
and the watchdog status on the first call.
8991
"""
90-
if self.device_has_watchdog is None:
91-
self.device_has_watchdog = (value == MSG_VALUE_WATCHDOG_PRESENT)
92+
if self.device_reasons is None:
93+
reasons, wdg_status = (int(i, base=16) for i in value.split(','))
94+
self.device_has_watchdog = (wdg_status == MSG_VALUE_WATCHDOG_PRESENT)
95+
self.device_reasons = [k for k, v in RESET_REASONS.items() if (reasons & 1 << int(v))]
9296
self.send_kv(MSG_KEY_RESET_REASON_RAW, MSG_VALUE_RESET_REASON_GET)
9397

9498
def cb_reset_reason_raw(self, key, value, timestamp):
@@ -133,35 +137,45 @@ def test_steps(self):
133137
__ignored_clear_ack = yield
134138

135139
# Request a NVIC_SystemReset() call.
136-
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC)
137-
__ignored_reset_ack = yield
138-
time.sleep(self.sync_delay)
139-
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
140-
reset_reason = yield
141-
raise_if_different(RESET_REASONS['SOFTWARE'], reset_reason, 'Wrong reset reason. ')
142-
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
143-
__ignored_clear_ack = yield
140+
expected_reason = 'SOFTWARE'
141+
if expected_reason not in self.device_reasons:
142+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
143+
else:
144+
# Request a NVIC_SystemReset() call.
145+
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_NVIC)
146+
__ignored_reset_ack = yield
147+
time.sleep(self.sync_delay)
148+
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
149+
reset_reason = yield
150+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
151+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
152+
__ignored_clear_ack = yield
144153

145154
# Reset the device using DAP.
146-
self.reset()
147-
__ignored_reset_ack = yield # 'reset_complete'
148-
time.sleep(self.sync_delay)
149-
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
150-
reset_reason = yield
151-
raise_if_different(RESET_REASONS['PIN_RESET'], reset_reason, 'Wrong reset reason. ')
152-
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
153-
__ignored_clear_ack = yield
155+
expected_reason = 'PIN_RESET'
156+
if expected_reason not in self.device_reasons:
157+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
158+
else:
159+
self.reset()
160+
__ignored_reset_ack = yield # 'reset_complete'
161+
time.sleep(self.sync_delay)
162+
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
163+
reset_reason = yield
164+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
165+
self.send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR)
166+
__ignored_clear_ack = yield
154167

155168
# Start a watchdog timer and wait for it to reset the device.
156-
if not self.device_has_watchdog:
157-
self.log('DUT does not have a watchdog. Skipping this reset reason.')
169+
expected_reason = 'WATCHDOG'
170+
if expected_reason not in self.device_reasons or not self.device_has_watchdog:
171+
self.log('Skipping the {} reset reason -- not supported.'.format(expected_reason))
158172
else:
159173
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_WATCHDOG)
160174
__ignored_reset_ack = yield
161175
time.sleep(self.sync_delay)
162176
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
163177
reset_reason = yield
164-
raise_if_different(RESET_REASONS['WATCHDOG'], reset_reason, 'Wrong reset reason. ')
178+
raise_if_different(RESET_REASONS[expected_reason], reset_reason, 'Wrong reset reason. ')
165179

166180
# The sequence is correct -- test passed.
167181
yield True

TESTS/mbed_drivers/reset_reason/main.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@
2525
#include "mbed.h"
2626

2727
#if DEVICE_WATCHDOG
28-
#include "hal/watchdog_api.h"
29-
30-
#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
31-
#define WDG_TIMEOUT_MS 50UL
32-
28+
# include "hal/watchdog_api.h"
29+
# define MSG_VALUE_WATCHDOG_STATUS 1
30+
# define WDG_TIMEOUT_MS 50UL
3331
#else
34-
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
32+
# define MSG_VALUE_WATCHDOG_STATUS 0
3533
#endif
3634

3735
#define MSG_VALUE_DUMMY "0"
@@ -132,8 +130,18 @@ static cmd_status_t handle_command(const char *key, const char *value)
132130

133131
void test_reset_reason()
134132
{
135-
// Report readiness and watchdog status.
136-
greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_WATCHDOG_STATUS);
133+
reset_reason_capabilities_t rrcap = {};
134+
hal_reset_reason_get_capabilities(&rrcap);
135+
char msg_value[11];
136+
int str_len = snprintf(msg_value, sizeof msg_value, "%08lx,%01x", rrcap.reasons, MSG_VALUE_WATCHDOG_STATUS);
137+
if (str_len != (sizeof msg_value) - 1) {
138+
printf("Failed to compose a value string to be sent to host.");
139+
GREENTEA_TESTSUITE_RESULT(0);
140+
return;
141+
}
142+
143+
// Report readiness, capabilities and watchdog status.
144+
greentea_send_kv(MSG_KEY_DEVICE_READY, msg_value);
137145

138146
cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
139147
static char _key[MSG_KEY_LEN + 1] = { };

TESTS/mbed_hal/reset_reason/main.cpp

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@
2525
#include "mbed.h"
2626

2727
#if DEVICE_WATCHDOG
28-
#include "hal/watchdog_api.h"
29-
30-
#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
31-
#define WDG_TIMEOUT_MS 50UL
32-
28+
# include "hal/watchdog_api.h"
29+
# define MSG_VALUE_WATCHDOG_STATUS 1
30+
# define WDG_TIMEOUT_MS 50UL
3331
#else
34-
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
32+
# define MSG_VALUE_WATCHDOG_STATUS 0
3533
#endif
3634

3735
#define MSG_VALUE_DUMMY "0"
@@ -127,8 +125,18 @@ static cmd_status_t handle_command(const char *key, const char *value)
127125

128126
void test_reset_reason()
129127
{
130-
// Report readiness and watchdog status.
131-
greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_WATCHDOG_STATUS);
128+
reset_reason_capabilities_t rrcap = {};
129+
hal_reset_reason_get_capabilities(&rrcap);
130+
char msg_value[11];
131+
int str_len = snprintf(msg_value, sizeof msg_value, "%08lx,%01x", rrcap.reasons, MSG_VALUE_WATCHDOG_STATUS);
132+
if (str_len != (sizeof msg_value) - 1) {
133+
printf("Failed to compose a value string to be sent to host.");
134+
GREENTEA_TESTSUITE_RESULT(0);
135+
return;
136+
}
137+
138+
// Report readiness, capabilities and watchdog status.
139+
greentea_send_kv(MSG_KEY_DEVICE_READY, msg_value);
132140

133141
cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
134142
static char _key[MSG_KEY_LEN + 1] = { };

hal/mbed_compat.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "i2c_api.h"
2020
#include "spi_api.h"
2121
#include "gpio_api.h"
22+
#include "reset_reason_api.h"
2223
#include "mbed_toolchain.h"
2324

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

93-
#endif
94+
#endif
95+
96+
#if DEVICE_RESET_REASON
97+
// To be re-implemented in the target layer if required
98+
MBED_WEAK void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
99+
{
100+
cap->reasons = (1 << RESET_REASON_PIN_RESET) | (1 << RESET_REASON_SOFTWARE);
101+
#if DEVICE_WATCHDOG
102+
cap->reasons |= 1 << RESET_REASON_WATCHDOG;
103+
#endif
104+
}
105+
#endif

hal/reset_reason_api.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ extern "C" {
4141
* some other part of the application may have cleared the value. Therefore,
4242
* though there may have been a reset reason in the registers when the system
4343
* started, the reason may not be available when the user comes to check it.
44+
* * The function ::hal_reset_reason_get_capabilities fills the given
45+
* `reset_reason_capabilities_t` instance.
4446
*
4547
* # Undefined behavior
4648
* * There is no guarantee that the function ::hal_reset_reason_get will
@@ -88,6 +90,12 @@ typedef enum {
8890
RESET_REASON_UNKNOWN /**< Unknown or unreadable reset reason **/
8991
} reset_reason_t;
9092

93+
/** Reset reason capabilities of the platform
94+
*/
95+
typedef struct {
96+
uint32_t reasons; /**< Supported reset reasons. Each bit represents a corresponding reset_reason_t value.**/
97+
} reset_reason_capabilities_t;
98+
9199
/** Fetch the reset reason for the last system reset.
92100
*
93101
* This function must return the contents of the system reset reason registers
@@ -137,6 +145,10 @@ uint32_t hal_reset_reason_get_raw(void);
137145
*/
138146
void hal_reset_reason_clear(void);
139147

148+
/** Fill the given reset_reason_capabilities_t instance according to platform capabilities.
149+
*/
150+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap);
151+
140152
/**@}*/
141153

142154
#ifdef __cplusplus

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/reset_reason.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,23 @@ void hal_reset_reason_clear(void)
105105
#endif
106106
}
107107

108+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
109+
{
110+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
111+
cap->reasons |= 1 << RESET_REASON_POWER_ON;
112+
cap->reasons |= 1 << RESET_REASON_BROWN_OUT;
113+
cap->reasons |= 1 << RESET_REASON_WATCHDOG;
114+
cap->reasons |= 1 << RESET_REASON_PIN_RESET;
115+
cap->reasons |= 1 << RESET_REASON_SOFTWARE;
116+
117+
#if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) || \
118+
(defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) || \
119+
(defined(FSL_FEATURE_RCM_HAS_LOL) && FSL_FEATURE_RCM_HAS_LOL) || \
120+
(defined(FSL_FEATURE_RCM_HAS_JTAG) && FSL_FEATURE_RCM_HAS_JTAG) || \
121+
(defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) || \
122+
(defined(FSL_FEATURE_RCM_HAS_EZPORT) && FSL_FEATURE_RCM_HAS_EZPORT)
123+
cap->reasons |= 1 << RESET_REASON_PLATFORM;
124+
#endif
125+
}
126+
108127
#endif // DEVICE_RESET_REASON

targets/TARGET_TOSHIBA/TARGET_TMPM066/reset_reason_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ reset_reason_t hal_reset_reason_get(void)
8686
return ret;
8787
}
8888

89+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
90+
{
91+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
92+
cap->reasons |= 1 << RESET_REASON_POWER_ON;
93+
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
94+
}
95+
8996
static bool bit_status(uint32_t reg, uint8_t bit_no)
9097
{
9198
bool status = false;

targets/TARGET_TOSHIBA/TARGET_TMPM3H6/reset_reason_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ reset_reason_t hal_reset_reason_get(void)
8383
return ret;
8484
}
8585

86+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
87+
{
88+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
89+
cap->reasons |= 1 << RESET_REASON_POWER_ON;
90+
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
91+
}
92+
8693
static bool bit_status(uint32_t reg, uint8_t bit_no)
8794
{
8895
bool status = false;

targets/TARGET_TOSHIBA/TARGET_TMPM3HQ/reset_reason_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ reset_reason_t hal_reset_reason_get(void)
8383
return ret;
8484
}
8585

86+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
87+
{
88+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
89+
cap->reasons |= 1 << RESET_REASON_POWER_ON;
90+
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
91+
}
92+
8693
static bool bit_status(uint32_t reg, uint8_t bit_no)
8794
{
8895
bool status = false;

targets/TARGET_TOSHIBA/TARGET_TMPM46B/reset_reason_api.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ reset_reason_t hal_reset_reason_get(void)
6666
return ret;
6767
}
6868

69+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
70+
{
71+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
72+
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
73+
}
74+
6975
static uint8_t set_bit_count(uint32_t reg)
7076
{
7177
uint8_t count = 0;

targets/TARGET_TOSHIBA/TARGET_TMPM4G9/reset_reason_api.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ reset_reason_t hal_reset_reason_get(void)
8888
return ret;
8989
}
9090

91+
void hal_reset_reason_get_capabilities(reset_reason_capabilities_t *cap)
92+
{
93+
cap->reasons = 1 << RESET_REASON_UNKNOWN;
94+
cap->reasons |= 1 << RESET_REASON_POWER_ON;
95+
cap->reasons |= 1 << RESET_REASON_MULTIPLE;
96+
}
97+
9198
static bool bit_status(uint32_t reg, uint8_t bit_no)
9299
{
93100
bool status = false;

0 commit comments

Comments
 (0)