Merge pull request #150 from rbaron/zb-wdt
[zigbee sample] Fix rare infinite loop bug & introduce watchdog
This commit is contained in:
commit
8fb45f7165
6 changed files with 111 additions and 16 deletions
|
|
@ -32,11 +32,10 @@ int prst_shtc3_read(prst_shtc3_read_t *out) {
|
|||
|
||||
// Reading in normal (not low power) mode can take up to 12.1 ms, according to
|
||||
// the datasheet.
|
||||
k_msleep(15);
|
||||
k_msleep(20);
|
||||
|
||||
while (i2c_read_dt(&shtc3, buff, 6) != 0) {
|
||||
k_msleep(10);
|
||||
}
|
||||
// Read response.
|
||||
RET_IF_ERR(i2c_read_dt(&shtc3, buff, 6));
|
||||
|
||||
// Put the sensor in sleep mode.
|
||||
RET_IF_ERR(write_cmd(PRST_SHTC3_CMD_SLEEP));
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -132,14 +134,15 @@ void update_sensors_cb(zb_uint8_t arg) {
|
|||
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000 * CONFIG_PRST_ZB_SLEEP_DURATION_SEC));
|
||||
if (ret != RET_OK) {
|
||||
prst_debug_counters_increment("sens_cb_schedule_err");
|
||||
zb_reset(0);
|
||||
__ASSERT(false, "Unable to schedule sensor update callback");
|
||||
}
|
||||
|
||||
__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");
|
||||
LOG_ERR("Unable to read sensors");
|
||||
return;
|
||||
__ASSERT(false, "Unable to read sensors");
|
||||
}
|
||||
prst_debug_counters_increment("sensors_read_after");
|
||||
|
||||
|
|
@ -227,9 +230,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,
|
||||
/*param=*/0,
|
||||
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000));
|
||||
ZB_ERROR_CHECK(ZB_SCHEDULE_APP_ALARM(update_sensors_cb,
|
||||
/*param=*/0,
|
||||
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000)));
|
||||
__ASSERT_NO_MSG(!prst_watchdog_start());
|
||||
break;
|
||||
}
|
||||
case ZB_NLME_STATUS_INDICATION: {
|
||||
|
|
@ -255,10 +259,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 +301,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);
|
||||
|
|
|
|||
47
code/nrf-connect/samples/zigbee/src/watchdog.c
Normal file
47
code/nrf-connect/samples/zigbee/src/watchdog.c
Normal 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;
|
||||
}
|
||||
8
code/nrf-connect/samples/zigbee/src/watchdog.h
Normal file
8
code/nrf-connect/samples/zigbee/src/watchdog.h
Normal 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_
|
||||
Loading…
Add table
Reference in a new issue