Core Panic with Bluetooth + freeRTOS

paeion
Posts: 4
Joined: Tue Feb 01, 2022 5:23 am

Core Panic with Bluetooth + freeRTOS

Postby paeion » Tue Feb 01, 2022 5:37 am

  1. Hi all, I have a simple program to measure an external ADC via SPI with the ESP32 and I am trying to send the raw data received over bluetooth to my PC. I have implemented freeRTOS within the arduino IDE and when using the Serial port the code works without issues. When I attempt to do the same using Bluetooth Serial the ESP32 resets continuously in panic and I get: Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). I have tried my best to debug it and explore similar threads on the internet but I can't really figure out the issue. Below is my code and the snippet of the error message (I haven't figured out how to decode the backtrace yet). Any advice would be extremely welcome, thanks in advance!
  1. //
  2. #include "esp_system.h"
  3. #include "freertos/FreeRTOS.h"
  4. #include "freertos/task.h"
  5. #include "freertos/timers.h"
  6.  
  7. #include <SPI.h>
  8. #include <SoftwareSerial.h>
  9. #include <BluetoothSerial.h>
  10. #include <ads1262.h>
  11.  
  12. #define PGA 32          // Programmable Gain = 32
  13. #define VREF 2.50       // Internal reference of 2.5V
  14. #define BUFF_SIZE 32
  15. #define BYTE_LEN 4      // Number of bytes for 32 bit int
  16.  
  17. ads1262 ADS; // ADS class
  18. BluetoothSerial SerialBT;
  19.  
  20. int32_t val1;
  21. int32_t val2;
  22. int32_t val3;
  23. int32_t val4;
  24. int32_t val5;
  25.  
  26. int32_t data1;
  27. int32_t data2;
  28. int32_t data3;
  29. int32_t data4;
  30. int32_t timeData;
  31.  
  32. int32_t t_start;
  33. int32_t t_finish;
  34.  
  35. volatile char *data_struct;
  36. volatile char buff_array[6];
  37. volatile long data_array[4];
  38. volatile signed long counts;
  39. volatile int isDataReady = 0;
  40.  
  41. TaskHandle_t TaskGetData;
  42. TaskHandle_t TasksendPC;
  43. QueueHandle_t Queue1;
  44. QueueHandle_t Queue2;
  45. QueueHandle_t Queue3;
  46. QueueHandle_t Queue4;
  47. QueueHandle_t QueueT;
  48. //SemaphoreHandle_t semaphore;
  49.  
  50. void setup()
  51. {
  52.     portDISABLE_INTERRUPTS();
  53.  
  54.     // initalize the  data ready and chip select pins:
  55.     pinMode(ADS1262_DRDY_PIN, INPUT);   // Data ready input line
  56.     pinMode(ADS1262_CS_PIN, OUTPUT);    // Chip enable output line
  57.     pinMode(ADS1262_START_PIN, OUTPUT); // Start
  58.     pinMode(ADS1262_PWDN_PIN, OUTPUT);  // Power down output
  59.     attachInterrupt(digitalPinToInterrupt(ADS1262_DRDY_PIN), awaitDRDY, FALLING);
  60.  
  61.     SerialBT.begin("PLAKA PLATES");
  62. //    Serial.begin(500000);               // Max Baud Rate
  63.     ADS.ads1262_Init();                 // Initialise ADS1262
  64.  
  65.     Queue1 = xQueueCreate(500, sizeof(int32_t));
  66.     Queue2 = xQueueCreate(500, sizeof(int32_t));
  67.     Queue3 = xQueueCreate(500, sizeof(int32_t));
  68.     Queue4 = xQueueCreate(500, sizeof(int32_t));
  69.     QueueT = xQueueCreate(500, sizeof(int32_t));
  70.  
  71.    setCpuFrequencyMhz(240);
  72.    xTaskCreatePinnedToCore(loopGet, "TaskGetData", 4096, NULL, 3, &TaskGetData, 1); // 0
  73.    xTaskCreatePinnedToCore(loopSend, "TasksendPC", 4096, NULL, 3, &TasksendPC, 1); // 1
  74.    
  75.    portENABLE_INTERRUPTS();
  76. }
  77.  
  78. void loop()
  79. {
  80.     vTaskDelete (NULL);
  81. }
  82.  
  83.  void loopGet(void *parameter)
  84. {
  85.     for (;;) {
  86.         t_start = micros(); // micros()
  87.  
  88.         // Cycle through differential channels
  89.         val1 = read_channel(0x01);
  90.         val2 = read_channel(0x23);
  91.         val3 = read_channel(0x45);
  92.         val4 = read_channel(0x67);
  93.         val5 = read_channel(0x01);  // Dummy read to not affect 4th load cell reading
  94.        
  95.         xQueueSend(Queue1, &val1, portMAX_DELAY);
  96.         xQueueSend(Queue2, &val2, portMAX_DELAY);
  97.         xQueueSend(Queue3, &val3, portMAX_DELAY);
  98.         xQueueSend(Queue4, &val4, portMAX_DELAY);
  99.        
  100.         t_finish = micros() - t_start;
  101.         xQueueSend(QueueT, &t_finish, portMAX_DELAY);
  102.     }
  103. }
  104.  
  105.  void loopSend(void *parameter)
  106. {
  107.     for (;;) {
  108.  
  109.         xQueueReceive(Queue1, &data1, portMAX_DELAY);
  110.         xQueueReceive(Queue2, &data2, portMAX_DELAY);
  111.         xQueueReceive(Queue3, &data3, portMAX_DELAY);
  112.         xQueueReceive(Queue4, &data4, portMAX_DELAY);
  113.         xQueueReceive(QueueT, &timeData, portMAX_DELAY);
  114.  
  115.         // Serial Port Debug
  116. //        printf("%i,%i,%i,%i,%i\n", data1, data2, data3, data4, timeData);
  117.        
  118.         // Send binary to Bluetooth Serial Port
  119.         SerialBT.write((byte*)&data1, BYTE_LEN);
  120.         SerialBT.write((byte*)&data2, BYTE_LEN);
  121.         SerialBT.write((byte*)&data3, BYTE_LEN);
  122.         SerialBT.write((byte*)&data4, BYTE_LEN);
  123.         SerialBT.write((byte*)&timeData, BYTE_LEN);
  124.         SerialBT.write('\n');
  125.     }
  126. }
  127.  
  128. void awaitDRDY() {  // IRAM_ATTR
  129.     isDataReady = 1;
  130. //    xSemaphoreGive(semaphore);
  131. }
  132.  
  133. // Read adc binary data
  134. int32_t read_channel(char channel)
  135. {
  136.     // Channel multiplexer channel
  137.     ADS.ads1262_Reg_Write(INPMUX, channel);
  138.    
  139.     // Wait until ADC is ready for conversion    //    while (digitalRead(ADS1262_DRDY_PIN) != LOW){
  140.     isDataReady = 0;
  141.     while (isDataReady != 1) {}
  142. //    xSemaphoreTake(semaphore, portMAX_DELAY);  // Faster ISR response to DRDY signal
  143.    
  144.     // Dump Binary Data
  145.     data_struct = ADS.ads1262_Read_Data();
  146.     for (int i = 1; i < 5; ++i)
  147.       {
  148.         buff_array[i] = *(data_struct + i);              
  149.         data_array[i] = (unsigned char)buff_array[i];
  150.       }
  151.     counts = (signed long) (((unsigned long)data_array[0]<<24) | ((unsigned long)data_array[1]<<16) | (data_array[2]<<8) | data_array[3]);
  152.     return counts;
  153. }
  1. Rebooting...
  2. ets Jul 29 2019 12:21:46
  3.  
  4. rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
  5. configsip: 0, SPIWP:0xee
  6. clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
  7. mode:DIO, clock div:1
  8. load:0x3fff0018,len:4
  9. load:0x3fff001c,len:1044
  10. load:0x40078000,len:10124
  11. load:0x40080400,len:5856
  12. entry 0x400806a8
  13. Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
  14. Core 1 register dump:
  15. PC      : 0x40092824  PS      : 0x00060b34  A0      : 0x80091a3b  A1      : 0x3ffc7490  
  16. A2      : 0x3ffbbca4  A3      : 0x3ffc7720  A4      : 0x00000001  A5      : 0x00000001  
  17. A6      : 0x00060b23  A7      : 0x00000000  A8      : 0x3ffc7720  A9      : 0x3ffc7720  
  18. A10     : 0x00000018  A11     : 0x00000018  A12     : 0x00000001  A13     : 0x00000001  
  19. A14     : 0x00060b23  A15     : 0x00000000  SAR     : 0x0000001d  EXCCAUSE: 0x00000006  
  20. EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
  21.  
  22. ELF file SHA256: 0000000000000000
  23.  
  24. Backtrace: 0x40092824:0x3ffc7490 0x40091a38:0x3ffc74b0 0x4008fcef:0x3ffc74d0 0x400e2fbb:0x3ffc7510 0x4015a1df:0x3ffc7530 0x400e354f:0x3ffc7570 0x400d23aa:0x3ffc7590 0x400d1e3e:0x3ffc75d0 0x400d13ba:0x3ffc7610 0x400d3332:0x3ffc7650 0x4008ff1a:0x3ffc7670
  25.  
  26. Core 0 register dump:
  27. PC      : 0x40090f1e  PS      : 0x00060334  A0      : 0x80092079  A1      : 0x3ffcbb10  
  28. A2      : 0x3ffbed5c  A3      : 0x0000cdcd  A4      : 0xb33fffff  A5      : 0x00000001  
  29. A6      : 0x00060123  A7      : 0x0000abab  A8      : 0x0000abab  A9      : 0x3ffcbc50  
  30. A10     : 0x3ffae704  A11     : 0x00000002  A12     : 0x00060320  A13     : 0x3ffcbcf8  
  31. A14     : 0x00000006  A15     : 0x00000000  SAR     : 0x00000000  EXCCAUSE: 0x00000006  
  32. EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
  33.  
  34. ELF file SHA256: 0000000000000000
  35.  
  36. Backtrace: 0x40090f1e:0x3ffcbb10 0x40092076:0x3ffcbb40 0x4008fc57:0x3ffcbb60 0x40086517:0x3ffcbba0 0x400865ed:0x3ffcbbd0 0x40172691:0x3ffcbbf0 0x40155636:0x3ffcbc10 0x401556e5:0x3ffcbc50 0x400814e6:0x3ffcbc80 0x40159676:0x3ffcbca0 0x40159744:0x3ffcbcd0 0x40159d28:0x3ffcbcf0 0x4008ff1a:0x3ffcbd20
  37.  

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Core Panic with Bluetooth + freeRTOS

