When my program starts, I set up a watchdog timer for 100 milliseconds and I start a repeated app timer that runs every 90 milliseconds to feed the watchdog. I use the app scheduler for other interrupt handling so that normal operation does not interfere with the watchdog feed timer. It seems that whenever I call fds_gc(), if there is garbage collection to be done, it causes the watchdog to trigger. Presumably something in the garbage collection is not allowing app timer interrupts to happen. Code to reproduce this issue is below. Thank you in advance for your help.
I am using SDK 15.3.0 and SoftDevice 6.1.1 on an nRF52840 chip.
FDS code:
static ret_code_t datastorage_set_record(uint16_t file_id, uint16_t record_key, uint32_t *value, uint32_t words) { ret_code_t err_code; fds_record_desc_t desc = {0}; fds_find_token_t tok = {0}; fds_record_t write_record = {0}; write_record.file_id = file_id; write_record.key = record_key; write_record.data.length_words = words; write_record.data.p_data = value; err_code = fds_record_find(file_id, record_key, &desc, &tok); if (err_code == FDS_SUCCESS) { err_code = fds_record_update(&desc, &write_record); } else if(err_code == FDS_ERR_NOT_FOUND) { err_code = fds_record_write(&desc, &write_record); } APP_ERROR_CHECK(err_code); return err_code; } static uint32_t count = 1; static void datastorage_sched_fds_handler(void *p_event_data, uint16_t event_size) { ret_code_t err_code; fds_evt_t const * p_evt = (fds_evt_t const *)p_event_data; APP_ERROR_CHECK(p_evt->result); switch(p_evt->id) { case FDS_EVT_INIT: datastorage_set_record(1, 1, &count, 1); break; case FDS_EVT_WRITE: case FDS_EVT_UPDATE: if(count < 10) { NRF_LOG_INFO("Updating..."); count++; datastorage_set_record(1, 1, &count, 1); } else { NRF_LOG_INFO("Garbage collecting..."); fds_gc(); } break; case FDS_EVT_GC: NRF_LOG_INFO("Garbage collection done"); break; } } static void datastorage_fds_handler(fds_evt_t const * p_evt) { app_sched_event_put(p_evt, sizeof(fds_evt_t), datastorage_sched_fds_handler); } void datastorage_init(void) { ret_code_t err_code; err_code = fds_register(datastorage_fds_handler); APP_ERROR_CHECK(err_code); err_code = fds_init(); APP_ERROR_CHECK(err_code); }
Watchdog code:
static void watchdog_handler(void) { //reboot occurs } static void watchdog_feed(void * p_context) { nrf_drv_wdt_channel_feed(watchdog_id); } static void watchdog_init(void) { ret_code_t err_code; const nrf_drv_wdt_config_t wdt_config = { .behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP, .reload_value = 100, //milliseconds .interrupt_priority = APP_IRQ_PRIORITY_HIGH, }; err_code = nrf_drv_wdt_init(&wdt_config, watchdog_handler); APP_ERROR_CHECK(err_code); err_code = nrf_drv_wdt_channel_alloc(&watchdog_id); APP_ERROR_CHECK(err_code); err_code = app_timer_create(&watchdog_feed_id, APP_TIMER_MODE_REPEATED, watchdog_feed); APP_ERROR_CHECK(err_code); nrf_drv_wdt_enable(); err_code = app_timer_start(watchdog_feed_id, APP_TIMER_TICKS(90), NULL); APP_ERROR_CHECK(err_code); }