2019-10-22 09:10 AM
Hi ,
I am coding for STM32F207 for first time so I do not understand Why is STM32F207 processor loading 16 bit thumb instruction where as the Function pointer is 32-bit . is this ((void (*)(void))g_ulTransferAddress)() wrong ?
As per our Project requirement we have 4 different sections of 1MB Flash. All the 4 Different sections of 1MB flash has 4 independent projects.
1. CRC Verifier Project 0x0800_0000 to 0x0800_3FFF
2. Decision Maker Project 0x0800_4000 to 0x0800_7FFF
3. Bootloader Project 0x0800_8000 to 0x0801_FFFF
4. Runtime or Scheduler Project 0x0802_0000 to 0x0810_0000
Decision Marker should be loaded from the CRC verifier for this I am using following code
g_ulTransferAddress=0x0800_4004 ; // RUN Decision maker
((void (*)(void))g_ulTransferAddress)(); // Execute Code with Function Pointer
This is causing an exception as the STM32F207 is switching to 16 bit Thumb instruction mode when the Function Pointer is Invoked .
Where as it should be 32 bit Function pointer to the Decision Maker .
Attached Image shows the same address location of 32 bit function pointer being interpreted as 16 bit thumb instruction .
0x08004000
0x08004004
0x08004008
2019-10-22 09:36 AM
>>I am coding for STM32F207 for first time so I do not understand Why is STM32F207 processor loading 16 bit thumb instruction where as the Function pointer is 32-bit . is this ((void (*)(void))g_ulTransferAddress)() wrong ?
It is loading a 32-bit instruction pointer (PC) from the vector table. The address space is still 32-bit with Thumb, and it is not loading an instruction here. The vector table contains addresses, not instructions. The address it reads should be ODD, designating that the code in 16-bit Thumb
ie 0x08005E4D
Disassemble the code at 0x08005E4C
2019-10-22 09:51 AM
Cortex-M controllers support only Thumb and Thumb2 instruction sets. This has nothing to do with the pointer size, registers are still 32 bits wide.
What you are seeing in both listings are the vector table interpreted as ARM or Thumb instructions, both are nonsense code, because it's a table of addresses, not code. The first element is the initial value for the stack pointer, the second value at 0x08004004 contains the address of the reset handler. Instead of jumping directly to 0x08004004, you should jump to the address stored in the table:
g_ulTransferAddress=*(uint32_t *)0x0800_4004 ; // RUN Decision maker
((void (*)(void))g_ulTransferAddress)(); // Execute Code with Function Pointer
The actual cause of the exception is that the least significant bit of the program counter indicates whether the code should be executed in ARM or Thumb mode. PC&1==0 (your code jumps to an even address) indicates ARM mode, which is not supported by this MCU, that's why it is causing an exception. Had you jumped to an odd address, it would start executing the nonsense code there, possibly causing an exception shortly.