[zigbee sample] Introduce watchdog for sensor task

This commit is contained in:
rbaron 2023-07-13 19:34:18 +02:00
parent 95ec660cb6
commit c70eb600a3
5 changed files with 106 additions and 9 deletions

View file

@ -19,6 +19,7 @@ target_sources(app PRIVATE
src/prst_zb_attrs.c
src/prst_zb_soil_moisture_defs.c
src/restart_handler.c
src/watchdog.c
)
add_subdirectory(../../prstlib prstlib)

View file

@ -60,6 +60,10 @@ CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FILE_SYSTEM=y
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_WATCHDOG=y
CONFIG_HWINFO=y
CONFIG_ASSERT=y
# Uncomment for debug log level.
# CONFIG_LOG_DEFAULT_LEVEL=4

View file

@ -10,6 +10,7 @@
#include <zboss_api.h>
#include <zboss_api_addons.h>
#include <zcl/zb_zcl_power_config.h>
#include <zephyr/drivers/hwinfo.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zigbee/zigbee_app_utils.h>
@ -22,6 +23,7 @@
#include "prst_zb_endpoint_defs.h"
#include "prst_zb_soil_moisture_defs.h"
#include "restart_handler.h"
#include "watchdog.h"
LOG_MODULE_REGISTER(app, CONFIG_LOG_DEFAULT_LEVEL);
@ -135,6 +137,8 @@ void update_sensors_cb(zb_uint8_t arg) {
zb_reset(0);
}
__ASSERT(!prst_watchdog_feed(), "Failed to feed watchdog");
prst_debug_counters_increment("sensors_read_before");
if (prst_sensors_read_all(&sensors)) {
prst_debug_counters_increment("sensors_read_error");
@ -227,9 +231,10 @@ void zboss_signal_handler(zb_bufid_t bufid) {
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
// Kick off main sensor update task.
ZB_SCHEDULE_APP_ALARM(update_sensors_cb,
ZB_ERROR_CHECK(ZB_SCHEDULE_APP_ALARM(update_sensors_cb,
/*param=*/0,
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000));
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000)));
__ASSERT_NO_MSG(!prst_watchdog_start());
break;
}
case ZB_NLME_STATUS_INDICATION: {
@ -255,10 +260,40 @@ void zboss_signal_handler(zb_bufid_t bufid) {
}
}
void log_counter(const char *counter_name, prst_debug_counter_t value) {
void dump_counter(const char *counter_name, prst_debug_counter_t value) {
LOG_INF("- %s: %d", counter_name, value);
}
int log_reset_reason_counter() {
uint32_t cause;
const char *reset_counter_str = "reset_cause_unknown";
RET_IF_ERR(hwinfo_get_reset_cause(&cause));
RET_IF_ERR(hwinfo_clear_reset_cause());
if (cause & RESET_PIN) {
reset_counter_str = "reset_cause_pin";
} else if (cause & RESET_SOFTWARE) {
// Includes fatal errors from __ASSERT, ZB_ERROR_CHECK and friends.
reset_counter_str = "reset_cause_software";
} else if (cause & RESET_BROWNOUT) {
reset_counter_str = "reset_cause_brownout";
} else if (cause & RESET_POR) {
reset_counter_str = "reset_cause_power_on";
} else if (cause & RESET_WATCHDOG) {
reset_counter_str = "reset_cause_watchdog";
} else if (cause & RESET_DEBUG) {
reset_counter_str = "reset_cause_debug";
} else if (cause & RESET_LOW_POWER_WAKE) {
reset_counter_str = "reset_cause_low_power";
} else if (cause & RESET_CPU_LOCKUP) {
reset_counter_str = "reset_cause_cpu_lockup";
} else if (cause & RESET_HARDWARE) {
reset_counter_str = "reset_cause_hardware";
} else if (cause & RESET_USER) {
reset_counter_str = "reset_cause_user";
}
return prst_debug_counters_increment(reset_counter_str);
}
int main(void) {
RET_IF_ERR(prst_adc_init());
RET_IF_ERR(prst_led_init());
@ -267,20 +302,22 @@ int main(void) {
RET_IF_ERR(prst_debug_counters_init());
// Initialize sensors - quickly put them into low power mode.
RET_IF_ERR(prst_sensors_read_all(&sensors));
__ASSERT_NO_MSG(!prst_sensors_read_all(&sensors));
prst_debug_counters_increment("boot");
LOG_INF("Dumping debug counters:");
prst_debug_counters_get_all(log_counter);
log_reset_reason_counter();
RET_IF_ERR(prst_zb_factory_reset_check());
LOG_INF("Dumping debug counters:");
prst_debug_counters_get_all(dump_counter);
__ASSERT_NO_MSG(!prst_zb_factory_reset_check());
prst_zb_attrs_init(&dev_ctx);
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
RET_IF_ERR(prst_led_flash(2));
prst_led_flash(2);
k_msleep(100);
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(PRST_ZIGBEE_ENDPOINT, identify_cb);

View file

@ -0,0 +1,47 @@
#include "watchdog.h"
#include <prstlib/macros.h>
#include <zephyr/device.h>
#include <zephyr/drivers/watchdog.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#define PRST_ZB_WATCHDOG_TIMEOUT_SEC (2 * CONFIG_PRST_ZB_SLEEP_DURATION_SEC)
LOG_MODULE_REGISTER(watchdog, CONFIG_LOG_DEFAULT_LEVEL);
typedef struct {
const struct device *const wdt;
int wtd_channel_id;
} wtd_data_t;
static wtd_data_t wtd_data = {
.wdt = DEVICE_DT_GET(DT_NODELABEL(wdt)),
};
int prst_watchdog_start() {
static const struct wdt_timeout_cfg wdt_settings = {
.window = {
.min = 0,
.max = PRST_ZB_WATCHDOG_TIMEOUT_SEC * MSEC_PER_SEC,
},
// NULL callback means use the default, which is the system reset.
.callback = NULL,
.flags = WDT_FLAG_RESET_SOC};
RET_IF_ERR(!device_is_ready(wtd_data.wdt));
// Install timeout.
wtd_data.wtd_channel_id = wdt_install_timeout(wtd_data.wdt, &wdt_settings);
RET_CHECK(wtd_data.wtd_channel_id >= 0, "Failed to install watchdog timeout.");
// Start watchdog.
RET_IF_ERR(wdt_setup(wtd_data.wdt, WDT_OPT_PAUSE_HALTED_BY_DBG));
return 0;
}
int prst_watchdog_feed() {
RET_IF_ERR(wdt_feed(wtd_data.wdt, wtd_data.wtd_channel_id));
return 0;
}

View file

@ -0,0 +1,8 @@
#ifndef _PRST_ZB_WATCHDOG_H_
#define _PRST_ZB_WATCHDOG_H_
int prst_watchdog_start();
int prst_watchdog_feed();
#endif // _PRST_ZB_WATCHDOG_H_