Postby ESP_Sprite » Tue Feb 01, 2022 11:45 am

paeion wrote:
Tue Feb 01, 2022 5:37 am
  1. //
  2. void setup()
  3. {
  4.     portDISABLE_INTERRUPTS();
  5. [...]  
  6.    portENABLE_INTERRUPTS();
  7. }
Why?

paeion
Posts: 4
Joined: Tue Feb 01, 2022 5:23 am

Re: Core Panic with Bluetooth + freeRTOS

Postby paeion » Tue Feb 01, 2022 10:40 pm

ESP_Sprite, I was attempting to use a binary semaphore to remove the while loop that waits for the external interrupt and I believe
  1. xSemaphoreGive(semaphore);
was calling before the xSemaphoreCreate() line was executed in setup hence disabling the interrupts. I believe it is not needed for how I am doing it and just something I forgot to comment out.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Core Panic with Bluetooth + freeRTOS

Postby ESP_Sprite » Wed Feb 02, 2022 3:12 am

Good. Does removing those lines also fix your issue? If not, decoding the backtrace is your best bet: you probably want this.

paeion
Posts: 4
Joined: Tue Feb 01, 2022 5:23 am

Re: Core Panic with Bluetooth + freeRTOS

Postby paeion » Wed Feb 02, 2022 3:38 am

