I am trying to read UID value from LPC11xx chip. My code is running ok, until I try to read UID. After that, well after few other things that run on the uC it ends up in HardKernel. I guess stack overflow or something, but I dont see anything wrong in iap call..
#define IAP_ADDRESS 0x1FFF1FF1 struct iap_commands{ enum CMD { eReadUID = 58 }; }; unsigned int param_table[5]; unsigned int result_table[5]; typedef void(*iap)(unsigned int [], unsigned int []); iap iap_entry; void read_serial_num () { iap_entry = (iap)IAP_ADDRESS; param_table[0] = iap_commands::eReadUID; iap_entry (param_table, result_table); }
It is totally same whether I call this function at the beginning of main or at some other place, it would always end up with HardKernel. Same use case but without call of read_serial_num runs fine.
I am not really near the RAM or ROM limit of uC.
I am using C++. Am I missing some extern "C" somewhere ?
Perhaps you should consider clearing the structure or other fields within it first? Leaving it with random junk, or values unusable by the IAP code may cause it to touch memory that it should not.
Are there requirements to use specific RAM areas for the parameters? Is the Hard Fault allowing you to determine what exactly faulted? ie the memory address is was trying to touch and the instructions it was using.
Standard debugging techniques should allow you to determine what is annoying the processor.
Clearing the structure indeed prevented HardKernel. I was thinking that it would take parameters which are needed for each command. Which in my case is none, and rest would be ignored...
Input Command code: 58 (decimal) Status Code CMD_SUCCESS Result Result0: The first 32-bit word (at the lowest address). Result1: The second 32-bit word. Result2: The third 32-bit word. Result3: The fourth 32-bit word. Description This command is used to read the unique ID.
Although I dont receive HardKernel fault now, it seems that my GPIO inputs are not working anymore ?! Of course if I remove call to that function, everything works.
Do I need to "reserve" that IAP memory in the configuration somehow ? Although it is outside the user RAM, so I guess it should be read only anyway.
Actually what happens is that param_table runs over part of memory that is used by one of my objects and that prevents storing the value of gpio to structure. Which gives impression that gpio is not working...
How it is possible that param_table is initialised at already used part of memory ?
My uC should have 8Kb of RAM and I am using 4824 bytes if my calculation is right.
Program Size: Code=11972 RO-data=1720 RW-data=68 ZI-data=3036
Also stack size is defined with size of 0x200. Tried to extend it but without any difference. I dont have any dynamic allocations in the code. Everything bigger is statically allocated and used as ring buffers.
After searching for the problem I noticed that my stack gets overwritten ... Then I found that IAP functions are located in memory that is used by stack and that I need to reserve those last 32 bytes of SRAM for IAP.
How do I configure that in Keil ?
Just shrink the size of the RAM block in the project settings - or in the scatter file, in case you are using a manually created scatter file.