mbed-os/TESTS/mbed_drivers/reset_reason/main.cpp

143 lines
5.0 KiB
C++

/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !DEVICE_RESET_REASON
#error [NOT_SUPPORTED] Reset reason API not supported for this target
#endif
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "drivers/ResetReason.h"
#include "ResetReason_tests.h"
#include "mbed.h"
#if DEVICE_WATCHDOG
#include "drivers/Watchdog.h"
#define MSG_VALUE_WATCHDOG_STATUS "wdg_present"
#define WDG_TIMEOUT_MS 50UL
#define WDG_TIMEOUT_DELTA_MS 50UL
#else
#define MSG_VALUE_WATCHDOG_STATUS "no_wdg"
#endif
#define MSG_VALUE_DUMMY "0"
#define MSG_VALUE_RESET_REASON_GET "get"
#define MSG_VALUE_RESET_REASON_CLEAR "clear"
#define MSG_VALUE_RESET_REASON_CLEAR_ACK "cleared"
#define MSG_VALUE_DEVICE_RESET_ACK "ack"
#define MSG_VALUE_DEVICE_RESET_NVIC "nvic"
#define MSG_VALUE_DEVICE_RESET_WATCHDOG "watchdog"
#define MSG_VALUE_LEN 16
#define MSG_KEY_LEN 16
#define MSG_KEY_DEVICE_READY "ready"
#define MSG_KEY_RESET_REASON_RAW "reason_raw"
#define MSG_KEY_RESET_REASON "reason"
#define MSG_KEY_DEVICE_RESET "reset"
typedef enum {
CMD_STATUS_CONTINUE,
CMD_STATUS_ERROR
} cmd_status_t;
static cmd_status_t handle_command(const char *key, const char *value)
{
if (strcmp(key, MSG_KEY_RESET_REASON_RAW) == 0) {
uint32_t raw_reason = ResetReason::get_raw();
char raw_reason_hex_str[9] = { };
int raw_reason_hex_str_len = snprintf(raw_reason_hex_str,
sizeof raw_reason_hex_str, "%08lx", raw_reason);
if (raw_reason_hex_str_len != (sizeof raw_reason_hex_str) - 1) {
TEST_ASSERT_MESSAGE(0, "Failed to compose raw reset reason hex string.");
return CMD_STATUS_ERROR;
}
greentea_send_kv(MSG_KEY_RESET_REASON_RAW, raw_reason_hex_str);
return CMD_STATUS_CONTINUE;
}
if (strcmp(key, MSG_KEY_RESET_REASON) == 0 && strcmp(value, MSG_VALUE_RESET_REASON_GET) == 0) {
int reason = (int) ResetReason::get();
greentea_send_kv(MSG_KEY_RESET_REASON, reason);
return CMD_STATUS_CONTINUE;
}
if (strcmp(key, MSG_KEY_RESET_REASON) == 0 && strcmp(value, MSG_VALUE_RESET_REASON_CLEAR) == 0) {
/* In order to keep this code compatible with a host script common for
* both HAL API tests and driver API tests, ignore the 'clear' command
* received from host.
*
* The driver API does not provide clear() function directly.
*/
greentea_send_kv(MSG_KEY_RESET_REASON, MSG_VALUE_RESET_REASON_CLEAR_ACK);
return CMD_STATUS_CONTINUE;
}
if (strcmp(key, MSG_KEY_DEVICE_RESET) == 0 && strcmp(value, MSG_VALUE_DEVICE_RESET_NVIC) == 0) {
greentea_send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_ACK);
wait_ms(10); // Wait for the serial buffers to flush.
NVIC_SystemReset();
TEST_ASSERT_MESSAGE(0, "NVIC_SystemReset did not reset the device as expected.");
return CMD_STATUS_ERROR;
}
#if DEVICE_WATCHDOG
if (strcmp(key, MSG_KEY_DEVICE_RESET) == 0 && strcmp(value, MSG_VALUE_DEVICE_RESET_WATCHDOG) == 0) {
greentea_send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DEVICE_RESET_ACK);
wait_ms(10); // Wait for the serial buffers to flush.
Watchdog watchdog;
if (watchdog.start(WDG_TIMEOUT_MS) != WATCHDOG_STATUS_OK) {
TEST_ASSERT_MESSAGE(0, "watchdog.start() error.");
return CMD_STATUS_ERROR;
}
wait_ms(WDG_TIMEOUT_MS + WDG_TIMEOUT_DELTA_MS);
TEST_ASSERT_MESSAGE(0, "Watchdog did not reset the device as expected.");
return CMD_STATUS_ERROR;
}
#endif
TEST_ASSERT_MESSAGE(0, "Invalid message key.");
return CMD_STATUS_ERROR;
}
void test_reset_reason()
{
// Report readiness and watchdog status.
greentea_send_kv(MSG_KEY_DEVICE_READY, MSG_VALUE_WATCHDOG_STATUS);
cmd_status_t cmd_status = CMD_STATUS_CONTINUE;
static char _key[MSG_KEY_LEN + 1] = { };
static char _value[MSG_VALUE_LEN + 1] = { };
// Let the host side decide what to do and just handle the commands.
while (CMD_STATUS_CONTINUE == cmd_status) {
memset(_key, 0, sizeof _key);
memset(_value, 0, sizeof _value);
greentea_parse_kv(_key, _value, MSG_KEY_LEN, MSG_VALUE_LEN);
cmd_status = handle_command(_key, _value);
}
}
int main()
{
GREENTEA_SETUP(60, "reset_reason");
test_reset_reason(); // The result of this test suite is reported by the host side.
GREENTEA_TESTSUITE_RESULT(0); // Fail on any error.
}