Watchdog in BLE NUS example sdk 2.4.0

Hello everyone,

I am developing a ble project that builds on the peripheral Uart example using the sdk 2.4.0 for nrf5340.

I want to implement a watchdog since I sometimes run into corners where the code does not otherwise recover itself. I found the watchdog driver example and have successfully set up the watchdog in the peripheral Uart example, however, I do not understand where in the code I should feed the watchdog using wdt_feed(wdt, wdt_channel_id); since the main seems to run only once to set up the ble advertising. 
So, where should I feed the watchdog in case there is a) a connection and b) no connection?

Thanks in advance!

Paul

  • More specifically, this is my main:

    void main(void)
    {
    	int err = 0;
    	// weight_arr = calculate_weighted_arr(weight_arr);
    
    	
    	// int wdt_channel_id;
    	// const struct device *const wdt = DEVICE_DT_GET(DT_ALIAS(watchdog0));
    
    	
    
    	if (!device_is_ready(wdt)) {
    		
    		return 0;
    	}
    
    	struct wdt_timeout_cfg wdt_config = {
    		/* Reset SoC when watchdog timer expires. */
    		.flags = WDT_FLAG_RESET_SOC,
    
    		/* Expire watchdog after max window */
    		.window.min = WDT_MIN_WINDOW,
    		.window.max = WDT_MAX_WINDOW,
    	};
    
    	wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
    	if (wdt_channel_id == -ENOTSUP) {
    		/* IWDG driver for STM32 doesn't support callback */
    		//printk("Callback support rejected, continuing anyway\n");
    		wdt_config.callback = NULL;
    		wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
    	}
    	if (wdt_channel_id < 0) {
    		//printk("Watchdog install error\n");
    		return 0;
    	}
    
    	err = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
    	if (err < 0) {
    		//printk("Watchdog setup error\n");
    		return 0;
    	}
    
    	uint32_t led2_pin = NRF_GPIO_PIN_MAP(1, 1);
    	uint32_t enable_pin = NRF_GPIO_PIN_MAP(0, 16);
    
    	uint8_t spec_hello_check[] = {0x03, 0xBB, CMD_HELLO, 0x00, 0x41};
    	uint8_t *spec_hello_return;
    
    	pin_configure(button);
    	// calculate_weighted_arr(weight_arr);
    	// because of DFU/OTA configs one time SPI communication
    	nrf_gpio_pin_set(enable_pin);
    	spec_hello_return = cmd_hello(spispec);
    	for(int i = 0; i < 5; i++){
    		if(spec_hello_check[i] == spec_hello_return[i]){
    			nrf_gpio_pin_clear(enable_pin);
    		}
    	}
    	nrf_gpio_pin_clear(enable_pin);
    
    	nrf_gpio_cfg_output(led2_pin);
    	
    	nrf_gpio_pin_set(led2_pin);
    	k_msleep(500);
    	nrf_gpio_pin_clear(led2_pin);
    	k_msleep(500);
    
    	// for (int i = 0; i < sizeof(m_camera1_framebuffer); i++)
    	// {
    	// 	m_camera1_framebuffer[i] = 10;
    	// }
    
    	// camera initialisation
    	k_sem_init(&m_camera_1_sem, 0, 1);
    
    	//Configure camera
    	// LOG_INF("Configure camera 1");
    	err = camera_osirism_init(&m_camera_1, &m_camera_1_config);
    	if(err != 0) {
    		// LOG_ERR("Failed to setup camera 1: %d", result);
    		return;
    	}
    	
    	gpio_pin_configure_dt(&interrupt1, GPIO_INPUT);
    	ISM330DLC_powerdown(i2c_dev);
    	// gpio_pin_interrupt_configure_dt(&interrupt1, GPIO_INT_EDGE_TO_ACTIVE);
    	// gpio_init_callback(&interrupt1_cb, interrupt1_handler, BIT(interrupt1.pin));
    	// gpio_add_callback(interrupt1.port, &interrupt1_cb);
    
    
    	bt_conn_cb_register(&conn_callbacks);
    	err = bt_enable(NULL);
    	if (err) {
     		printk("Failed to initialize UEnable BT (err: %d)\n", err);
    		return;
    	}
    	
    	err = bt_nus_init(&nus_cb);
    	printk("BLE initialized\n");
    	if (err) {
     		printk("Failed to initialize UART service (err: %d)\n", err);
    		return;
    	}
     
    	err = bt_le_adv_start(BT_LE_ADV_CONN_SLOW, ad, ARRAY_SIZE(ad), sd,
    			      ARRAY_SIZE(sd));
    
    	
    
    	if (err) {
    		printk("Advertising failed to start (err %d)\n", err);
    	}
    	
    	printk("Starting BLE NUS\n");
    
    	while (true)
    	{	
    		wdt_feed(wdt, wdt_channel_id);
    		k_msleep(3000);
    	}
    }

    I added the while loop at the end for the watchdog but otherwise would not have it. I dont know if that is the best way to do it however.

  • Hello,

    I don't have any good pointers here than you need to ensure to feed the watchdog (one way or the other) faster than the watchdog timeout. I think your proposol to put it in the inifinite while loop in main is a good idea, this will ensure that if any thread go into a block state, that it will eventually reset.

    Kenneth

  • Hello Kenneth,

    We had the problem, which is however very hard to replicate, that when we get a disconnect event it does not return to advertising. I dont know if we return into the main loop and just lack the advertising, or the code in genereall gets blocked. So I wanted to make sure that advertising will always resume. I did not find however where I could put the wtd feed function to ensure that. My idea was to do that in the same code part where the advertisement is handled, I could not find where that happens however, or if that is eaven recommended to do.

    So basically what I am afraid of is that the main thread keeps working without problem, which would keep feeding the wtd, but the bluetooth thread might have a problem.

    Thanks for your help!

Related