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!

  • Paul M. said:
    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.

    Ah, in such case watchdog wouldn't help no. You can just also periodically call the api to start advertisement, and just ignore the potential error code it will return if it's already advertising. I am not aware of any reason why it would stop advertising on it's own no.

    Kenneth

Related