When adding button interrupt to "chat" exmaple, the system crashed.

Toolchain : nRF Connect SDK V2.3.0

Board : PCA10056

IC : nRF52840

We copy a "chat" example from nrf/samples/bluetooth/mesh/chat

After building and flashing it into PCA10056, we can use android app "Nordic nRF Mesh" to provision PCA10056 into mesh network.

Once we add below code and flash into PCA10056.

We trigger interrupt GPIO, the system reset and shows below error message.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Add Button Code : 

#define SW0_NODE    DT_ALIAS(sw0)
#if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
#error "Unsupported board: sw0 devicetree alias is not defined"
#endif

static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
static struct gpio_callback button_cb_data;

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
    printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
}

void main(void) {
   
    int ret;

    if (!gpio_is_ready_dt(&button)) {
        printk("Error: button device %s is not ready\n",
               button.port->name);
        return 0;
    }

    ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
    if (ret != 0) {
        printk("Error %d: failed to configure %s pin %d\n",
               ret, button.port->name, button.pin);
        return 0;
    }
 
    ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
   
    if (ret != 0) {
        printk("Error %d: failed to configure interrupt on %s pin %d\n",
            ret, button.port->name, button.pin);
        return 0;
    }

    gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
    gpio_add_callback(button.port, &button_cb_data);
}
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Error Messgae : 

Button pressed at 640331
ASSERTION FAIL @ WEST_TOPDIR/nrf/lib/dk_buttons_and_leds/dk_buttons_and_leds.c:186
[00:00:19.541,442] <err> os: esf_dump: r0/a1: 0x00000004 r1/a2: 0x000000ba r2/a3: 0x00000005
[00:00:19.541,473] <err> os: esf_dump: r3/a4: 0x20002440 r12/ip: 0x00000010 r14/lr: 0x0003e853
[00:00:19.541,473] <err> os: esf_dump: xpsr: 0x41000016
[00:00:19.541,503] <err> os: esf_dump: Faulting instruction address (r15/pc): 0x00049368
[00:00:19.541,534] <err> os: z_fatal_error: >>> ZEPHYR FATAL ERROR 4: Kernel panic on CPU 0
[00:00:19.541,564] <err> os: z_fatal_error: Fault during interrupt handling

[00:00:19.541,625] <err> os: z_fatal_error: Current thread: 0x20004328 (idle)
[00:00:19.690,460] <err> fatal_error: k_sys_fatal_error_handler: Resetting system
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If we comment out the bt_enable(bt_ready), the interrupt function works fine.
Button pressed at 215420
Button pressed at 215422
Button pressed at 215424
Button pressed at 337356
Button pressed at 337358
Button pressed at 337359
Button pressed at 337361
Button pressed at 337362
Button pressed at 337367
Button pressed at 337373
Button pressed at 401065
Button pressed at 401067
Button pressed at 401073
Button pressed at 401074
Parents
  • Hi Zhong, 

    I don't see a problem with that. As long as you don't call any Bluetooth API in the interrupt handler. 
    I did a quick test here with the chat sample (NCS v2.5.0) and I didn't see any problem. 

    main.c : 

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    /** @file
     *  @brief Nordic Mesh light sample
     */
    #include <zephyr/bluetooth/bluetooth.h>
    #include <bluetooth/mesh/models.h>
    #include <bluetooth/mesh/dk_prov.h>
    #include <dk_buttons_and_leds.h>
    #include "model_handler.h"
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/sys/util.h>
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(chat, CONFIG_LOG_DEFAULT_LEVEL);
    #define SW0_NODE    DT_ALIAS(sw0)
    #if !DT_NODE_HAS_STATUS(SW0_NODE, okay)
    #error "Unsupported board: sw0 devicetree alias is not defined"
    #endif
    
    static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
    static struct gpio_callback button_cb_data;
    
    void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
    {
        printk("Button pressed at %" PRIu32 "\n", k_cycle_get_32());
    }
    
    static void bt_ready(int err)
    {
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    		return;
    	}
    
    	printk("Bluetooth initialized\n");
    
    	dk_leds_init();
    	dk_buttons_init(NULL);
    
    	err = bt_mesh_init(bt_mesh_dk_prov_init(), model_handler_init());
    	if (err) {
    		printk("Initializing mesh failed (err %d)\n", err);
    		return;
    	}
    
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	/* This will be a no-op if settings_load() loaded provisioning info */
    	bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
    
    	printk("Mesh initialized\n");
    }
    
    int main(void)
    {
    	int err;
      	int ret;
    	printk("Initializing...\n");
    	err = bt_enable(bt_ready);
    	if (err) {
    		printk("Bluetooth init failed (err %d)\n", err);
    	}
       	if (!gpio_is_ready_dt(&button)) {
            printk("Error: button device %s is not ready\n",
                   button.port->name);
            return 0;
        }
    
        ret = gpio_pin_configure_dt(&button, GPIO_INPUT);
        if (ret != 0) {
            printk("Error %d: failed to configure %s pin %d\n",
                   ret, button.port->name, button.pin);
            return 0;
        }
     
        ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
       
        if (ret != 0) {
            printk("Error %d: failed to configure interrupt on %s pin %d\n",
                ret, button.port->name, button.pin);
            return 0;
        }
    
        gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin));
        gpio_add_callback(button.port, &button_cb_data);
    
    
    	
    
    	return 0;
    }
    

    Could you please test ? 

    If you plan to call BLE function inside a the handler, you would need to use work queue instead. Or you can use the dk_buttons library like in our peripheral_lbs sample. 

  • Hi Hung,

    I upgrade ncs version from 2.3.0 to 2.5.0.
    The issue fixed, thanks for your help.

Reply Children
No Data
Related