2018-09-11 11:01 PM
I’m trying to write a context switch assembly on STM32F411E but I encounter a usageFault right after I make a second call to the SVC 0 (in my second task) instruction. The funny thing is the first task can make SVC calls just fine but the second task has issues. The logic for the first and second task is the same so not sure what's causing it. I'm thinking maybe my stack management is bad and so the stack becomes corrupted? I have no way or technique for verifying this hypothesis. I have no way of knowing what I am looking at when I do a stack dump, after the fault occurs.
Here are some of the status register values inside the UsageFault handler, after I make a call to SVC 0, in my second task:
CCR = 0x00000218
HFSR = 0x40000000
CFSR = 0x00000000
DFSR = 0x0000000b
BFSR = 0x00000000
BFAR = 0xe000ed38
AFSR = 0x00000000
MMFSR = 0x00000000
MMFAR = 0xe000ed34
Looks like DFSR might provide the biggest clue but I am still not sure what is causing this fault. Has anyone encountered a similar error and can anyone assist me with finding the source of this fault? Why would first call to SVC 0 (in task1) work but the second call to SVC 0 (in task2) fail? It's a bit confusing when CFSR is not telling me what the exact cause of the error because it just reads all zero (CFSR = 0x00000000 ) .
Here’s my context switch code:
/***************************************************
* activate
*
* Description: context switch routine for tasks
*
* Input:
*
* Output:
*
* Return:
*
* Note:
*
*
***************************************************/
activate:
cpsie i
mrs ip, psr
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
ldmfd r0!, {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
msr control, ip
isb
msr psp, r0
/* jump to user task*/
bx lr
/***************************************************
* SVC_Handler
*
* Description:
*
* Input:
*
* Output:
*
* Return:
*
* Note: supervisor call (handler mode)
*
*
***************************************************/
.thumb_func
SVC_Handler:
mrs r0, psp
stmdb r0!, {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
/* load kernel state */
pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
msr psr_nzcvq, ip
/* back to the thread mode if no other active exception */
bx lr
If I can even get some tips about how I can debug this (ie. any useful status registers or techniques ?) that would be appreciated. At this point I don't have enough information about the cause so maybe there is someone out there who understands ARM architecture better than me? I'm relatively new to ARM arch to be honest.
2018-09-16 11:10 PM
bump
2018-09-16 11:38 PM
What is on 0xe000ed38 ?
2018-09-18 07:15 PM
@Community member I'm thinking the default value of BFAR register is 0xE000ED38 since the BFSR bits of CFSR register is all zero (BFSR = 0x00000000). In other words, I think the value at that register address (0xe000ed38) is irrelevant since the CFSR is reading zero for all its bit fields.
What do you think?
2018-09-19 04:12 AM
"The BusFault Address Register contains the address of the location that generated a BusFault. See the register summary in Table 4.12 for its attributes."
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/Cihbhdbc.html
2018-09-19 09:07 PM
@Community member
Table 4.30. BFAR bit assignments
Bits Name Function
[31:0] ADDRESS "When the BFARVALID bit of the BFSR is set to 1, this field holds the address of the location that generated the BusFault"
2018-09-19 09:09 PM
The BFARVALID bit of the BFSR is set to zero so the given address shown by "BFAR" is not a valid address.