Strange I2C driver panic while using IDF 5.4 with C++

ULP_User
Posts: 5
Joined: Thu Jun 13, 2024 8:04 am

Strange I2C driver panic while using IDF 5.4 with C++

Postby ULP_User » Fri Jan 31, 2025 2:48 pm

Hi,

I have a really strange problem here, which is very hard to track down, but I made a very simple minimum project which shows the problem:

I made a data logging project, starting with IDF 5.2.3 on a Lilygo T7-S3-board with a DS3231 RTC and a SHT40 temperature sensor, written in C++. With IDF 5.2.3 everything worked perfect for many weeks.
Now I'd like to update to IDF 5.4 and I'm running in serious problems when I'm talking to my I2C devices. The problem is, that the IRQ watchdog gets fired in the driver's IRQ function. But I can't find any reason for this. The hardware is absolutely fine and the test code is so simple, that I'm sure that the problem is NOT here (keep in mind, that the test code is working 100 % OK with IDF 5.2.3).

Have a look at line 110 in main.cpp: Commenting out the unused class "DS3231 Uhr" will lead to a working program again.
Uncommenting this line will lead to a core 0 panic right BEFORE any code of the classes are executed (line 105, have a look at the monitor output)!

But there's nothing in the class constructor which could lead to any memory corruption. I checked the stack size (8192 bytes) which is more than sufficient. I switched on every stack and heap tracing and checking functions. No stack overflow or any other problem.
I don't have any idea why this happens, but it seems to be related using C++.

I attached the simple test program with the configurations. Switching fore and back the IDF from 5.2.3 to 5.4 will show a working program with 5.2.3 and a failing program with a core 0 panic on IDF 5.4.

Any ideas what to do?
Thanks and bye, Oliver

