I have a real-time embedded app with the major cycle running at 10KHz. It runs on a TI TMS320C configured to boot from flash. I recently added an initialized array to a source file, and all of a sudden the timing is screwed up (in a way too complex to explain well – essentially a serial port write is no longer completing on time.)
The things about this that baffle me:
- I’m not even accessing the new data, just declaring an initialized array.
- It is size dependant – the problem only appears if the array is >40 words.
- I know I’m not overflowing any data segments in the link map.
- There is no data caching, so it’s not due to disrupting cache consistency.
Any ideas on how simply increasing the size of the .cinit segment in flash can affect the timing of your code?
Additional Info:
I considered that maybe the code had moved, but it is well-separated from the data. I verified through the memory map that all the code segements have the same addresses before and after the bug. I also verified that none of the segments are full – The only addresses that change in the map are a handful in the .cinit section. That section contains data values used to initialize variables in ram (like my array). It shouldn’t ever be accessed after main() is called.
After more than a day staring at traces and generated assembly, I think I figured it out. The root cause problem turned out to be an design issue that caused glitches only if the ISR that kicked off the serial port write collided with a higher priority one. The timing just happened to work out that it only took adding a few extra instructions to one loop to cause the two interrupts to collide.
So the question becomes: How does storing, but not accessing, additional data in flash memory cause additional instructions to be executed?
It appears that the answer is related to, but not quite the same as, the suggestions by Frosty and Frederico. The new array does move some existing variables, but not across page boundaries or to slower regions (on this board, access times should be the same for all regions) . But it does change the offsets of some frequently accessed structures, which causes the optimizer to issue slightly different instruction sequences for accessing them. One data alignment may cause a one cycle pipeline stall, where the other does not. And those few instructions shifted timing enough enough to expose the underlying problem.