SPRAD28 October 2022 AM2431 , AM2432 , AM2434 , AM2631 , AM2631-Q1 , AM2632 , AM2632-Q1 , AM2634 , AM2634-Q1 , AM263P4 , AM263P4-Q1 , AM26C31 , AM26C31-EP , AM26C31M , AM26C32 , AM26C32-EP , AM26C32C , AM26C32M , AM26LS31 , AM26LS31M , AM26LS32A , AM26LS32AC , AM26LS32AM , AM26LS33A , AM26LS33A-SP , AM26LS33AM , AM26LV31 , AM26LV31E , AM26LV31E-EP , AM26LV32 , AM26LV32E , AM26LV32E-EP , AM26S10 , AM2732 , AM2732-Q1
You can also simulate a different UsageFault exception of invalid state (UFSR = 0x2). This fault means that the processor has attempted to execute an instruction that makes illegal use of the Execution Program Status Register (EPSR).
When the INVSTATE bit of the UFSR is set, the PC value stacked for the exception return points to the instruction that attempted the illegal use of the EPSR. Potential reasons:
The LSB of the address is loaded to the 'T' bit of the EPSR. If this bit is set, it means that the processor is in Thumb mode, if this bit is cleared, it means that the processor is in Arm mode. Since Arm Cortex M Series support only Thumb ISA, then this bit must be set during execution. This is something that is done by the compiler, but if you assign an address manually to the PC, then you need to take care of this bit by ourselves.
The code below causes the processor to halt in the UsageFault handler, but this time with UFSR = 0x2 (Invalid State):
void empty_main(void *args)
{
/* Open drivers to open the UART driver for console */
Drivers_open();
Board_driversOpen();
//Enable all configurable exceptions:
uint32_t *pSHCSR = (uint32_t*)0xE000ED24;
*pSHCSR |= ( 1<< 16); //Memory Manage Fault
*pSHCSR |= ( 1<< 17); //Bus Fault
*pSHCSR |= ( 1<< 18); //Usage Fault
//Address LSB = 0
uint32_t* pADDR = (uint32_t*)0x00030000;
*pADDR = 0xFFFFFFFF;
void (*temp_address) (void);
temp_address = pADDR;
temp_address();
while(1);
Board_driversClose();
Drivers_close();
}