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
|
// Reading in normal (not low power) mode can take up to 12.1 ms, according to
|
||||||
// the datasheet.
|
// the datasheet.
|
||||||
k_msleep(15);
|
k_msleep(20);
|
||||||
|
|
||||||
while (i2c_read_dt(&shtc3, buff, 6) != 0) {
|
// Read response.
|
||||||
k_msleep(10);
|
RET_IF_ERR(i2c_read_dt(&shtc3, buff, 6));
|
||||||
}
|
|
||||||
|
|
||||||
// Put the sensor in sleep mode.
|
// Put the sensor in sleep mode.
|
||||||
RET_IF_ERR(write_cmd(PRST_SHTC3_CMD_SLEEP));
|
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_attrs.c
|
||||||
src/prst_zb_soil_moisture_defs.c
|
src/prst_zb_soil_moisture_defs.c
|
||||||
src/restart_handler.c
|
src/restart_handler.c
|
||||||
|
src/watchdog.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(../../prstlib prstlib)
|
add_subdirectory(../../prstlib prstlib)
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,10 @@ CONFIG_FLASH_PAGE_LAYOUT=y
|
||||||
CONFIG_FILE_SYSTEM=y
|
CONFIG_FILE_SYSTEM=y
|
||||||
CONFIG_FILE_SYSTEM_LITTLEFS=y
|
CONFIG_FILE_SYSTEM_LITTLEFS=y
|
||||||
|
|
||||||
|
CONFIG_WATCHDOG=y
|
||||||
|
CONFIG_HWINFO=y
|
||||||
|
CONFIG_ASSERT=y
|
||||||
|
|
||||||
# Uncomment for debug log level.
|
# Uncomment for debug log level.
|
||||||
# CONFIG_LOG_DEFAULT_LEVEL=4
|
# CONFIG_LOG_DEFAULT_LEVEL=4
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <zboss_api.h>
|
#include <zboss_api.h>
|
||||||
#include <zboss_api_addons.h>
|
#include <zboss_api_addons.h>
|
||||||
#include <zcl/zb_zcl_power_config.h>
|
#include <zcl/zb_zcl_power_config.h>
|
||||||
|
#include <zephyr/drivers/hwinfo.h>
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/logging/log.h>
|
#include <zephyr/logging/log.h>
|
||||||
#include <zigbee/zigbee_app_utils.h>
|
#include <zigbee/zigbee_app_utils.h>
|
||||||
|
|
@ -22,6 +23,7 @@
|
||||||
#include "prst_zb_endpoint_defs.h"
|
#include "prst_zb_endpoint_defs.h"
|
||||||
#include "prst_zb_soil_moisture_defs.h"
|
#include "prst_zb_soil_moisture_defs.h"
|
||||||
#include "restart_handler.h"
|
#include "restart_handler.h"
|
||||||
|
#include "watchdog.h"
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(app, CONFIG_LOG_DEFAULT_LEVEL);
|
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));
|
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000 * CONFIG_PRST_ZB_SLEEP_DURATION_SEC));
|
||||||
if (ret != RET_OK) {
|
if (ret != RET_OK) {
|
||||||
prst_debug_counters_increment("sens_cb_schedule_err");
|
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");
|
prst_debug_counters_increment("sensors_read_before");
|
||||||
if (prst_sensors_read_all(&sensors)) {
|
if (prst_sensors_read_all(&sensors)) {
|
||||||
prst_debug_counters_increment("sensors_read_error");
|
prst_debug_counters_increment("sensors_read_error");
|
||||||
LOG_ERR("Unable to read sensors");
|
__ASSERT(false, "Unable to read sensors");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
prst_debug_counters_increment("sensors_read_after");
|
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));
|
k_timer_start(&led_flashing_timer, K_NO_WAIT, K_SECONDS(1));
|
||||||
|
|
||||||
// Kick off main sensor update task.
|
// 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,
|
/*param=*/0,
|
||||||
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000));
|
ZB_MILLISECONDS_TO_BEACON_INTERVAL(1000)));
|
||||||
|
__ASSERT_NO_MSG(!prst_watchdog_start());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ZB_NLME_STATUS_INDICATION: {
|
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);
|
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) {
|
int main(void) {
|
||||||
RET_IF_ERR(prst_adc_init());
|
RET_IF_ERR(prst_adc_init());
|
||||||
RET_IF_ERR(prst_led_init());
|
RET_IF_ERR(prst_led_init());
|
||||||
|
|
@ -267,20 +301,22 @@ int main(void) {
|
||||||
RET_IF_ERR(prst_debug_counters_init());
|
RET_IF_ERR(prst_debug_counters_init());
|
||||||
|
|
||||||
// Initialize sensors - quickly put them into low power mode.
|
// 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");
|
prst_debug_counters_increment("boot");
|
||||||
|
|
||||||
LOG_INF("Dumping debug counters:");
|
log_reset_reason_counter();
|
||||||
prst_debug_counters_get_all(log_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);
|
prst_zb_attrs_init(&dev_ctx);
|
||||||
|
|
||||||
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
|
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
|
||||||
|
|
||||||
RET_IF_ERR(prst_led_flash(2));
|
prst_led_flash(2);
|
||||||
k_msleep(100);
|
k_msleep(100);
|
||||||
|
|
||||||
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(PRST_ZIGBEE_ENDPOINT, identify_cb);
|
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