pasko-zh / brzo_i2c

Brzo I2C is a fast I2C Implementation written in Assembly for the esp8266
GNU General Public License v3.0
244 stars 47 forks source link

GCC 10 compilation issue with Arduino #40

Open mcspr opened 4 years ago

mcspr commented 4 years ago

Hey,

ESP8266 Arduino Core project plans to use current version of GCC as default some time soon, but something had changed in compilation process since 4.8.2 and brzo can no longer build.

https://github.com/esp8266/Arduino/pull/6294 https://github.com/earlephilhower/esp-quick-toolchain/releases

I commented on the GCC issue directly in hope it was something noticed during the migration of the Core sources, but it was suggested I should post here. Building using PIatformIO.

xtensa-lx106-elf-gcc -o ".pio/build/d1_mini/lib8be/Brzo I2C_ID335/brzo_i2c.c.o" -c -std=gnu99 -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -Os -mlongcalls -mtext-section-literals -falign-functions=4 -U__STRICT_ANSI__ -ffunction-sections -fdata-sections -fno-exceptions -Wall -DPLATFORMIO=40305 -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_WEMOS_D1MINI -DF_CPU=80000000L -D__ets__ -DICACHE_FLASH -DARDUINO=10805 -DARDUINO_BOARD=\"PLATFORMIO_D1_MINI\" -DFLASHMODE_DIO -DLWIP_OPEN_SRC -DNONOSDK22x_190703=1 -DTCP_MSS=536 -DLWIP_FEATURES=1 -DLWIP_IPV6=0 -DVTABLES_IN_FLASH "-I/home/max/.platformio/lib/Brzo I2C_ID335/src" -I.pio/build/d1_mini/core -I/home/max/.platformio/packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/tools/sdk/include -I/home/max/.platformio/packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/tools/sdk/libc/xtensa-lx106-elf/include -I/home/max/.platformio/packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/cores/esp8266 -I/home/max/.platformio/packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/tools/sdk/lwip2/include -I/home/max/.platformio/packages/framework-arduinoespressif8266@src-31d658a59f41540201fc3726a1394910/variants/d1_mini "/home/max/.platformio/lib/Brzo I2C_ID335/src/brzo_i2c.c"
/home/max/.platformio/lib/Brzo I2C_ID335/src/brzo_i2c.c: In function 'brzo_i2c_write':
/home/max/.platformio/lib/Brzo I2C_ID335/src/brzo_i2c.c:72:2: error: cannot find a register in class 'RL_REGS' while reloading 'asm'
   72 |  asm volatile (
      |  ^~~
/home/max/.platformio/lib/Brzo I2C_ID335/src/brzo_i2c.c:72:2: error: 'asm' operand has impossible constraints
*** [.pio/build/d1_mini/lib8be/Brzo I2C_ID335/brzo_i2c.c.o] Error 1

I also noticed https://github.com/pasko-zh/brzo_i2c/issues/9#issuecomment-246939228, but I have no idea what exactly is missing from flags / defines. ICACHE_RAM_ATTR seems to be there, optimization flags do not change anything.

pasko-zh commented 4 years ago

Hi Max,

Thanks for your support... I am not the GCC expert, so, let me investigate it...

beefeater94 commented 4 years ago

I think the compiler is just running out of registers. ASM blocks in read() and write() use 14 registers. Even with the old compiler, I got the RL_REGS error when I tried to add a 15th. The best fix is to rewrite assembly with fewer registers. For example, error and repeated-start flags can be in RAM without slowing the execution.

pasko-zh commented 4 years ago

@beefeater94 : Well, the point is not that I do not understand what the compiler is saying, i.e. no more registers. However, the question is why this version of GCC behaves differently and which compiler flags cause thise different behaviour compared to older versions. Thus, changing flags comes before changing code ;-)

JimDrewGH commented 3 years ago

You should be able to just save and restore registers in the assembly code and it would not matter how many registers you use as long as the code was single threaded (ie. save registers - run code - restore registers - exit). I have no idea why a compiler would care about register usage - but I am an assembly guy, not a high level language user.

pasko-zh commented 3 years ago

@JimDrewGH Well, with inline assembly you can either choose registers to be used yourself, or you can let the compiler choose them, see here. I have used the latter method.