Replies: 10 comments
-
I think that this is almost certainly a bug in the C code.
Changes since 1.5.6
|
Beta Was this translation helpful? Give feedback.
-
Hi SpenceKonde, Thank you very much for your comprehensive reply. Probably you are right, there is a bug in my code somewhere. But it is a tricky one. I noticed an unstable behavior of the sketch a while ago. Strange things appear and disappear without any obvious correlation to the changes I do in the code. This time at least I can control it somehow: it can be reproduced, and a small change makes it disappear. The sketch is not too big:
The sketch HBnode_DD32 is here. However, it would not be so easy to reproduce it by someone else because it employs a custom bootloader with size of 1K. Thus, DxCore "boards.txt" needs to be modified. To upload a compiled sketch to the board one would need a custom programmer with appropriate PC application. Sketch has a monitor connected to a PC hyperterminal via a I2C-to-serial converter FT200XD. It is not a standard converter because I2C in the FT200XD is a slave rather than a master. All together amount of specific hardware is a bit excessive to reproduce. So, I'd rather show my observations. For instance, when I upload a new compiled sketch via HBus, the current sketch stores the new code in a serial EEPROM. The new code is sent to the node in 32-bytes chunks, and the current sketch stores those chunks in EEPROM using the mentioned in my previous post When code is uploaded to EEPROM, the last 8-byte chunk stored in EEPROM at address 0x0010. It is a descriptor. First four byte are a pattern Before writing the last chunk to the EEPROM, sketch checks crc and, if matches, stores descriptor in EEPROM and after a delay resets AVR. At wake-up bootloader checks EEPROM descriptor at address 0x0010. If there is the required pattern there, bootloader copies EEPROM to AVR flash, clears the pattern in the EEPROM and resets. If there is no required pattern there, bootloader passes control to the sketch at address 0x400. After wake-up sketch prints a wake-up message. Monitor command EErd prints content of EEPROM descriptor (address 0x10, length 8 bytes) To be continued in the next post... |
Beta Was this translation helpful? Give feedback.
-
The problem arises when I use the function For the sake of debug, I implemented monitor command But it does not. After executing |
Beta Was this translation helpful? Give feedback.
-
As far as I understand, compiled code should fill registers R20, R22, R23, R24, R25 before calling function
etc But for some reason in the reset function it is drastically different:
|
Beta Was this translation helpful? Give feedback.
-
When I take the local declaration of the
And behavior of the sketch changed too. Now it correctly writes the pattern into EEPROM, but it corrupts displayed addresses: |
Beta Was this translation helpful? Give feedback.
-
I could be wrong, but looking to the listing I conclude that compiler passes parameters to the functions via registers rather than via stack. To the function
in second case (correct pointer)
Where r22 could be cleared? |
Beta Was this translation helpful? Give feedback.
-
Arduino IDE settings as shown
|
Beta Was this translation helpful? Give feedback.
-
Transition to Arduino 1.8.19 and DxCore 1.5.11 did not make any difference. |
Beta Was this translation helpful? Give feedback.
-
I refer you to https://gcc.gnu.org/wiki/avr-gcc#Calling_Convention Whether and which arguments are passed in registers and which are passed on the stack ("in memory") is fully described there. |
Beta Was this translation helpful? Give feedback.
-
Thank you. So far I use the following empirical rules:
|
Beta Was this translation helpful? Give feedback.
-
Hi All,
I use DxCore in a AVR64DD32 project. Project description is here
There is a function to write a buffer into an external I2C EEPROM:
write_EE(uchar* buf, uint addr, uchar len);
It works fine when I call it in all cases except one. In one case when I call this function, it receives NULL instead of pointer buf. My procedure handles NULL pointer in a specific way: it writes 0xFF into EEPROM, this is how I could detect that it was wrong.
Byte array buf in the calling function is local for calling function. If I make it global then my function works correctly. Other calling functions can use the write_EE functions with locally declared buffers, no problems.
So, basically, when I call
write_EE(uchar* buf, uint addr, uchar len);
function from one place in my code, it somehow corrupts pointer. When I call it from other places it works OK.I compile project with Arduino 1.8.6, DxCore 1.5.6.
Beta Was this translation helpful? Give feedback.
All reactions