At the beginning of main I have two variables, namely:
unsigned char audioDataBuffer1[512]; unsigned char audioDataBuffer2[512];
Later in the code I use them as buffers for audio data from SD Card.
The problem is that the stack pointer is set too low and these big variables overwrite my stack pointer which is set automatically by Keil startup code. How is this possible?
I have noticed that the problem disappears when I set above variables to global, or when I use malloc instead.
I would appreciate if you could explain what goes wrong here and is there any reason I should not declare large variables like this?
Thank you.
About the end of main, my friend Chiu has a real story, he personally experienced.
When Chiu was a new guy in a CMMI level 3 qualified company, he got an assignment to study and maintain (temporarily) an already released project. That project was created and modified by many engineers. Chiu was been told that, that device/project has some strange behaviors, such like when the device is waken up from sleep mode, some variables would be destroyed.
Chiu did quite a lot of study to better understand that device/project. He discovered, that project used a third-party software package, which was acquired from the customer legally; and it was a mandatory requirement for project development. The third party had been a jet fighter maker, so their software package has some low level shutdown procedure. (concept only)
Based on their design, when the device has nothing to do, the device exits from the main(), below the main(), it is the low level shutdown procedure, users have to implement their own appropriate functionality, such as to maintain or not to maintain the output signal. After the low level shutdown procedure, the device enters sleep mode. when the device is waken up from sleep mode, it triggers a software reset. (Chiu discovered this design concept from the third-party's example code.)
The customer and third-party also have another mandatory requirement, use FRAM to store important data.
So, my friend, Chiu's understanding is: users have two options. 1. Before the device enters sleep mode, store important data into FRAM, when the device is waken up, it restores important data from FRAM. After that, everything is clean and fresh. 2. The device ignores the low level shutdown procedure; it enters sleep mode within main(), and is waken up from sleep mode within main().
Chiu studied the source code of that project, and discovered that, in this CMMI qualified company, no one knows what is startup code and what is C runtime environment. So the creator and the early engineers of that project, modified whatever they like in the third-party startup code, trying to keep important data from the software reset. However, after the software reset, C runtime environment initials global/static variables. Without leveraging the FRAM, of course they failed. Somehow, they contacted the Chip supplier and got an perfect fix, they then use noinit pragma to protect the important data, so that C runtime environment would not initial the important data.
-- I resigned from my ex-company in April, and joined a very small company in May. Not sure if it is a good place to stay, but there is not much opportunity.