main.cpp
  1. /*
  2.  * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3.  *
  4.  * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5.  */
  6. #include <string.h>
  7. #include <stdio.h>
  8. #include "esp_log.h"
  9. #include "freertos/FreeRTOS.h"
  10. #include "freertos/task.h"
  11. #include "driver/i2c_master.h"
  12. #include "driver/gpio.h"
  13. #include "main.h"
  14.  
  15. // Uhr und ADC(Druck) am I2C-Bus 0
  16. #define PIN_SDA_BUS0 GPIO_NUM_13
  17. #define PIN_SCL_BUS0 GPIO_NUM_14
  18.  
  19. // Temperatursensor und Luftfeuchte am I2C-Bus
  20. #define PIN_SDA_BUS1 GPIO_NUM_21
  21. #define PIN_SCL_BUS1 GPIO_NUM_18
  22.  
  23. #define MASTER_FREQUENCY 400000
  24. #define PORT_NUMBER -1
  25. #define LENGTH 48
  26. #define SHT40_ADDR (0x44)
  27. #define DS3231_ADDR (0x68)
  28. #define DEV_TIMEOUT 1000
  29.  
  30. // GPIOs
  31. #define BOARD_LED GPIO_NUM_17
  32. #define SWITCH_BRIDGE_AND_CLOCK GPIO_NUM_10
  33.  
  34. void app_main_cpp();
  35.  
  36. extern "C"
  37. {
  38.   void app_main()
  39.   {
  40.     app_main_cpp();
  41.   }
  42. }
  43.  
  44. void app_main_cpp()
  45. {
  46.   // Outputs
  47.   const uint64_t OutputBitMask = (1ULL << BOARD_LED) | (1ULL << SWITCH_BRIDGE_AND_CLOCK);
  48.  
  49.   gpio_config_t ConfigOutput = {};
  50.   ConfigOutput.pin_bit_mask = OutputBitMask;
  51.   ConfigOutput.mode = GPIO_MODE_INPUT_OUTPUT; // damit man auch den aktuell eingestellten Wert zurücklesen kann!
  52.   ConfigOutput.pull_up_en = GPIO_PULLUP_DISABLE;
  53.   ConfigOutput.pull_down_en = GPIO_PULLDOWN_DISABLE;
  54.   ConfigOutput.intr_type = GPIO_INTR_DISABLE;
  55.   ESP_ERROR_CHECK(gpio_config(&ConfigOutput));
  56.  
  57.   // DS3231M
  58.   i2c_master_bus_config_t BusConfig0 = {};
  59.   BusConfig0.clk_source = I2C_CLK_SRC_DEFAULT;
  60.   BusConfig0.i2c_port = -1;
  61.   BusConfig0.scl_io_num = PIN_SCL_BUS0;
  62.   BusConfig0.sda_io_num = PIN_SDA_BUS0;
  63.   BusConfig0.glitch_ignore_cnt = 7;
  64.   BusConfig0.flags.enable_internal_pullup = 1;
  65.  
  66.   // SHT40
  67.   i2c_master_bus_config_t BusConfig1 = {};
  68.   BusConfig1.clk_source = I2C_CLK_SRC_DEFAULT;
  69.   BusConfig1.i2c_port = -1;
  70.   BusConfig1.scl_io_num = PIN_SCL_BUS1;
  71.   BusConfig1.sda_io_num = PIN_SDA_BUS1;
  72.   BusConfig1.glitch_ignore_cnt = 7;
  73.   BusConfig1.flags.enable_internal_pullup = 1;
  74.  
  75.   i2c_master_bus_handle_t BusHandle0, BusHandle1;
  76.  
  77.   ESP_ERROR_CHECK(i2c_new_master_bus(&BusConfig0, &BusHandle0));
  78.   ESP_ERROR_CHECK(i2c_new_master_bus(&BusConfig1, &BusHandle1));
  79.  
  80.   i2c_device_config_t SHTConfig, ClockConfig;
  81.   i2c_master_dev_handle_t iSHTHandle, iClockHandle;
  82.  
  83.   ClockConfig.dev_addr_length = I2C_ADDR_BIT_LEN_7;
  84.   ClockConfig.device_address = DS3231_ADDR;
  85.   ClockConfig.scl_speed_hz = MASTER_FREQUENCY;
  86.   ESP_ERROR_CHECK(i2c_master_bus_add_device(BusHandle0, &ClockConfig, &iClockHandle));
  87.  
  88.   SHTConfig.dev_addr_length = I2C_ADDR_BIT_LEN_7;
  89.   SHTConfig.device_address = SHT40_ADDR;
  90.   SHTConfig.scl_speed_hz = MASTER_FREQUENCY;
  91.   ESP_ERROR_CHECK(i2c_master_bus_add_device(BusHandle1, &SHTConfig, &iSHTHandle));
  92.  
  93.   uint8_t rb[7] = {0};
  94.  
  95.   // Echtzeituhr einschalten
  96.   gpio_set_level(SWITCH_BRIDGE_AND_CLOCK, 1);
  97.   vTaskDelay(pdMS_TO_TICKS(1));
  98.  
  99. #define DS3231_ADDR_TIME 0x00
  100.  
  101.   for (int i = 0; i < 5; i++)
  102.   {
  103.     // DS3231
  104.     uint8_t RegAddr=0x00;
  105.     ESP_ERROR_CHECK(i2c_master_transmit_receive(iClockHandle, &RegAddr, 1, rb, 7, DEV_TIMEOUT));
  106.     ESP_LOGI("DS3231:", "%x %x %x %x %x %x %x", rb[0], rb[1], rb[2], rb[3], rb[4], rb[5], rb[6]);
  107.     vTaskDelay(pdMS_TO_TICKS(1000));
  108.   }
  109.  
  110.   DS3231 Uhr;
  111.  
  112.   SHT40 Thermo;
  113.   ESP_ERROR_CHECK(Thermo.Init(BusHandle1, SHT40_ADDR, MASTER_FREQUENCY));
  114.   float MyTemp, MyHum;
  115.   bool CRCErr;
  116.   for (;;)
  117.   {
  118.     ESP_ERROR_CHECK(Thermo.Read(MyTemp, MyHum, CRCErr));
  119.     ESP_LOGI("TEMP:", "%.2f°C", MyTemp);
  120.     vTaskDelay(pdMS_TO_TICKS(1000));
  121.   }
  122. }
  123.  
  124. SHT40::SHT40()
  125. {
  126.   mDevHandle = NULL;
  127.   mBusHandle = NULL;
  128. }
  129.  
  130. esp_err_t SHT40::Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz)
  131. {
  132.   mBusHandle = aBusHandle;
  133.   i2c_device_config_t conf={};
  134.   conf.dev_addr_length = I2C_ADDR_BIT_LEN_7;
  135.   conf.device_address = aI2CAddr;
  136.   conf.scl_speed_hz = aI2CSpeed_Hz;
  137.   conf.scl_wait_us = 1000000;
  138.   return i2c_master_bus_add_device(mBusHandle, &conf, &mDevHandle);
  139. }
  140.  
  141. SHT40::~SHT40(void)
  142. {
  143.   if (mDevHandle != NULL)
  144.     i2c_master_bus_rm_device(mDevHandle);
  145. }
  146.  
  147. // SHT40-Sensor auslesen
  148. esp_err_t SHT40::Read(float &aTemp, float &aHum, bool &rCRC_Err)
  149. {
  150.   int ret;
  151.   rCRC_Err = false;
  152.   uint8_t mode = 0xFD;
  153.   ret = i2c_master_transmit(mDevHandle, &mode, 1, DEV_TIMEOUT);
  154.   if (ret != ESP_OK)
  155.   {
  156.     ESP_LOGE("SHT40::Read", "I2C error no.: %d", ret);
  157.     return ret;
  158.   }
  159.   int iWaitTime_ms = 200;
  160.  
  161.   vTaskDelay(iWaitTime_ms / portTICK_PERIOD_MS);
  162.   // Belegung Datenblock in bytes:
  163.   // Temperatur_high, Temperatur_low, Temperatur_crc, Luftfeuchte_high, Luftfeuchte_low, Luftfeuchte_crc
  164.   uint8_t rb[6] = {0};
  165.   ret = i2c_master_receive(mDevHandle, rb, 6, DEV_TIMEOUT);
  166.   if (ret != ESP_OK)
  167.   {
  168.     ESP_LOGE("SHT40::Read", "I2C error no.: %d", ret);
  169.     return ret;
  170.   }
  171.   aTemp = -45 + 175 * (double)(rb[0] * 256 + rb[1]) / 65535.0;
  172.   aHum = -6 + 125 * (double)(rb[3] * 256 + rb[4]) / 65535.0;
  173.   return ret;
  174. }
  175.  
  176. DS3231::DS3231()
  177. {
  178.   mDevHandle = NULL;
  179.   mBusHandle = NULL;
  180. }
  181.  
  182. DS3231::~DS3231(void)
  183. {
  184.   if (mDevHandle != NULL)
  185.     i2c_master_bus_rm_device(mDevHandle);
  186. }
  187.  
  188. esp_err_t DS3231::Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz)
  189. {
  190.   mBusHandle = aBusHandle;
  191.   if (aBusHandle == NULL)
  192.     return ESP_ERR_INVALID_ARG;
  193.   i2c_device_config_t conf={};
  194.   conf.dev_addr_length = I2C_ADDR_BIT_LEN_7;
  195.   conf.device_address = aI2CAddr;
  196.   conf.scl_speed_hz = aI2CSpeed_Hz;
  197.   return i2c_master_bus_add_device(mBusHandle, &conf, &mDevHandle);
  198. }
  199.  
  200. esp_err_t DS3231::WriteReg(uint8_t aReg, uint8_t *aWriteBuf, uint8_t aWriteSize)
  201. {
  202.   if (mDevHandle == NULL)
  203.     return ESP_ERR_INVALID_ARG;
  204.   esp_err_t ret;
  205.   uint8_t *WriteData = new uint8_t[aWriteSize + 1];
  206.   WriteData[0] = aReg;
  207.   memcpy(WriteData + 1, aWriteBuf, aWriteSize);
  208.   // Die Register der Uhr beschreiben sich recht langsam. 100 ms Timeout sind da zu wenig!
  209.   ret = i2c_master_transmit(mDevHandle, WriteData, aWriteSize + 1, 1000);
  210.   delete[] WriteData;
  211.   if (ret != ESP_OK)
  212.     ESP_LOGE("DS3231::WriteRegister", "I2C error no.: %d", ret);
  213.   return ret;
  214. }
  215.  
  216. esp_err_t DS3231::ReadReg(uint8_t aReg, uint8_t *aReadBuf, uint8_t aReadSize)
  217. {
  218.   if (mDevHandle == NULL)
  219.     return ESP_ERR_INVALID_ARG;
  220.   esp_err_t ret;
  221.   uint8_t RegAddr[1] = {aReg};
  222.   ret = i2c_master_transmit_receive(mDevHandle, RegAddr, 1, aReadBuf, aReadSize, DEV_TIMEOUT);
  223.   // uint8_t RegAddr=aReg;
  224.   // ret = i2c_master_transmit_receive(mDevHandle, &RegAddr, 1, aReadBuf, aReadSize, DEV_TIMEOUT);
  225.   if (ret != ESP_OK)
  226.     ESP_LOGE("DS3231::ReadRegister", "I2C error no.: %d", ret);
  227.  
  228.   return ret;
  229. }
  230.  
  231. esp_err_t DS3231::GetTime(struct tm *time)
  232. {
  233.   uint8_t data[7];
  234.  
  235.   /* read time */
  236.   ESP_LOGI("DS3231", "Start Reading 7 I2C bytes...");
  237.   esp_err_t res = ReadReg(0x00, data, 7);
  238.   if (res != ESP_OK)
  239.     return res;
  240.   ESP_LOGI("DS3231", "Read 7 I2C bytes!");
  241.  
  242.   return ESP_OK;
  243. }
