espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.52k stars 7.39k forks source link

I2C fails after upgrading to Arduino v2.0.2 #6674

Closed ivancmz closed 2 years ago

ivancmz commented 2 years ago

Board

Custom board ESP32

Device Description

Not relevant

Hardware Configuration

Not relevant

Version

v2.0.2

IDE Name

PlatformIO

Operating System

Windows 10

Flash frequency

40

PSRAM enabled

no

Upload speed

115200

Description

Just upgraded a working project from platform-espressif32 v3.2.1 to 4.2.0 (Arduino v2.0.2) and the fw wont even start. See error below related to I2C lock.

ELF file SHA256: 0000000000000000

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:0x3fff0030,len:1184
load:0x40078000,len:12776
load:0x40080400,len:3032
entry 0x400805e4
[     3][E][Wire.cpp:319] beginTransmission(): could not acquire lock
[     3][E][esp32-hal-i2c.c:142] i2cWrite(): could not acquire lock

assert failed: xQueueGenericSend queue.c:820 (pxQueue)

Backtrace:0x40083ce5:0x3ffe39000x4008d061:0x3ffe3920 0x40092651:0x3ffe3940 0x4008daba:0x3ffe3a70 0x400ff2e5:0x3ffe3ab0 0x400ff499:0x3ffe3ad0 0x400e8119:0x3ffe3af0 0x400e79fe:0x3ffe3b20 0x400e7e20:0x3ffe3b40 0x400e349b:0x3ffe3bb0 0x400e360e:0x3ffe3bd0 0x400ede39:0x3ffe3bf0 0x4011e20b:0x3ffe3c10 0x400833fe:0x3ffe3c40 0x400791f2:0x3ffe3c90  |<-CORRUPTED
  #0  0x40083ce5:0x3ffe39000 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:402

I removed the I2C initialization and calls and the firmware starts working again, so it's confirmed that the issue is on I2C.

I also tryed disabling the locks by adding -DCONFIG_DISABLE_HAL_LOCKS to platformio.ini but now it won't compile:

