Turning off BLE module after a time out period using a timer

cdyrssen
Posts: 2
Joined: Sat Jul 14, 2018 6:28 pm

Turning off BLE module after a time out period using a timer

Postby cdyrssen » Sun Sep 02, 2018 10:10 pm

Hello,

I have been struggling to get a working implementation of a timer to trigger once after a specified time which can stop all BLE services, stop advertising the BLE server, and shutdown the BLE module on the ESP32. I am using Neil Kolban's cpp_utils from his esp32-snippets github repository found here: https://github.com/nkolban/esp32-snippets. Specifically, I am creating a BLE server with custom services and characteristics using his BLEServer, BLEService, and BLECharacteristic classes.

Here is the interrupt service routine I am trying to use to accomplish this:

Code: Select all

static void IRAM_ATTR shutdownBLEModule(void *tmp){
	printf("Stop BLE services...\n");
	myBLEProfile->pBatterySvc->stop();
	myBLEProfile->pWifiSelectSvc->stop();

	printf("Stop advertising bluetooth server...\n");
	myBLEProfile->pServer->getAdvertising()->stop();

	printf("Bluetooth module shutting down\n");
	int err = esp_bt_controller_disable();
	printf("Bluetooth module shut down with error: %i\n", err);
}
The myBLEProfile variable is a pointer to an instance of a class of my own which contains the BLEServer, BLEService, BLECharacteristic, and other objects used in my application.

This is the code I am using to set up the timer:

Code: Select all

	timer_group_t timerGroup = TIMER_GROUP_0;
	timer_idx_t timerIndex = TIMER_0;
	timer_config_t timerConfig;
	memset(&timerConfig, 0, sizeof(timerConfig));
	timerConfig.alarm_en = 1;
	timerConfig.auto_reload = 0;
	timerConfig.counter_dir = TIMER_COUNT_UP;
	timerConfig.divider = 80;
	timerConfig.intr_type = TIMER_INTR_LEVEL;
	timerConfig.counter_en = TIMER_PAUSE;

	timer_init(timerGroup, timerIndex, &timerConfig);
	timer_pause(timerGroup, timerIndex);
	timer_set_counter_value(timerGroup, timerIndex, 0x00000000ULL);
	timer_set_alarm_value(timerGroup, timerIndex, (TIMER_BASE_CLK / 80) * 5);
	timer_enable_intr(timerGroup, timerIndex);
	timer_isr_register(timerGroup, timerIndex, shutdownBLEModule, (void *) timerIndex, ESP_INTR_FLAG_IRAM,  NULL);
	timer_start(timerGroup, timerIndex);
However, whenever I run a make monitor, the program runs through and after 5 seconds the timer triggers. When the timer is triggered I get the following error over and over again.

Code: Select all

Guru Meditation Error: Core  0 panic'ed (Interrupt wdt timeout on CPU0)
Core 0 register dump:
PC      : 0x400924f8  PS      : 0x00060334  A0      : 0x80091506  A1      : 0x3ffc08e0  
0x400924f8: vListInsert at /home/toffer/esp/iLeash/esp-idf/components/freertos/list.c:188 (discriminator 1)

A2      : 0x3ffd442c  A3      : 0x3ffd5ec0  A4      : 0x00060321  A5      : 0x00000001  
A6      : 0x00060321  A7      : 0x3ffe1a70  A8      : 0x3ffd5ec0  A9      : 0x3ffd5ec0  
A10     : 0x00000019  A11     : 0x00000019  A12     : 0x00000013  A13     : 0x00000001  
A14     : 0x00060323  A15     : 0x00000000  SAR     : 0x00000012  EXCCAUSE: 0x00000005  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core 0 was running in ISR context:
EPC1    : 0x40166bc8  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x400924f8
0x40166bc8: esp_ble_gatts_stop_service at /home/toffer/esp/iLeash/esp-idf/components/bt/bluedroid/api/esp_gatts_api.c:279

0x400924f8: vListInsert at /home/toffer/esp/iLeash/esp-idf/components/freertos/list.c:188 (discriminator 1)


Backtrace: 0x400924f8:0x3ffc08e0 0x40091503:0x3ffc0900 0x40090088:0x3ffc0920 0x4010e0f5:0x3ffc0960 0x40088cb9:0x3ffc09a0 0x40082bc2:0x3ffc0a00 0x400824e9:0x3ffc0a20 0x401a02ef:0x00000000
0x400924f8: vListInsert at /home/toffer/esp/iLeash/esp-idf/components/freertos/list.c:188 (discriminator 1)

0x40091503: vTaskPlaceOnEventList at /home/toffer/esp/iLeash/esp-idf/components/freertos/tasks.c:3564

0x40090088: xQueueGenericReceive at /home/toffer/esp/iLeash/esp-idf/components/freertos/queue.c:2037

0x4010e0f5: FreeRTOS::Semaphore::wait(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) at /home/toffer/esp/iLeash/test/components/cpp_utils/FreeRTOS.cpp:85

0x40088cb9: BLEService::stop() at /home/toffer/esp/iLeash/test/components/cpp_utils/BLEService.cpp:397

0x40082bc2: shutdownBLEModule(void*) at /home/toffer/esp/iLeash/test/main/main_helloworld.cpp:25