Thanks ESP_Sprite, admittedly removing those two lines fixed the core panic issue I was seeing. I had to move around the sequence of initialisation in the setup() to get the Bluetooth to work properly. For example, sometimes I cannot connect to the ESP32 bluetooth port on my Mac saying 'resource busy'.

I am also experiencing the following behaviour which is very confusing:
Case 1: I send the ADC data over the software serial port, the data is good.
Case 2: I send the data over the software AND bluetooth serial, the data is good ONLY IF viewed over the software serial port.
Case 3: I do as above and open the software AND bluetooth port, the data is corrupted at random, recurrent intervals. As soon as the bluetooth port is closed the data is good again on the software serial.
Case 4: I only send data over the bluetooth serial port, the same periodic data corruption is present.
(Attached photos of behaviour)

I know for a fact that if the ADC data read routine does not happen fast enough, the data can be corrupted because the SPI communication is reading the ADC register as it settles to new values. However I cannot understand how opening the bluetooth port could case additional latency in the ESP freeRTOS if the bluetooth serial data is being sent regardless of the activity on the PC side (i.e. port open or closed).

Any thoughts on this would be a lifesaver! :)
(For reference: Using Arduino IDE on Windows 10 to flash ESP32 Firebeetle board, software serial port open on Arduino IDE/ PuTTy on Windows 10, bluetooth serial open on MacOS High Sierra using Python 3 and the PySerial library)
Attachments
good_data_software_serial.png
good_data_software_serial.png (1.11 MiB) Viewed 11841 times
Corrupted_data_bluetooth_software_serial.png
Corrupted_data_bluetooth_software_serial.png (1.15 MiB) Viewed 11841 times

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Core Panic with Bluetooth + freeRTOS

