Comments (13)
Two things immediately stand out to me...
- Check stack usage, as you're allocating a buffer on the stack you might exhaust available stack space.
- You subtract block size from numBlocks, which is counter-intuitive given the variable name; check you actually use it correctly or make sure it is always aligned to block size otherwise you WILL miss your loop condition and loop forever as numBlocks is unsigned. Also see you use MIN when calling MemoryWriteBlock but not when subtracting.
from chameleonminidesfirestack.
i dunno, try printing out the arguments you're passing and see if they make any sense at all? then capture bus traffic and see if that provides any insight?
from chameleonminidesfirestack.
Have you tried to change the BASISTR ISR to maybe blink a led or something like that? It could help you to determine wether it's a stack corruption issue or due to never reaching the loop exit condition.
from chameleonminidesfirestack.
I don't think that's possible. Those macro are expanded by the preprocessor at compile time, given the ISR will be called at unexpected times it does not seem possible to me to access those values
from chameleonminidesfirestack.
@dev-zzo
Yes, you are right about the variable naming being off for the third parameter above. Must have not had enough coffee, or been staring at too much code, when I wrote that down. I should have enough space on the stack for 32
bytes, but not necessarily much more, which is why I'm looping over the FRAM space to initialize things only this minimally small size at a time. The idea is to initialize a chunk of allocated FRAm real estate to a constant byte value across the space (analogous to the standard C-string function memset
).
The function name is indicative of what it should be doing. Based on my read of the function MemoryWriteBlock
and what it calls to write the FRAM in Memory.c
I think that subtracting the block size is still correct usage since that function should be the number of bytes to write.
Now that you mention it, I am usually writing block-wise jagged data. So the issue is probably the subtraction without a check for unsigned arithmetic over/underflow. Thank you for pointing that out. It really helps to have a second set of eyes on the code! My proposed fix is as follows:
void MemsetBlockBytes(uint8_t initValue, SIZET startBlock, SIZET byteCount) {
BYTE fillerBuf[DESFIRE_EEPROM_BLOCK_SIZE];
memset(fillerBuf, initValue, DESFIRE_EEPROM_BLOCK_SIZE);
SIZET writeAddr = startBlock * DESFIRE_EEPROM_BLOCK_SIZE;
while(byteCount > 0) {
MemoryWriteBlock(fillerBuf, writeAddr, MIN(DESFIRE_EEPROM_BLOCK_SIZE, byteCount));
writeAddr += DESFIRE_EEPROM_BLOCK_SIZE / sizeof(SIZET);
if(byteCount > DESFIRE_EEPROM_BLOCK_SIZE) {
byteCount -= DESFIRE_EEPROM_BLOCK_SIZE;
}
else {
break;
}
}
}
I will try testing this out later when I circle back to the firmware project and testing.
from chameleonminidesfirestack.
I changed the implementation to the following:
/* TODO: Why doesn't this work ??? -- It freezes the AVR chip when run !! */
void MemsetBlockBytes(uint8_t initValue, SIZET startBlock, SIZET byteCount) {
BYTE fillerBuf[DESFIRE_EEPROM_BLOCK_SIZE];
memset(fillerBuf, initValue, DESFIRE_EEPROM_BLOCK_SIZE);
SIZET writeAddr = startBlock;
while(byteCount > 0) {
WriteBlockBytes(fillerBuf, writeAddr, MIN(DESFIRE_EEPROM_BLOCK_SIZE, byteCount));
++writeAddr;
if(byteCount > DESFIRE_EEPROM_BLOCK_SIZE) {
byteCount -= DESFIRE_EEPROM_BLOCK_SIZE;
}
else {
break;
}
}
}
It still doesn't seem to be initializing things in FRAM correctly ...
from chameleonminidesfirestack.
I thought it might be something weird with the uint16_t
addresses not providing full 32-bit addresses into the FRAM. Using block sizes of 16
just confuses things and causes other unexpected side effects. I thought you might have some suggestions. In your original code the ReadBlockBytes
and WriteBlockBytes
refer to EEPROM's number of bytes per block. Based on my inspection of the Memory.c
code, it is now FRAM that can get stored back into FLASH from time to time. Maybe somethings have changed in the firmware since that code was written?
from chameleonminidesfirestack.
I also do not know how to fix this. Pretty much stuck for a while. This only seems to be relevant when writing and initializing the file system commands. Everywhere else in the code, this seems to be working correctly based on preliminary testing.
from chameleonminidesfirestack.
@ceres-c
I didn't know about that debugging option. I will have to try it out if problems persist in the code. My tests today suggest that making the change from 32
byte block sizes to 16
byte block sizes when addressing the data written out to FRAM (as I mentioned above for a possible cause), seems to fix the problems I was having. Thanks for the suggestion. I will keep it in mind.
from chameleonminidesfirestack.
@ceres-c
Do you know how to save state for the __LINE__/__FILE__/__func__
macros that are current just before jumping into the BASISTR ISR
? That would be very helpful to figure out if resetting the block size to 16
for FRAM memory reads/writes actually works. There seems to be very little documentation on the search engines about this.
from chameleonminidesfirestack.
@ceres-c
I guess that makes sense. If you have to stash a copy of those values for every roughly "atomic chunk" of code that gets run to see what is crashing things, the firmware will probably just thrash most of the time even when it is working well. This goes back to my very much wanting to have a gdb
-like interface and set breakpoints, etc. to figure out problems.
Just FYI, the reason I asked about something like this is that when I have debugged some of the DESFire related memory routines with my CMLD app, there is a need to store the (say), __LINE__
and __FILE__
associated with the call to WriteBlockBytes
. Otherwise, with all of the calls to that function, you get no meaningful output just knowing that an exceptional case happened. For example, something like the following macro setup works well in that instance:
void WriteBlockBytesMain(const void *Buffer, SIZET StartBlock, SIZET Count);
#define WriteBlockBytes(Buffer, StartBlock, Count) ({ \
snprintf_P(__InternalStringBuffer2, DATA_BUFFER_SIZE_SMALL, \
PSTR("%s @ %d"), __func__, __LINE__); \
__InternalStringBuffer2[DATA_BUFFER_SIZE_SMALL - 1] = '\0'; \
WriteBlockBytesMain(Buffer, StartBlock, Count); \
})
from chameleonminidesfirestack.
I guess you could use a global string, update it accordingly everywhere you need it and print in the BADISTR ISR. But I'm not sure you'd be able to, since, once you land there, the stack is toast and you probably lost the USB altogether...
from chameleonminidesfirestack.
@ceres-c
Hmm. So there's not a way to have the compiler detect that a violation or bad memory access has happened and give the error handling functions a chance to react without obliterating the stack?
I was reading some documentation about avr-gcc
compiler flags. It looks like they have the standard, non-embedded memory protection options -fsanitize=address
(see this doc). I don't know how this would get handled with an AVR that does not easily print or SEGFAULT out to console. I have used these debugging flags before in PC-Linux/Mac software. The behavior there is to exit with a detailed warning and stack trace to the offending line of code printed to the console.
from chameleonminidesfirestack.
Related Issues (9)
- Use crypto hardware acceleration HOT 6
- Firmware currently stuck in the anti collision loop HOT 3
- Libnfc compatible NFC readers for testing the firmware DESFire support HOT 1
- Clarifying tone on international copyright law (users be free) HOT 1
- Hardware compatibility ? HOT 7
- First official DESFire testing binaries available HOT 2
- Chameleon terminal commands not reporting full tag contents HOT 1
- Help and suggestions wanted: DES and 3DES encryption from AVRCryptoLibrary is slow! HOT 9
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from chameleonminidesfirestack.