0x400824e9: _xt_lowint1 at /home/toffer/esp/iLeash/esp-idf/components/freertos/xtensa_vectors.S:1105

0x401a02ef: esp_vApplicationWaitiHook at /home/toffer/esp/iLeash/esp-idf/components/esp32/freertos_hooks.c:66


Core 1 register dump:
PC      : 0x40090333  PS      : 0x00060034  A0      : 0x8009079a  A1      : 0x3ffd6270  
0x40090333: uxPortCompareSet at /home/toffer/esp/iLeash/esp-idf/components/freertos/port.c:374
 (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/toffer/esp/iLeash/esp-idf/components/freertos/portmux_impl.inc.h:86
 (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/toffer/esp/iLeash/esp-idf/components/freertos/portmux_impl.h:98
 (inlined by) vPortCPUAcquireMutex at /home/toffer/esp/iLeash/esp-idf/components/freertos/port.c:365

A2      : 0x3ffc110c  A3      : 0x00000000  A4      : 0x800902d2  A5      : 0x3ffc0fe0  
A6      : 0x3ffc1028  A7      : 0x00000001  A8      : 0x0000cdcd  A9      : 0x0000abab  
A10     : 0x00060023  A11     : 0xb33fffff  A12     : 0x0000cdcd  A13     : 0x3ffc0fb0  
A14     : 0x00000008  A15     : 0x00000001  SAR     : 0x00000019  EXCCAUSE: 0x00000005  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  

Backtrace: 0x40090333:0x3ffd6270 0x40090797:0x3ffd6290 0x400920f8:0x3ffd62b0 0x400920ae:0x00000000
0x40090333: uxPortCompareSet at /home/toffer/esp/iLeash/esp-idf/components/freertos/port.c:374
 (inlined by) vPortCPUAcquireMutexIntsDisabledInternal at /home/toffer/esp/iLeash/esp-idf/components/freertos/portmux_impl.inc.h:86
 (inlined by) vPortCPUAcquireMutexIntsDisabled at /home/toffer/esp/iLeash/esp-idf/components/freertos/portmux_impl.h:98
 (inlined by) vPortCPUAcquireMutex at /home/toffer/esp/iLeash/esp-idf/components/freertos/port.c:365

0x40090797: vTaskSwitchContext at /home/toffer/esp/iLeash/esp-idf/components/freertos/tasks.c:3564

0x400920f8: _frxt_dispatch at /home/toffer/esp/iLeash/esp-idf/components/freertos/portasm.S:406

0x400920ae: _frxt_int_exit at /home/toffer/esp/iLeash/esp-idf/components/freertos/portasm.S:206


Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:4748
load:0x40078000,len:7304
load:0x40080400,len:7076
entry 0x40080748
NVS open OK
The first time the board runs the program it seems to wait the full 5 seconds before triggering the error, but every subsequent reboot afterwards the timer's 5 second delay is completely skipped and causes another panic and reboot immediately. This continues indefinitely until the board is reset, in which case the 5 second delay from the timer occurs again until the interrupt service routine is triggered, at which point the program continues to produce a panic and reboot once more.

My first thought was that I was calling functions that were stored in flash and not in RAM, since the classes within Neil Kolban's ccp_utils library do no use the IRAM_ATTR on any of the class methods. However, when I tried to manually add the IRAM_ATTR to the methods which were being called within my interrupt service routine, nothing seemed to change. I even tried removing all the method calls from within the BLE classes and just run the following line in the interrupt service routine:

Code: Select all

int err = esp_bt_controller_disable();
That seemed to not have an affect either, though.

I was looking into maybe using the esp_intr_alloc() function, but I am unsure about how to use it in this case and if it would solve my issues. I am at the boundaries of my knowledge to debug this issue and hope someone could help point me in the right direction to solve this problem.

Thanks
cdyrssen

chegewara
Posts: 2378
Joined: Wed Jun 14, 2017 9:00 pm

Re: Turning off BLE module after a time out period using a timer

Postby chegewara » Mon Sep 03, 2018 7:49 pm

Hi, you cant use standard debug functions like printf or ESP_LOGX in interrupt function (ISR).

JoaoLopesF
Posts: 59
Joined: Thu Aug 17, 2017 5:40 pm

Re: Turning off BLE module after a time out period using a timer

Postby JoaoLopesF » Wed Sep 05, 2018 10:56 am

chegewara wrote:Hi, you cant use standard debug functions like printf or ESP_LOGX in interrupt function (ISR).
Yes, you must use ets_printf or ESP_EARLY_LOG*
(not for timers or interrupts that can execute in lower intervals, due this functions have a overhead)

cdyrssen
Posts: 2
Joined: Sat Jul 14, 2018 6:28 pm

Re: Turning off BLE module after a time out period using a timer

Postby cdyrssen » Sun Sep 09, 2018 1:23 am

Thanks guys for the responses. I ended up getting a functioning timeout timer using FreeRTOS Software Timer instead, but I will definitely keep that in mind next time I need a hardware timer. Is there a reason why ets_printf or ESP_EARLY_LOGX is not the standard? It would seem to me that it would be much more intuitive for newbies like myself to have a single print function that is guaranteed to work everywhere for simple debugging. Are there any disadvantages to using either of those options on a regular basis and ignoring printf and ESP_LOGX?
cdyrssen

Who is online

Users browsing this forum: No registered users and 91 guests