Compiling .pio\build\esp32release\FrameworkArduino\esp32-hal-ledc.c.o
C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c: In function 'i2cSlaveDeinit':
C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c:363:12: error: 'i2c_slave_struct_t' {aka 'struct i2c_slave_struct_t'} has no member named 'lock'
     if(!i2c->lock){
            ^~
C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c: In function 'i2cSlaveWrite':
C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c:380:12: error: 'i2c_slave_struct_t' {aka 'struct i2c_slave_struct_t'} has no member named 'lock'
     if(!i2c->lock){
            ^~
Compiling .pio\build\esp32release\FrameworkArduino\esp32-hal-matrix.c.o
*** [.pio\build\esp32release\FrameworkArduino\esp32-hal-i2c-slave.c.o] Error 1

Sketch

Wire.begin(22, 23,10000L);

bool I2C::Write(uint8_t slaveId, uint8_t address, uint8_t value) {
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    Wire.write(value);
    return Wire.endTransmission() == I2C_OK;
}

Debug Message

ELF file SHA256: 0000000000000000

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:0x3fff0030,len:1184
load:0x40078000,len:12776
load:0x40080400,len:3032
entry 0x400805e4
[     3][E][Wire.cpp:319] beginTransmission(): could not acquire lock
[     3][E][esp32-hal-i2c.c:142] i2cWrite(): could not acquire lock

assert failed: xQueueGenericSend queue.c:820 (pxQueue)

Backtrace:0x40083ce5:0x3ffe39000x4008d061:0x3ffe3920 0x40092651:0x3ffe3940 0x4008daba:0x3ffe3a70 0x400ff2e5:0x3ffe3ab0 0x400ff499:0x3ffe3ad0 0x400e8119:0x3ffe3af0 0x400e79fe:0x3ffe3b20 0x400e7e20:0x3ffe3b40 0x400e349b:0x3ffe3bb0 0x400e360e:0x3ffe3bd0 0x400ede39:0x3ffe3bf0 0x4011e20b:0x3ffe3c10 0x400833fe:0x3ffe3c40 0x400791f2:0x3ffe3c90  |<-CORRUPTED
  #0  0x40083ce5:0x3ffe39000 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:402


### Other Steps to Reproduce

I also tryed with v4.1.0 and the error is the same as in v4.2.0, so the problem might also be present in Arduino v2.0.1.
I also tryed with v3.5.0 and it works again.

### I have checked existing issues, online documentation and the Troubleshooting Guide

- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.
podaen commented 2 years ago

You have a backtrace... Any information on that with the exeption decoder?

SuGlider commented 2 years ago

@ivancmz - Based on the compilation errors you have reported, I think that it is is more likely an error of configuration of PlatformIO.

Does the exactly same code work fine using Arduino IDE environment?

Based on @ivankravets commentaries in the last Arduino Community Meeting of last week, PlatformIO for the Arduino Core 2.0.2 shall be released soon.

I guess that as soon as PIO releases the latest version, this issue will be solved.

ivankravets commented 2 years ago

Hi, guys,

Glad to inform you that the latest version of the ESP32 dev-platform is out with support for Arduino core for ESP32 v.2.0.2. Please update your local development platform.

More information at https://piolabs.com/blog/news/platformio-oss-april-2022-updates.html

SuGlider commented 2 years ago

@ivancmz - Please let me know if with the latest PIO Core version 5.2.5 this issue can be closed. Thanks!

i164j9 commented 2 years ago

I updated platformio yesterday, and all of the libraries I use, now i2c fails to work, where it worked before the updates were applied. Working with Esp32 wroom 32

Everything compiles and works fine in the Arduino ide. According to my scope the clock line is not running, after using Arduino ide it's operating as expected.

SuGlider commented 2 years ago

@i164j9

Maybe reinstalling PlatformIO may solve this problem with it...

If not, please open an issue at their GitHub.

Jason2866 commented 2 years ago

I make a bet there are left overs from old versions in the Platformio setup. Delete the hidden folder .platformio and .cache

ivankravets commented 2 years ago

@i164j9, could you run pio upgrade --dev, navigate to the project folder, and type pio pkg list. Please provide a list of project packages.

i164j9 commented 2 years ago

i ran the upgrade and pio pkg list: Resolving esp32doit-devkit-v1 environment packages... Platform espressif32 @ 4.2.0 (required: espressif32) ├── framework-arduinoespressif32 @ 3.20002.0 (required: platformio/framework-arduinoespressif32 @ ~3.20002.0) ├── tool-esptoolpy @ 1.30300.0 (required: platformio/tool-esptoolpy @ ~1.30300.0) ├── tool-mkfatfs @ 2.0.1 (required: platformio/tool-mkfatfs @ ~2.0.0) ├── tool-mklittlefs @ 1.203.210628 (required: platformio/tool-mklittlefs @ ~1.203.0) ├── tool-mkspiffs @ 2.230.0 (required: platformio/tool-mkspiffs @ ~2.230.0) ├── tool-openocd-esp32 @ 2.1100.20220411 (required: platformio/tool-openocd-esp32 @ ~2.1100.0) └── toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch3 (required: espressif/toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch3)

in addition to that i use the MPU6050 library by jeff rowberg https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

Tested with the dev version. Same result when the code executes it hangs in the mpu6050 library in the initialize() and does not go any further than the first line in the method setClockSource()

As mentioned earlier it compiles and runs fine with the Arduino ide, I am going to blow away the installation and start fresh to see what happens.

blew away the installation of platformio and vscode and still no change uninstalled pio, then vscode went back into .appdata deleted all remaining folders as well as .platformio and .cache reinstalled...

maybe i missed something, but nothing changed. still compiles and uploads but no clock output. Arduino IDE(1.8.19, 1.8.13). works

ivankravets commented 2 years ago

Thanks for the provided information. If the same simple project works with Arduino IDE and does not work with PlatfomIO, we should investigate it on our side. We've just reopened https://github.com/platformio/platform-espressif32/issues/786 . Please subscribe to that issue.

atanisoft commented 2 years ago

@ivancmz Are you by any chance using multiple threads (tasks) and concurrently accessing the Wire library from them at the same time?

If you could also decode the backtrace you have provided, there is a PR over on platform-espressif32 that may help fix the backtrace decoding within PIO (@ivankravets it would be great to include the fix as it appears PIO monitor is responsible for dropping spaces).

i164j9 commented 2 years ago

I don't have multiple threads, and I have no backtrace. There is no crash happening. It just halts. It's not hardware I have tested across 5 boards with the same configuration and get the same results. My first thought was hardware, then I thought I hosed my code... Went through and disabled all my new code. Still nothing worked. So I created a new project with new hardware and implemented minimal code to run a gyro (MPU6050, GY-521) and even that didn't work So I pulled the silly scope out and behold the surprise of no clock output, so I moved through 4 brand new boards, and two other development boards with the same result. Then moved on to testing with the Arduino IDE and life was good again. So I started thinking about what I had done. I thought about the updates I applied yesterday, everything worked fine before and now I have failure. So now, the only logical source of the issue is the software update. Only thing that changed that makes any sense to me.

ivancmz commented 2 years ago

@ivancmz - Please let me know if with the latest PIO Core version 5.2.5 this issue can be closed. Thanks!

I'm sorry I haven't been able to work on this. I'm gonna try it today. Is there any way I can backup my PIO Core/configuration and everything before updating so I can go back in case of a problem?

cdluv commented 2 years ago

info

I've had some issues too over the past week - I2C was working fine, then after some casual auto updates of platform io upgrading, I ended up venturing into a black hole of assuming it was my fault - which is pretty shit when you have years of experience and really want to get to the bottom of what went wrong.

I2C code to speak to MPU6050 is definately f*cked.... I2C scanning works, but can't send data to it.... Just freezes on requesting data.

Tried different ESP32's and different MPU6050's - Houston, we have a problem. Added some debug out to the libraries, to see where it was going wrong.

My test debug log:

Key: BT=begin txn WR = write, ET=end txn, RF= request from.... freeze!

sda=21, scl=22

MPU6050 init Wire@3ffc13d8, I2C (0x68) reading 1 bytes from 0x6B...readBytes: len=1, BT, WR, ET, BT, RF, FREEZE

I2C scan sees device as 0x68...

Used a scope to test SDA and SCL - they seem okay -- and besides, how can the I2C scan see the device?? Really weird.

For anyone else who has similar issues, I found these issues that helped me figure out the resolution:

https://github.com/espressif/arduino-esp32/issues/6674 https://community.platformio.org/t/change-arduino-esp32-core-version/24593 https://github.com/platformio/platform-espressif32/issues/786

The bottom line:

Upgrade PIO to the latest dev version:

pio upgrade --dev

Then change platformio.ini

platform = espressif32@3.4.0

cdluv commented 2 years ago

@i164j9, could you run pio upgrade --dev, navigate to the project folder, and type pio pkg list. Please provide a list of project packages.

I can confirm this works, providing you add to your platform.ini: platform = espressif32@3.4.0

I hope it helps others - I have been baffled for a week (not full-time on it, but elapsed)

i164j9 commented 2 years ago

I can confirm that changing platform.ini Platform = espressif32@3.4.0 Does make my boards come back to life too.

Aside from the platform upgrades and such maybe I am mis understanding but it sounds like the issue lies with the MPU6050 library that's being used?

I am lacking the experience but slowly learning and maybe one day I'll get gdb to play nice and be able to dive deeper into issues like these.

Thank you for the resolution / workaround for this.

Jason2866 commented 2 years ago

@cdluv @i164j9 By doing this you are using old Arduino Core 1.0.6.

me-no-dev commented 2 years ago

@cdluv the problem is probably wrong use of Wire API in the library for MPU6050. I2C works fine, but requires code to be sane. Unfortunately we found out that some libraries out there do not conform to the official API and cause issue on newer Arduino cores.

cdluv commented 2 years ago

@cdluv the problem is probably wrong use of Wire API in the library for MPU6050. I2C works fine, but requires code to be sane. Unfortunately we found out that some libraries out there do not conform to the official API and cause issue on newer Arduino cores.

I'm using a DFRobot FireBeetle with a Wroom-32U ... that doesn't sound new to me?

The library was written by Jeff Rowberg - it's been around for years - any suggestions on what causes this issue, and I'll contribute towards a fix.

It worked before, on older hardware. Don't understand what changed.

atanisoft commented 2 years ago

DFRobot FireBeetle with a Wroom-32U ... that doesn't sound new to me?

It's not the ESP32 that is a problem here, it is the library that implements the MPU6050 interaction.

The library was written by Jeff Rowberg

Can you share a link to the specific library? It is very likely a simple coding bug in the library where it is not checking return codes which may indicate a failure condition.

cdluv commented 2 years ago

I debugged the library - the error was when waiting for data to come back. The library is i2cdev.cpp (v 0.5.0)

This is the line that caused my ESP32 to hang:

            Wire.requestFrom(devAddr, (uint8_t)(length * 2)); //

length=words, this wants bytes

For context:

        // Arduino v1.0.1+, Wire library
        // Adds official support for repeated start condition, yay!

        // I2C/TWI subsystem uses internal buffer that breaks with

large data requests // so if user requests more than BUFFER_LENGTH bytes, we have to do it in // smaller chunks instead of all at once for (uint8_t k = 0; k < length 2; k += min(length 2, BUFFER_LENGTH)) { Wire.beginTransmission(devAddr); Wire.write(regAddr); Wire.endTransmission(); Wire.beginTransmission(devAddr); Wire.requestFrom(devAddr, (uint8_t)(length * 2)); // length=words, this wants bytes ** HANGS HERE *****

            bool msb = true; // starts with MSB, then LSB
            for (; Wire.available() && count < length && (timeout == 0

|| millis() - t1 < timeout);) { if (msb) { // first byte is bits 15-8 (MSb=15) data[count] = Wire.read() << 8; } else { // second byte is bits 7-0 (LSb=0) data[count] |= Wire.read();

ifdef I2CDEV_SERIAL_DEBUG

                        Serial.print(data[count], HEX);
                        if (count + 1 < length) Serial.print(" ");
                    #endif
                    count++;
                }
                msb = !msb;
            }

            Wire.endTransmission();
        }

On Tue, 10 May 2022 at 14:11, Mike Dunston @.***> wrote:

DFRobot FireBeetle with a Wroom-32U ... that doesn't sound new to me?

It's not the ESP32 that is a problem here, it is the library that implements the MPU6050 interaction.

The library was written by Jeff Rowberg

Can you share a link to the specific library? It is very likely a simple coding bug in the library where it is not checking return codes which may indicate a failure condition.

— Reply to this email directly, view it on GitHub https://github.com/espressif/arduino-esp32/issues/6674#issuecomment-1122370438, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA534DWO334HPDPYULVW4M3VJJOBPANCNFSM5UZ3FAFQ . You are receiving this because you were mentioned.Message ID: @.***>

cdluv commented 2 years ago

Can you share a link to the specific library? It is very likely a simple coding bug in the library where it is not checking return codes which may indicate a failure condition.

Sure, it's this one: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

atanisoft commented 2 years ago

Try commenting out Wire.beginTransmission(devAddr);. It is very likely hanging due to this invalid usage pattern which is very common across libraries. The call to Wire.endTransmission(); should also be adjusted to Wire.endTransmission(false);.

A better implementation would look closer to: https://github.com/kriswiner/MPU6050/blob/master/MPU6050Library/MPU6050.cpp#L372-L375. This doesn't have a lot of error checking in it but it should also work on the ESP32 correctly.

cdluv commented 2 years ago

Awesome! It worked! There were a couple of places which needed fixing up, but yeah, thanks for highlighting that! I'll push up a PR to fix that library shortly.

On Tue, 10 May 2022 at 14:36, Mike Dunston @.***> wrote:

Try commenting out Wire.beginTransmission(devAddr);. It is very likely hanging due to this invalid usage pattern which is very common across libraries. The call to Wire.endTransmission(); should also be adjusted to Wire.endTransmission(false);.

A better implementation would look closer to: https://github.com/kriswiner/MPU6050/blob/master/MPU6050Library/MPU6050.cpp#L372-L375. This doesn't have a lot of error checking in it but it should also work on the ESP32 correctly.

— Reply to this email directly, view it on GitHub https://github.com/espressif/arduino-esp32/issues/6674#issuecomment-1122406524, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA534DUPSRPNYCCZ4MTJ2G3VJJQ7JANCNFSM5UZ3FAFQ . You are receiving this because you were mentioned.Message ID: @.***>

atanisoft commented 2 years ago

Great, glad that it was a relatively simple fix. This is just one example of an invalid usage pattern that has been exposed by tightening the validations as part of migrating to ESP-IDF I2C APIs. There are likely going to be more.

me-no-dev commented 2 years ago

The problem is that many libraries have code like the one below, which is invalid. Wire.beginTransmission and Wire.endTransmission should be used only for Wire.write and never for Wire.requestFrom

// Invalid Code
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.requestFrom(addr, 2);
Wire.read();
Wire.endTransmission();

// Valid Code
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(addr, 2);
Wire.read();
Jason2866 commented 2 years ago

@atanisoft @me-no-dev Sadly there are many bad (wrong) i2c librarys "in the wild" out there. We had to fix some we use for Tasmota too. For some we wondered the ever worked...

me-no-dev commented 2 years ago

@Jason2866 sadly that is the case and we are the first to end up having to deal with it. Somebody eventually had to, if we are to stick to that API and work in multithreaded environment. Hopefully it will all come to pass soon.

SuGlider commented 2 years ago

Guys, this discussion is way far from the original issue open by @ivancmz. Please open a new one, or a new discussion about I2C libraries, in case you have found something new.

SuGlider commented 2 years ago

@ivancmz - Please let me know if with the latest PIO Core version 5.2.5 this issue can be closed. Thanks!

I'm sorry I haven't been able to work on this. I'm gonna try it today. Is there any way I can backup my PIO Core/configuration and everything before updating so I can go back in case of a problem?

@Jason2866 or anyone else - can you help on it?

Jason2866 commented 2 years ago

@ivancmz - Please let me know if with the latest PIO Core version 5.2.5 this issue can be closed. Thanks!

I'm sorry I haven't been able to work on this. I'm gonna try it today. Is there any way I can backup my PIO Core/configuration and everything before updating so I can go back in case of a problem?

@Jason2866 or anyone else - can you help on it?

Yes, when using setting platform = espressif32 @ 3.2.1 Platformio installs everything which is needed for this platform version (core, toolchains...)

wgaylord commented 2 years ago

I am currently having an issue where I can not compile after upgrading to the latest PlatformIO version of the ESP32 platform.

I am also getting

C:/Users/chibi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c: In function 'i2cSlaveDeinit':
C:/Users/chibi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c:363:12: error: 'i2c_slave_struct_t' {aka 'struct i2c_slave_struct_t'} has no member named 'lock'
     if(!i2c->lock){
            ^~
C:/Users/chibi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c: In function 'i2cSlaveWrite':
C:/Users/chibi/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c-slave.c:380:12: error: 'i2c_slave_struct_t' {aka 'struct i2c_slave_struct_t'} has no member named 'lock'
     if(!i2c->lock){

While I attempt to compile. Was a solution found other then using the older version of the plugin?

me-no-dev commented 2 years ago

@wgaylord something is not updated, because that code no longer exists here (where you are getting compilation errors)

atanisoft commented 2 years ago

The if(!i2c->lock){ failure was present in 2.0.2 which is what PlatformIO provides as one of it's latest versions. This is only a problem if you disable CONFIG_DISABLE_HAL_LOCKS in sdkconfig. @me-no-dev this config parameter needs to be reworked/reworded as a lot of people disable it thinking it is a good option to disable when in fact it may do the exact opposite.

me-no-dev commented 2 years ago

@atanisoft with the latest release it will not error if you disable hal locks. Code referenced above is old.

atanisoft commented 2 years ago

@atanisoft with the latest release it will not error if you disable hal locks. Code referenced above is old.

Right, it last existed in 2.0.2 which PlatformIO is packaging in their version 4.2.0 (latest tagged release). The only workarounds would be not to disable that flag or override the arduino-esp32 version picked up to 2.0.3 via platformio.ini.

ivancmz commented 2 years ago

Did update and upgrade:

PS C:\proyecto\x> pio upgrade
You're up-to-date!
PlatformIO 5.2.5 is currently the newest version available.
PS C:\proyecto\x> pio update
Updating platformio/contrib-piohome           3.4.1 @ ~3.4.1                     [Up-to-date]
Updating platformio/tool-scons                4.40300.1 @ ~4.40300.0             [Up-to-date]

Platform Manager
================
Platform espressif32
--------
Updating platformio/espressif32               4.2.0                              [Up-to-date]
Updating espressif/toolchain-xtensa-esp32     8.4.0+2021r2-patch3 @ 8.4.0+2021r2-patch3[Up-to-date]
Updating platformio/framework-arduinoespressif32 3.20002.0 @ ~3.20002.0             [Updating to 3.20002.220503]
Tool Manager: Installing platformio/framework-arduinoespressif32 @ 3.20002.220503
Downloading  [####################################]  100%
Unpacking  [####################################]  100%
Tool Manager: framework-arduinoespressif32 @ 3.20002.220503 has been installed!
Tool Manager: Removing framework-arduinoespressif32 @ 3.20002.0
Tool Manager: framework-arduinoespressif32 @ 3.20002.0 has been removed!
Updating platformio/tool-esptoolpy            1.30300.0 @ ~1.30300.0             [Up-to-date]
Updating platformio/tool-mkspiffs             2.230.0 @ ~2.230.0                 [Up-to-date]
Updating platformio/tool-mklittlefs           1.203.210628 @ ~1.203.0            [Up-to-date]
Updating platformio/tool-mkfatfs              2.0.1 @ ~2.0.0                     [Up-to-date]

Platform espressif32
--------
Updating platformio/espressif32               3.1.0                              [Detached]
Updating platformio/toolchain-xtensa32        2.50200.97 @ ~2.50200.0            [Up-to-date]
Updating platformio/framework-arduinoespressif32 3.10005.210308 @ ~3.10005.0        [Up-to-date]Updating platformio/tool-esptoolpy            1.30000.201119 @ ~1.30000.0        [Up-to-date]
Updating platformio/tool-mkspiffs             2.230.0 @ ~2.230.0                 [Up-to-date]

Platform espressif32
--------
Updating platformio/espressif32               3.2.1                              [Detached]
Updating platformio/toolchain-xtensa32        2.50200.97 @ ~2.50200.0            [Up-to-date]
Updating platformio/framework-arduinoespressif32 3.10006.210326 @ ~3.10006.0        [Up-to-date]Updating platformio/tool-esptoolpy            1.30000.201119 @ ~1.30000.0        [Up-to-date]
Updating platformio/tool-mkspiffs             2.230.0 @ ~2.230.0                 [Up-to-date]

Platform espressif32
--------
Updating platformio/espressif32               3.5.0                              [Detached]
Updating platformio/toolchain-xtensa32        2.50200.97 @ ~2.50200.0            [Up-to-date]
Updating platformio/framework-arduinoespressif32 3.10006.210326 @ ~3.10006.0        [Up-to-date]Updating platformio/tool-esptoolpy            1.30100.210531 @ ~1.30100.0        [Up-to-date]   
Updating platformio/tool-mkspiffs             2.230.0 @ ~2.230.0                 [Up-to-date]   

Platform espressif32
--------
Updating platformio/espressif32               4.1.0                              [Detached]     
Updating espressif/toolchain-xtensa-esp32     8.4.0+2021r2-patch3 @ 8.4.0+2021r2-patch3[Up-to-date]
Updating platformio/framework-arduinoespressif32 3.20001.0 @ ~3.20001.0             [Up-to-date]Updating platformio/tool-esptoolpy            1.30100.210531 @ ~1.30100.0        [Up-to-date]   
Updating platformio/tool-mkspiffs             2.230.0 @ ~2.230.0                 [Up-to-date]   
Updating platformio/tool-mklittlefs           1.203.210628 @ ~1.203.0            [Up-to-date]   
Updating platformio/tool-mkfatfs              2.0.1 @ ~2.0.0                     [Up-to-date]   

Library Manager
===============
Library Storage: C:\Users\x\.platformio\lib

The issue is still there:

rst:0x1 (POWERON_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:0x3fff0030,len:1184
load:0x40078000,len:12776
load:0x40080400,len:3032
entry 0x400805e4
[     3][E][Wire.cpp:319] beginTransmission(): could not acquire lock
[     3][E][esp32-hal-i2c.c:142] i2cWrite(): could not acquire lock

assert failed: xQueueGenericSend queue.c:820 (pxQueue)

Backtrace:0x40083ce5:0x3ffe38900x4008d095:0x3ffe38b0 0x40092685:0x3ffe38d0 0x4008daee:0x3ffe3a00 0x40100f61:0x3ffe3a40 0x40101115:0x3ffe3a60 0x400e820d:0x3ffe3a80 0x400e7af2:0x3ffe3ab0 0x400e7f14:0x3ffe3ad0 0x400e7e7f:0x3ffe3b40 0x400e356f:0x3ffe3bb0 0x400e36e2:0x3ffe3bd0 0x400efab5:0x3ffe3bf0 0x4011ff1b:0x3ffe3c10 0x400833fe:0x3ffe3c40 0x400791f2:0x3ffe3c90  |<-CORRUPTED
  #0  0x40083ce5:0x3ffe38900 in panic_abort at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/panic.c:402

ELF file SHA256: 0000000000000000

I've also checked out I2C library and corrected it as indicated by @me-no-dev (and tested it with platform-espressif32 v3.5.0) so this is not the cause either:

bool I2C::Read(uint8_t slaveId, uint8_t size, uint8_t buffer[]) {
    Wire.beginTransmission(slaveId);
    Wire.endTransmission();
    //Wire.beginTransmission(slaveId); //remmoved this as indicated by @me-no-dev
    Wire.requestFrom(slaveId, size);
    for(uint8_t i = 0; i < size && Wire.available(); i++)
        buffer[i] = Wire.read();
    return Wire.endTransmission() == I2C_OK;
}
ivancmz commented 2 years ago

I have managed to decode the backtrace:

c:\proyecto\x>xtensa-esp32-elf-addr2line -pfiaC -e .pio\build\esp32release\firmware.elf Backtrace:0x40083ce5:0x3ffe39000x4008d095:0x3ffe3920 0x40092685:0x3ffe3940 0x4008daee:0x3ffe3a70 0x40100f61:0x3ffe3ab0 0x40101115:0x3ffe3ad0 0x400e820d:0x3ffe3af0 0x400e7af2:0x3ffe3b20 0x400e7f14:0x3ffe3b40 0x400e356f:0x3ffe3bb0 0x400e36e2:0x3ffe3bd0 0x400efab5:0x3ffe3bf0 0x4011ff1b:0x3ffe3c10 0x400833fe:0x3ffe3c40 0x400791f2:0x3ffe3c90
0x00000bac: ?? ??:0
0x40092685: __assert_func at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/assert.c:85
0x4008daee: xQueueGenericSend at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:821 (discriminator 2)
0x40100f61: TwoWire::endTransmission(bool) at C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src/Wire.cpp:339
0x40101115: TwoWire::endTransmission() at C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src/Wire.cpp:503
0x400e820d: I2C::Read(unsigned char, unsigned char, unsigned char, unsigned char*) at C:\proyecto\x/src/models/infraestructure/I2C.cpp:53
0x400e7af2: ClockService::ReadClock(unsigned char, unsigned char, unsigned char*) at C:\proyecto\x/src/models/infraestructure/ClockService.cpp:412
0x400e7f14: ClockService::Update() at C:\proyecto\x/src/models/infraestructure/ClockService.cpp:290
0x400e356f: GlobalDaily::GlobalDaily() at C:\proyecto\x/src/models/GlobalDaily.cpp:8
0x400e36e2: GlobalStatus::GlobalStatus() at C:\proyecto\x/src/models/GlobalStatus.cpp:3
0x400efab5: _GLOBAL__sub_I__ZN12ServerUpload5loginE at C:\proyecto\x/include/models/utils/Singleton.h:35
 (inlined by) __static_initialization_and_destruction_0 at C:\proyecto\x/src/server/ServerUpload.cpp:157
 (inlined by) __static_initialization_and_destruction_0 at C:\proyecto\x/src/server/ServerUpload.cpp:280
 (inlined by) _GLOBAL__sub_I__ZN12ServerUpload5loginE at C:\proyecto\x/src/server/ServerUpload.cpp:280
0x4011ff1b: do_global_ctors at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/startup.c:185
 (inlined by) start_cpu0_default at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/startup.c:404
0x400833fe: call_start_cpu0 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/port/cpu_start.c:632
0x400791f2: ?? ??:0

This is the supposed offending code (I2C.cpp:53):

bool I2C::Read(uint8_t slaveId, uint8_t address, uint8_t size, uint8_t buffer[]) {
    uint8_t i = 0;
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    if(Wire.endTransmission()==0) // THIS IS LINE 53!
    {
        Wire.requestFrom(slaveId, size);
        for(; i < size && Wire.available(); i++)
            buffer[i] = Wire.read();
    }
    return (i==size);
}

Any suggestions?

me-no-dev commented 2 years ago

That is actually the code that is executed after whatever other code did not use Wire properly. In your previous message you see in the logs that Wire was not able to acquire the lock, so naturally was not able to later release it (and that caused the exception+backtrace). What else is using Wire on your code? Maybe missing Wire.endTransmission() somewhere?

ivancmz commented 2 years ago

That particular function is missing the Wire.endTransmission()... I have added it, and checked all the rest, but still no progress. This is the only class that uses Wire:

#include <models/infraestructure/I2C.h>

I2C::I2C() {
    if(!Wire.begin(22, 23,10000L))
    {
        Serial.println("Could not start I2C");
    }
}

I2C::~I2C() {
    Wire.end();
}

bool I2C::Write(uint8_t slaveId, uint8_t value) {
    Wire.beginTransmission(slaveId);
    Wire.write(value);
    return (Wire.endTransmission() == I2C_OK);
}

bool I2C::Write(uint8_t slaveId, uint8_t address, uint8_t value) {
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    Wire.write(value);
    return (Wire.endTransmission() == I2C_OK);
}

bool I2C::WriteArray(uint8_t slaveId, uint8_t size, uint8_t values[]) {
    Wire.beginTransmission(slaveId);
    for(uint8_t i = 0; i < size; i++)
        Wire.write(values[i]);
    return (Wire.endTransmission() == I2C_OK);
}

bool I2C::WriteArray(uint8_t slaveId, uint8_t address, uint8_t size, uint8_t values[]) {
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    for(uint8_t i = 0; i < size; i++)
        Wire.write(values[i]);
    return (Wire.endTransmission() == I2C_OK);
}

bool I2C::Read(uint8_t slaveId, uint8_t size, uint8_t buffer[]) {
    Wire.beginTransmission(slaveId);
    Wire.endTransmission();
    //Wire.beginTransmission(slaveId); //remmoved this as indicated by @me-no-dev
    Wire.requestFrom(slaveId, size);
    for(uint8_t i = 0; i < size && Wire.available(); i++)
        buffer[i] = Wire.read();
    /* Checking the return value of the `endTransmission()` function. */
    return (Wire.endTransmission() == I2C_OK);
}

bool I2C::Read(uint8_t slaveId, uint8_t address, uint8_t size, uint8_t buffer[]) {
    uint8_t i = 0;
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    if(Wire.endTransmission()==0)
    {
        Wire.requestFrom(slaveId, size);
        for(; i < size && Wire.available(); i++)
            buffer[i] = Wire.read();
    }
    return (Wire.endTransmission() == I2C_OK) && (i==size); // Adding this endTransmission() here make my reads fail on v3.5.0
}

Testing in v3.5.0 to make sure I haven't broken anything and that last Wire.endTransmission() does make the reads from the RTC fail.

me-no-dev commented 2 years ago

Your read functions are wrong. They need to be:

bool I2C::Read(uint8_t slaveId, uint8_t size, uint8_t buffer[]) {
    size_t res = Wire.requestFrom(slaveId, size);
    if(res == 0)
        return false;
    for(uint8_t i = 0; i < size && Wire.available(); i++)
        buffer[i] = Wire.read();
    return res == size;
}

bool I2C::Read(uint8_t slaveId, uint8_t address, uint8_t size, uint8_t buffer[]) {
    uint8_t i = 0;
    size_t res = 0;
    Wire.beginTransmission(slaveId);
    Wire.write(address);
    if(Wire.endTransmission()==0)
    {
        res = Wire.requestFrom(slaveId, size);
        if(res == 0)
            return false;
        for(; i < size && Wire.available(); i++)
            buffer[i] = Wire.read();
    }
    return res == size;
}
ivancmz commented 2 years ago

Your read functions are wrong. They need to be:

Thanks @me-no-dev, I've made the changes and tested it in v3.5.0, it worked fine, so I went back to try v4.2.0, but it keeps failing.

On the same line where if(Wire.endTransmission()==0)

xtensa-esp32-elf-addr2line -pfiaC -e .pio\build\esp32release\firmware.elf Backtrace:0x40083ce5:0x3ffe39100x4008d095:0x3ffe3930 0x40092685:0x3ffe3950 0x4008daee:0x3ffe3a80 0x40101449:0x3ffe3ac0 0x401015fd:0x3ffe3ae0 0x400e8503:0x3ffe3b00 0x400e7dda:0x3ffe3b20 0x400e81fc:0x3ffe3b40 0x400e3857:0x3ffe3bb0 0x400e39ca:0x3ffe3bd0 0x400eff11:0x3ffe3bf0 0x40120413:0x3ffe3c10 0x400833fe:0x3ffe3c40 0x400791f2:0x3ffe3c90
0x00000bac: ?? ??:0
0x40092685: __assert_func at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/assert.c:85
0x4008daee: xQueueGenericSend at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/queue.c:821 (discriminator 2)
0x40101449: TwoWire::endTransmission(bool) at C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src/Wire.cpp:339
0x401015fd: TwoWire::endTransmission() at C:/Users/imarquez/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src/Wire.cpp:503
0x400e8503: I2C::Read(unsigned char, unsigned char, unsigned char, unsigned char*) at C:\proyecto\edesna.xeptareef.autobalance/src/models/infraestructure/I2C.cpp:78
0x400e7dda: ClockService::ReadClock(unsigned char, unsigned char, unsigned char*) at C:\proyecto\edesna.xeptareef.autobalance/src/models/infraestructure/ClockService.cpp:412
0x400e81fc: ClockService::Update() at C:\proyecto\edesna.xeptareef.autobalance/src/models/infraestructure/ClockService.cpp:290
0x400e3857: GlobalDaily::GlobalDaily() at C:\proyecto\edesna.xeptareef.autobalance/src/models/GlobalDaily.cpp:8
0x400e39ca: GlobalStatus::GlobalStatus() at C:\proyecto\edesna.xeptareef.autobalance/src/models/GlobalStatus.cpp:3
0x400eff11: _GLOBAL__sub_I__ZN12ServerUpload5loginE at C:\proyecto\edesna.xeptareef.autobalance/include/models/utils/Singleton.h:35
 (inlined by) __static_initialization_and_destruction_0 at C:\proyecto\edesna.xeptareef.autobalance/src/server/ServerUpload.cpp:157
 (inlined by) __static_initialization_and_destruction_0 at C:\proyecto\edesna.xeptareef.autobalance/src/server/ServerUpload.cpp:280
 (inlined by) _GLOBAL__sub_I__ZN12ServerUpload5loginE at C:\proyecto\edesna.xeptareef.autobalance/src/server/ServerUpload.cpp:280
0x40120413: do_global_ctors at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/startup.c:185
 (inlined by) start_cpu0_default at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/startup.c:404
0x400833fe: call_start_cpu0 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/port/cpu_start.c:632
me-no-dev commented 2 years ago

huh? the code above is good (with the changes I gave you). There is no reason for this to happen.

uhmm... Wire.begin() should never be called in a constructor of a class, unless you instantiate it later by new. I think that you are having a whole another issue. I see in the trace that it starts from call_start_cpu0 and then goest to do_global_ctors which then means that you are calling Wire class functions in the global scope. There is a coding error in your sketch.

ivancmz commented 2 years ago

I think that you are having a whole another issue.

Yeah, this whole project is a mess...

uhmm... Wire.begin() should never be called in a constructor of a class, unless you instantiate it later by new.

I modified some of the classes to do a kind of "lazy initialization", and I2C is now working. So I can confirm that the issue had to do with the I2C being initialized on a ctor. Question remains on why did it work fine until now.

I'm seeing now a whole lot of other new issues with WiFi, http server and client.... I'll stick to v3.5.0 for now.

Thanks to @me-no-dev and everyone for your time and effort.

igorlrg commented 2 years ago

The problem is that many libraries have code like the one below, which is invalid. Wire.beginTransmission and Wire.endTransmission should be used only for Wire.write and never for Wire.requestFrom

// Invalid Code
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
Wire.beginTransmission(addr);
Wire.requestFrom(addr, 2);
Wire.read();
Wire.endTransmission();

// Valid Code
Wire.beginTransmission(addr);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(addr, 2);
Wire.read();

This was the issue!!! I fix the code in few places (not all yet) and works! Best tip ever.