main.h
  1. #ifndef __MAIN_H__
  2. #define __MAIN_H__
  3.  
  4. #include "driver/i2c_master.h"
  5.  
  6. class SHT40
  7. {
  8. private:
  9.   i2c_master_bus_handle_t mBusHandle;
  10.   i2c_master_dev_handle_t mDevHandle;
  11.   uint8_t mReadMode;
  12.  
  13. public:
  14.   SHT40();
  15.   ~SHT40(void);
  16.   esp_err_t Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz);
  17.   esp_err_t Read(float &aTemp, float &aHum, bool &rCRC_Err);
  18. };
  19.  
  20. class DS3231
  21. {
  22. private:
  23.   i2c_master_bus_handle_t mBusHandle;
  24.   i2c_master_dev_handle_t mDevHandle;
  25.  
  26.   esp_err_t WriteReg(uint8_t aReg, uint8_t *aWriteBuf, uint8_t aWriteSize);
  27.   esp_err_t ReadReg(uint8_t aReg, uint8_t *aReadBuf, uint8_t aReadSize);
  28.  
  29. public:
  30.   DS3231();
  31.   esp_err_t Init(i2c_master_bus_handle_t aBusHandle, uint8_t aI2CAddr, uint32_t aI2CSpeed_Hz);
  32.   ~DS3231(void);
  33.  
  34.   esp_err_t GetTime(struct tm *time);
  35. };
  36.  
  37. #endif
