#include "LPC177x_8x.H" void f1(U8 *ptr); void f2(U8 *ptr); void (*fpTest1[2])(U8 *ptr1)={&f1,&f2}; void (*const fpTest[2])(U8 *ptr1)={&f1,&f2}; U8 b[2][2]={{0,1},{2,3}}; int main(void) { (*fpTest[0])(b[0]); // fpTest[0]=&f2; //(*fpTest[0])(b[0]); (*fpTest[1])(b[1]); } void f1(U8 *ptr) { volatile U8 a=0; volatile U8 b=0; a=*(ptr); b=*(ptr+1); } void f2(U8 *ptr) { volatile U8 a=0; volatile U8 b=0; a=ptr[0]; b=ptr[1]; }
Why does fpTest exist in On-Chip Flash and fpTest1 in SRAM?
It isn't a trick.
And it's irrelevant if the processor has more or less flash compared to RAM.
Initialized RAM must get the initial values from from somewhere - and that somewhere would be the flash in a LPC17xx chip (unless you downloaded the program directly into RAM using a JTAG interface). So if the pointer value is already stored in flash - what reason would it be to make a second copy of the pointer in RAM? Copying the pointer would consume RAM, and it would slow down the boot process since the startup code has four more bytes to copy.
The only cost of having const data in flash is that there might be some extra wait states for the memory access - RAM is normally faster than flash.
In the LPC17xx, the program is run from flash. So keeping const data in the flash is a logical thing to do.
On a PC, the program is run in RAM. So there is no flash to store the pointer in - a running program can't use a pointer stored on the disk. So that is a reason why a PC compiler doesn't do this. But a PC compiler will still separate const variables from non-const variables and keep them in a separate memory segment - const data can be thrown away and reloaded from disk if you run out of RAM. Non-const data needs to be written to a swap file and then later restored from the swap file.
So in the end, both a PC compiler and the Keil compiler will perform the same type of optimization - it's just that the optimization is adapted to the different requirements of the target hardware. So no tricks involved.
Another advantage of keeping const data in write-protected memory, is that a bug in the program can't corrupt the data. And an attempt to type cast away the "const" and assign to the variable will catch this in the form of a memory access error - it is considered a direct error for a program to try to write to a const variable. So a program trying that stunt should be shot on sight.
Thanks.
So even if the const pointer tries to point to an invalid address(address of function not assigned for it to point to) by accident while executing the code from Flash, it will cause an exception ?
Different rules for different processors what memory regions that may produce access violations. It's the memory controller "glue" that decides if a memory region has write protection or both read+write protection or if you are free to both read and write. So the memory controller can allow the program to make read and write accesses even to ranges where there are no memory - it's just depends on what specific processor that is used. And in some cases on what register initializations your program has made.
But besides violations from accessing invalid memory ranges, you can also get exceptions by trying to execute invalid instructions. Which may happen if a pointer points into "air". Or if you get a stack overflow, or the program has problems with memory overwrites. Or maybe there are problems with the memory so you get bit errors.
Note that you do not need to perform any assign to the pointer - the compiler/linker together with the startup code will assign initial values to the pointers. And as long as you don't upload a broken binary to the processor, there will be two functions at the destination addresses for the two pointers.