k_sem_take error -11 when I call the bt_le_adv_start() functions.

Hi, I'm developing ble applications.

But there are problems on calling Ble APIs.

If I call the functions that conatins bt_le_adv_start() in main loop(Maybe main thread?), It start advertising well.

But If I call same function on GPIOTE Interrupt handler, I got the "ASSETION FAIL" message like this :

ASSERTION FAIL [err == 0] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/hci_core.c:430
  Controller unresponsive, command opcode 0x2005 timeout with err -11

The purpose of this interrupt is making button for starting or stopping advertisement of BLE.

If I press the button once, It is starting to advertising and If I press it again, advertising stops.

But I cannot make it because of that error.

Here is my entire code for BLE

BLE configuration structure : 

struct BLE_CONFIG_PERIPHERAL{
    char adv_name[20];
    uint16_t mtu;
    int8_t tx_pwr;
};

BLE Peripheral initialization : 

	static char temp_adv_name[50];
	uint8_t *addr = getAddress();
	sprintf(temp_adv_name, "%s-%02X%02X", config.adv_name, addr[4], addr[5]);
	sd = BT_DATA(BT_DATA_NAME_COMPLETE, (const uint8_t *)temp_adv_name, (uint8_t)strlen(temp_adv_name));
	int32_t err = 0;

	if(IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
		err = bt_conn_auth_cb_register(&conn_auth_callbacks);
		if (err) {
			printk("Failed to register authorization callbacks.\n");
			return;
		}

		err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
		if (err) {
			printk("Failed to register authorization info callbacks.\n");
			return;
		}
	}

	err = bt_enable(NULL);
	bt_set_name(temp_adv_name);
	k_sem_give(&ble_init_ok);

	// Load settings
	if (IS_ENABLED(CONFIG_SETTINGS)) {
		settings_load();
	}

	err = bt_nus_init(&nus_cb);
	if (err) {
		return;
	}

start advertising fucntion : 

	static struct bt_le_adv_param params;
	params.options = BT_LE_ADV_OPT_CONNECTABLE;
	params.interval_min = 32;
	params.interval_max = 64;
	params.peer = NULL;
	params.options |= BT_LE_ADV_OPT_USE_TX_POWER;
	uint32_t err = bt_le_adv_start(&params, ad, ARRAY_SIZE(ad), &sd, 1);
	if (err) {
		return;
	}else{
		BleEventListener(BLE_EVT_ADV_STARTED);
	}

Why this function can run at void main() functions?

And how can I implement these functions at interrupt functions?

Parents
  • Hi!

    Could you post a stripped-down sample that reproduces this ?

  • void main(){
        // Initialize BLE Module
        BLE_CONFIG_PERIPHERAL ble_config = {
                .adv_name = "ARA",
                .mtu = 247,
                .tx_pwr = 4
        };
        ble.Init(ble_config);
        k_sem_give(&test);
        ble.startAdv();
        while(true){
            ...
        }
    }
    
    
    // GPIOTE Interrupt Handler for Adv. Button
    void GPIOTE_IRQHandler(){
            // GPIO Task & Event Event Handler
            static bool isStarted = false;
            if(NRF_GPIOTE->EVENTS_IN[0] == 1){
                    NRF_GPIOTE->EVENTS_IN[0] = 0;
                    if(!isStarted){
                            // Advertising 시작
                            printk("Start Adv\r\n");
                            k_sem_take(&test, K_FOREVER);
                            ble.startAdv();
                            isStarted = true;
                    }else{
                            // Advertising 중단
                            printk("Stop Adv\r\n");
                            ble.stopAdv();
                            isStarted = false;
                    }
            }
    }
    
    void BLE_PERIPHERAL::Init(BLE_CONFIG_PERIPHERAL config){
    	// BluetoothLE initializing functions
    	static char temp_adv_name[50];
    	uint8_t *addr = getAddress();
    	sprintf(temp_adv_name, "%s-%02X%02X", config.adv_name, addr[4], addr[5]);
    	sd = BT_DATA(BT_DATA_NAME_COMPLETE, (const uint8_t *)temp_adv_name, (uint8_t)strlen(temp_adv_name));
    	int32_t err = 0;
    
    	if(IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
    		err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    		if (err) {
    			printk("Failed to register authorization callbacks.\n");
    			return;
    		}
    
    		err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    		if (err) {
    			printk("Failed to register authorization info callbacks.\n");
    			return;
    		}
    	}
    
    	err = bt_enable(NULL);
    	bt_set_name(temp_adv_name);
    	k_sem_give(&ble_init_ok);
    
    	// Load settings
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	err = bt_nus_init(&nus_cb);
    	if (err) {
    		return;
    	}
    }
    
    
    void BLE_PERIPHERAL::startAdv(){
    	// Advertising Start Function
    	static struct bt_le_adv_param params;
    	params.options = BT_LE_ADV_OPT_CONNECTABLE;
    	params.interval_min = 32;
    	params.interval_max = 64;
    	params.peer = NULL;
    	params.options |= BT_LE_ADV_OPT_USE_TX_POWER;
    	uint32_t err = bt_le_adv_start(&params, ad, ARRAY_SIZE(ad), &sd, 1);
    	if (err) {
    		return;
    	}else{
    		BleEventListener(BLE_EVT_ADV_STARTED);
    	}
    }