ESP32 monitor output:
  1. I (26) boot: ESP-IDF v5.4 2nd stage bootloader
  2. I (26) boot: compile time Jan 31 2025 15:07:40
  3. I (26) boot: Multicore bootloader
  4. I (27) boot: chip revision: v0.1
  5. I (29) boot: efuse block revision: v1.2
  6. I (33) boot.esp32s3: Boot SPI Speed : 80MHz
  7. I (36) boot.esp32s3: SPI Mode       : DIO
  8. I (40) boot.esp32s3: SPI Flash Size : 16MB
  9. I (44) boot: Enabling RNG early entropy source...
  10. I (49) boot: Partition Table:
  11. I (51) boot: ## Label            Usage          Type ST Offset   Length
  12. I (57) boot:  0 nvs              WiFi data        01 02 00009000 00006000
  13. I (64) boot:  1 phy_init         RF data          01 01 0000f000 00001000
  14. I (70) boot:  2 factory          factory app      00 00 00010000 00100000
  15. I (77) boot: End of partition table
  16. I (80) esp_image: segment 0: paddr=00010020 vaddr=3c020020 size=0bbf0h ( 48112) map
  17. I (96) esp_image: segment 1: paddr=0001bc18 vaddr=3fc93b00 size=02e64h ( 11876) load
  18. I (99) esp_image: segment 2: paddr=0001ea84 vaddr=40374000 size=01594h (  5524) load
  19. I (104) esp_image: segment 3: paddr=00020020 vaddr=42000020 size=1c360h (115552) map
  20. I (130) esp_image: segment 4: paddr=0003c388 vaddr=40375594 size=0e4e4h ( 58596) load
  21. I (144) esp_image: segment 5: paddr=0004a874 vaddr=600fe100 size=0001ch (    28) load
  22. I (150) boot: Loaded app from partition at offset 0x10000
  23. I (150) boot: Disabling RNG early entropy source...
  24. I (161) octal_psram: vendor id    : 0x0d (AP)
  25. I (161) octal_psram: dev id       : 0x02 (generation 3)
  26. I (162) octal_psram: density      : 0x03 (64 Mbit)
  27. I (164) octal_psram: good-die     : 0x01 (Pass)
  28. I (168) octal_psram: Latency      : 0x01 (Fixed)
  29. I (172) octal_psram: VCC          : 0x01 (3V)
  30. I (176) octal_psram: SRF          : 0x01 (Fast Refresh)
  31. I (181) octal_psram: BurstType    : 0x01 (Hybrid Wrap)
  32. I (186) octal_psram: BurstLen     : 0x01 (32 Byte)
  33. I (191) octal_psram: Readlatency  : 0x02 (10 cycles@Fixed)
  34. I (196) octal_psram: DriveStrength: 0x00 (1/1)
  35. I (201) MSPI Timing: PSRAM timing tuning index: 4
  36. I (204) esp_psram: Found 8MB PSRAM device
  37. I (208) esp_psram: Speed: 80MHz
  38. I (211) cpu_start: Multicore app
  39. I (640) esp_psram: SPI SRAM memory test OK
  40. I (649) cpu_start: Pro cpu start user code
  41. I (649) cpu_start: cpu freq: 160000000 Hz
  42. I (649) app_init: Application information:
  43. I (649) app_init: Project name:     i2c_IDF_5_4
  44. I (653) app_init: App version:      1
  45. I (657) app_init: Compile time:     Jan 31 2025 15:07:21
  46. I (662) app_init: ELF file SHA256:  9f604b8ae...
  47. I (666) app_init: ESP-IDF:          v5.4
  48. I (670) efuse_init: Min chip rev:     v0.0
  49. I (674) efuse_init: Max chip rev:     v0.99
  50. I (678) efuse_init: Chip rev:         v0.1
  51. I (681) heap_init: Initializing. RAM available for dynamic allocation:
  52. I (688) heap_init: At 3FC972C8 len 00052448 (329 KiB): RAM
  53. I (693) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
  54. I (698) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
  55. I (703) heap_init: At 600FE11C len 00001ECC (7 KiB): RTCRAM
  56. I (709) esp_psram: Adding pool of 8192K of PSRAM memory to heap allocator
  57. I (716) spi_flash: detected chip: gd
  58. I (718) spi_flash: flash io: dio
  59. I (721) sleep_gpio: Configure to isolate all GPIO pins in sleep state
  60. I (728) sleep_gpio: Enable automatic switching of GPIO sleep configuration
  61. I (735) main_task: Started on CPU0
  62. I (738) esp_psram: Reserving pool of 32K of internal memory for DMA/internal allocations
  63. I (746) main_task: Calling app_main()
  64. I (749) gpio: GPIO[10]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
  65. I (758) gpio: GPIO[17]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
  66. Guru Meditation Error: Core  0 panic'ed (Interrupt wdt timeout on CPU0).
  67.  
  68. Core  0 register dump:
  69. PC      : 0x4037bf9d  PS      : 0x00060034  A0      : 0x8037b8dd  A1      : 0x3fc94b90
  70. --- Error: ClearCommError failed (PermissionError(13, 'Das Gerät erkennt den Befehl nicht.', None, 22))
  71. --- Waiting for the device to reconnect--- 0x4037bf9d: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:183
  72.  (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501
  73.  
  74. A2      : 0x3c030da8  A3      : 0xffffffff  A4      : 0x00000000  A5      : 0x00060023
  75. A6      : 0x00000000  A7      : 0x0000cdcd  A8      : 0x3fc96f14  A9      : 0x00000002
  76. A10     : 0x00000000  A11     : 0xb33fffff  A12     : 0x0000cdcd  A13     : 0x00060023
  77. A14     : 0x00000003  A15     : 0x0000cdcd  SAR     : 0x00000016  EXCCAUSE: 0x00000005
  78. EXCVADDR: 0x00000000  LBEG    : 0x40056f5c  LEND    : 0x40056f72  LCOUNT  : 0xffffffff
  79. --- 0x40056f5c: memcpy in ROM
  80. 0x40056f72: memcpy in ROM
  81.  
  82. Core  0 was running in ISR context:
  83. EPC1    : 0x4201a61f  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x4037bf9d
  84. --- 0x4201a61f: uart_hal_write_txfifo at C:/Espressif/idf/v5.4/esp-idf/components/hal/uart_hal_iram.c:27
  85. 0x4037bf9d: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:183
  86.  (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501
  87.  
  88.  
  89.  
  90. Backtrace: 0x4037bf9a:0x3fc94b90 0x4037b8da:0x3fc94bb0 0x403785fe:0x3fc94bd0 0x4037672d:0x3fc94c10 0x40377401:0x3fc94c30 0x400559dd:0x3fc9aa70 0x4037c01e:0x3fc9aa80 0x4037ba75:0x3fc9aaa0 0x4200e0b5:0x3fc9aae0 0x4200e2ec:0x3fc9ab10 0x4200e3ce:0x3fc9ab50 0x4200f1df:0x3fc9ab80 0x4200a042:0x3fc9ac10 0x4200a13f:0x3fc9ad10 0x4201bbb3:0x3fc9ad30 0x4037bc85:0x3fc9ad60
  91. .--- 0x4037bf9a: spinlock_release at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/include/spinlock.h:181 (discriminator 1)
  92.  (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:501 (discriminator 1)
  93. 0x4037b8da: xQueueGenericSendFromISR at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1339
  94. 0x403785fe: i2c_master_isr_handler_default at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:704
  95. 0x4037672d: shared_intr_isr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/intr_alloc.c:445
  96. 0x40377401: _xt_lowint1 at C:/Espressif/idf/v5.4/esp-idf/components/xtensa/xtensa_vectors.S:1240
  97. 0x400559dd: _xtos_set_intlevel in ROM
  98. 0x4037c01e: vPortClearInterruptMaskFromISR at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h:560
  99.  (inlined by) vPortExitCritical at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:514
  100. 0x4037ba75: xQueueReceive at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/queue.c:1632
  101. 0x4200e0b5: s_i2c_send_commands at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:513
  102. 0x4200e2ec: s_i2c_transaction_start at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:625
  103. 0x4200e3ce: s_i2c_synchronous_transaction at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:918
  104. 0x4200f1df: i2c_master_transmit_receive at C:/Espressif/idf/v5.4/esp-idf/components/esp_driver_i2c/i2c_master.c:1214
  105. 0x4200a042: app_main_cpp() at D:/usr/esp/i2c_IDF_5_4/main/main.cpp:105
  106. 0x4200a13f: app_main at D:/usr/esp/i2c_IDF_5_4/main/main.cpp:40
  107. 0x4201bbb3: main_task at C:/Espressif/idf/v5.4/esp-idf/components/freertos/app_startup.c:208
  108. 0x4037bc85: vPortTaskWrapper at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
  109.  
  110.  
  111.  
  112. Core  1 register dump:
  113. PC      : 0x403788fa  PS      : 0x00060734  A0      : 0x82002c89  A1      : 0x3fc9bbc0
  114. --- 0x403788fa: esp_cpu_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/cpu.c:64
  115.  
  116. A2      : 0x00000000  A3      : 0x00000000  A4      : 0x3fc98a00  A5      : 0x3fc989e0
  117. A6      : 0x40375fec  A7      : 0x00000001  A8      : 0x8200c8ae  A9      : 0x3fc9bb80
  118. --- 0x40375fec: ipc_task at C:/Espressif/idf/v5.4/esp-idf/components/esp_system/esp_ipc.c:53
  119.  
  120. A10     : 0x00000000  A11     : 0x00000000  A12     : 0x3fc989e0  A13     : 0x3fc989c0
  121. A14     : 0x00000001  A15     : 0x3fc9bd94  SAR     : 0x00000000  EXCCAUSE: 0x00000005
  122. EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000
  123.  
  124.  
  125. Backtrace: 0x403788f7:0x3fc9bbc0 0x42002c86:0x3fc9bbe0 0x4037cbb1:0x3fc9bc00 0x4037bc85:0x3fc9bc20
  126. .--- 0x403788f7: xt_utils_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/xtensa/include/xt_utils.h:82
  127.  (inlined by) esp_cpu_wait_for_intr at C:/Espressif/idf/v5.4/esp-idf/components/esp_hw_support/cpu.c:55
  128. 0x42002c86: esp_vApplicationIdleHook at C:/Espressif/idf/v5.4/esp-idf/components/esp_system/freertos_hooks.c:58
  129. 0x4037cbb1: prvIdleTask at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:4353 (discriminator 1)
  130. 0x4037bc85: vPortTaskWrapper at C:/Espressif/idf/v5.4/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139
  131.  
  132. ELF file SHA256: 9f604b8ae
  133.  
  134. Rebooting...
Attachments
i2c_IDF_5_4.7z
(18.29 KiB) Downloaded 72 times

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

Re: Strange I2C driver panic while using IDF 5.4 with C++

Postby ESP_Sprite » Sat Feb 01, 2025 12:29 am

Hm. One thing I see is that you don't zero-initialize SHTConfig and ClockConfig, like you do with all other stack-allocated structs. But I'm not sure how that would cause the symptoms you see. I do agree with you that this strongly smells of a memory corruption issue, but none of your code jumps out on me as a probable cause.

MicroController
Posts: 1992
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Strange I2C driver panic while using IDF 5.4 with C++

Postby MicroController » Sat Feb 01, 2025 12:44 pm

ULP_User wrote:
Fri Jan 31, 2025 2:48 pm
at line 110 in main.cpp: Commenting out the unused class "DS3231 Uhr" will lead to a working program again.
Uhr is a local variable and as such allocated on the stack. Memory corruption may be the result of the stack overflowing. Try increasing the main task's stack size via menuconfig.

ULP_User
Posts: 5
Joined: Thu Jun 13, 2024 8:04 am

Re: Strange I2C driver panic while using IDF 5.4 with C++

Postby ULP_User » Sat Feb 01, 2025 5:12 pm

Hi,

it makes no difference if I'm zeroing the configs. In my classes, I always do that, it's only in the test code.
An no, there's no stack overflow! As I already wrote, increasing the stack (tried up to 64 KB) makes no difference. And all the stack overflow test code shows no problems at all.
As you can see in the classes, there's nothing allocated at all at the stack, especially nothing static.
Please keep in mind, that the code is crashing BEFORE the class DS3231 is instanciated! And keep in mind, that the IDF5.2.3 is just running fine, so I don't see where in this code should be a problem.
It looks like compiling the DS3231 class is enough to run in trouble. If so, this would be a serious problem of the IDF5.4.
I'd really like to see the error in one of my code lines, but I can't.

Bye,
Oliver

ULP_User
Posts: 5
Joined: Thu Jun 13, 2024 8:04 am

Re: Strange I2C driver panic while using IDF 5.4 with C++

Postby ULP_User » Tue Feb 04, 2025 4:34 pm

So, after some more testing I answer myself:

The problem in my posted example was indeed the zeroing of the configs. Doing that makes the example run again. I think the problem are the uninitialized timeout values here, which are not checked in the driver code (which is OK for me).

The problem in my (larger) data logger program was different but lead to the same driver behavior:
To save battery energy, the program uses the RISC-V ULP processor to measures sensors data. Every minute or so it wakes up the TX7-cores but then the I2C-communication failed.
The solution was to use "ulp_riscv_gpio_deinit" with the SDA and SCL lines on the end of the ULP program. Strange enough, this was not necessary with IDF 5.2.3.
Not de-initializing the I2C-pins after the ULP has done its work will lead to a non-working I2C driver, even a bus reset does not help then.

Tricky, but fortunately my program is running fine again on IDF 5.4.

Bye,
Oliver

Who is online

Users browsing this forum: No registered users and 58 guests