Postby ESP_Sprite » Wed Feb 02, 2022 11:53 am

I can't help you with that, sorry, I'm not deeply familiar with those Arduino APIs.

paeion
Posts: 4
Joined: Tue Feb 01, 2022 5:23 am

Re: Core Panic with Bluetooth + freeRTOS

Postby paeion » Thu Feb 03, 2022 12:47 am

All good ESP_Sprite! I managed to debug it, it has nothing to do with the functioning of the ESP32 or the bluetooth. I was using "\n" newline characters that are showing up in my data and therefore getting split data packets when I should not have. Thanks again for the rapid responses and assistance!

xien551
Posts: 69
Joined: Wed Feb 02, 2022 4:04 am

Re: Core Panic with Bluetooth + freeRTOS

Postby xien551 » Thu Feb 03, 2022 2:47 am

Hey, paeion. Arduino is not a real time system. I remember the timestamp is only 1ms. I doubt that the Arduino would not work well with freeRTOS. And I suggest using IDF instead. I think you should learn the callback function, which is also popular in STM32 SDK for better real-time performance.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Core Panic with Bluetooth + freeRTOS

Postby ESP_Sprite » Thu Feb 03, 2022 5:36 am

xien551 wrote:
Thu Feb 03, 2022 2:47 am
Hey, paeion. Arduino is not a real time system. I remember the timestamp is only 1ms. I doubt that the Arduino would not work well with freeRTOS. And I suggest using IDF instead. I think you should learn the callback function, which is also popular in STM32 SDK for better real-time performance.
Can you substantiate that 'Arduino is not a real-time system'? It's a strange assertion to me, especially given that it's built on ESP-IDF itself.

xien551
Posts: 69
Joined: Wed Feb 02, 2022 4:04 am

Re: Core Panic with Bluetooth + freeRTOS

Postby xien551 » Thu Feb 03, 2022 6:25 am

Let me tell you the history of Arduino.

Do you know that Arduino is developed by the artist?
Some artists want to design a Automatic works of art. Namely, the work is not static, but can move, like a robot.

They find many microprocessor, just find them hard to learn. So they create the Arduino, which is not just a software, it's a system with hardware and software. The original hardware is Arduino uno, which is based on ATmega 32, a 8 bit microprocessor. The software is what we familiar with ,the Arduino ide, which is a editor, compiler, flash tool and monitor.

Arduino is not used for real time application. the artist work need not to be acted very fast, 1ms is enough.
Arduino hide hardware interrupts underlying code, which is important to real time performance.

Also, real-time performance is different to different application. For the artist, 1ms is realy precise. But, for industrial application, 1ms is too slow, we want the 1us precision. They need real time operation system. For example, VxWorks, rtLinux,ucos, freeRTOS. If 1us is not enough, then we choose the hardware solution, CPLD or FPGA.

Arduino is not suitable for industrial application, where the us realtime performance is important. For most critical real-time application, even the mcu or dsp is not used, we use PLC.

real-time is not easy to realize, freeRTOS is a good system. But Arduino is not ,they are just used for prototype verification. If you are a engineer, you would agree with me. No one dare using Arduino for industrial application, for Example, Power system.

Who is online

Users browsing this forum: No registered users and 88 guests