Reply
  • void main(){
        // Initialize BLE Module
        BLE_CONFIG_PERIPHERAL ble_config = {
                .adv_name = "ARA",
                .mtu = 247,
                .tx_pwr = 4
        };
        ble.Init(ble_config);
        k_sem_give(&test);
        ble.startAdv();
        while(true){
            ...
        }
    }
    
    
    // GPIOTE Interrupt Handler for Adv. Button
    void GPIOTE_IRQHandler(){
            // GPIO Task & Event Event Handler
            static bool isStarted = false;
            if(NRF_GPIOTE->EVENTS_IN[0] == 1){
                    NRF_GPIOTE->EVENTS_IN[0] = 0;
                    if(!isStarted){
                            // Advertising 시작
                            printk("Start Adv\r\n");
                            k_sem_take(&test, K_FOREVER);
                            ble.startAdv();
                            isStarted = true;
                    }else{
                            // Advertising 중단
                            printk("Stop Adv\r\n");
                            ble.stopAdv();
                            isStarted = false;
                    }
            }
    }
    
    void BLE_PERIPHERAL::Init(BLE_CONFIG_PERIPHERAL config){
    	// BluetoothLE initializing functions
    	static char temp_adv_name[50];
    	uint8_t *addr = getAddress();
    	sprintf(temp_adv_name, "%s-%02X%02X", config.adv_name, addr[4], addr[5]);
    	sd = BT_DATA(BT_DATA_NAME_COMPLETE, (const uint8_t *)temp_adv_name, (uint8_t)strlen(temp_adv_name));
    	int32_t err = 0;
    
    	if(IS_ENABLED(CONFIG_BT_NUS_SECURITY_ENABLED)) {
    		err = bt_conn_auth_cb_register(&conn_auth_callbacks);
    		if (err) {
    			printk("Failed to register authorization callbacks.\n");
    			return;
    		}
    
    		err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
    		if (err) {
    			printk("Failed to register authorization info callbacks.\n");
    			return;
    		}
    	}
    
    	err = bt_enable(NULL);
    	bt_set_name(temp_adv_name);
    	k_sem_give(&ble_init_ok);
    
    	// Load settings
    	if (IS_ENABLED(CONFIG_SETTINGS)) {
    		settings_load();
    	}
    
    	err = bt_nus_init(&nus_cb);
    	if (err) {
    		return;
    	}
    }
    
    
    void BLE_PERIPHERAL::startAdv(){
    	// Advertising Start Function
    	static struct bt_le_adv_param params;
    	params.options = BT_LE_ADV_OPT_CONNECTABLE;
    	params.interval_min = 32;
    	params.interval_max = 64;
    	params.peer = NULL;
    	params.options |= BT_LE_ADV_OPT_USE_TX_POWER;
    	uint32_t err = bt_le_adv_start(&params, ad, ARRAY_SIZE(ad), &sd, 1);
    	if (err) {
    		return;
    	}else{
    		BleEventListener(BLE_EVT_ADV_STARTED);
    	}
    }

Children
Related