Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
4 years, 7 months ago.
STM32F746 SVC handler hard fault during boot
Hello,
I have a working STM32F429 Mbed project in IAR. I wanted to create a derived IAR project that uses the STM32F746/756. I felt that this should be easy since the two STM families are fairly similar, and CM4 and CM7 are somewhat similar.
However, something is not right with the RTOS layer in Mbed. During system initialization, svcKernelStart() is called from rtx_kernel.c. During the SVC_Handler code (defined in irq_cm4.S; I found it odd that there is not a specific file for cm7), an MPU exception is escalated to a HardFault.
I have added comments to the code below.
The fault is triggered at the line under SVC_ContextSave: STR R12,[R1,#TCB_SP_OFS] ; Store SP
This code was reached because the prior line: BNE SVC_ContextSwitch
Did not branch to the ContextSwitch label like my F429 code does.
I don't fully understand the internals of the RTX code, and obviously it is quite challenging to debug assembly code for something this complex. At this point, I assume something is mis-configured with my project.
EDIT: Issue resolved. FPU_PRESENT flag not defined on IAR Assembler command line, and FPU not enabled in compiler options.
;/* ; * Copyright (c) 2013-2018 Arm Limited. All rights reserved. ; * ; * SPDX-License-Identifier: Apache-2.0 ; * ; * Licensed under the Apache License, Version 2.0 (the License); you may ; * not use this file except in compliance with the License. ; * You may obtain a copy of the License at ; * ; * www.apache.org/licenses/LICENSE-2.0 ; * ; * Unless required by applicable law or agreed to in writing, software ; * distributed under the License is distributed on an AS IS BASIS, WITHOUT ; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; * See the License for the specific language governing permissions and ; * limitations under the License. ; * ; * ----------------------------------------------------------------------------- ; * ; * Project: CMSIS-RTOS RTX ; * Title: Cortex-M4F Exception handlers ; * ; * ----------------------------------------------------------------------------- ; */ NAME irq_cm4f.s I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset TCB_SP_OFS EQU 56 ; TCB.SP offset TCB_SF_OFS EQU 34 ; TCB.stack_frame offset PRESERVE8 SECTION .rodata:DATA:NOROOT(2) EXPORT irqRtxLib irqRtxLib DCB 0 ; Non weak library reference THUMB SECTION .text:CODE:NOROOT(2) SVC_Handler EXPORT SVC_Handler IMPORT osRtxUserSVC IMPORT osRtxInfo TST LR,#0x04 ; Determine return stack from EXC_RETURN bit 2 ITE EQ MRSEQ R0,MSP ; Get MSP if return stack is MSP MRSNE R0,PSP ; Get PSP if return stack is PSP LDR R1,[R0,#24] ; Load saved PC from stack LDRB R1,[R1,#-2] ; Load SVC number CBNZ R1,SVC_User ; Branch if not SVC 0 PUSH {R0,LR} ; Save SP and EXC_RETURN LDM R0,{R0-R3,R12} ; Load function parameters and address from stack BLX R12 ; Call service function POP {R12,LR} ; Restore SP and EXC_RETURN STM R12,{R0-R1} ; Store function return values SVC_Context LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next CMP R1,R2 ; Check if thread switch is required IT EQ BXEQ LR ; Exit when threads are the same CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted TST LR,#0x10 ; Check if extended stack frame BNE SVC_ContextSwitch #ifdef __FPU_PRESENT LDR R1,=0xE000EF34 ; FPCCR Address LDR R0,[R1] ; Load FPCCR BIC R0,R0,#1 ; Clear LSPACT (Lazy state) STR R0,[R1] ; Store FPCCR B SVC_ContextSwitch ; **************** In working program (F429), this code branches here **************** #endif SVC_ContextSave STMDB R12!,{R4-R11} ; Save R4..R11 #ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VSTMDBEQ R12!,{S16-S31} ; Save VFP S16.S31 #endif STR R12,[R1,#TCB_SP_OFS] ; Store SP ******************MPU -> HardFault happens here ********************** STRB LR, [R1,#TCB_SF_OFS] ; Store stack frame information SVC_ContextSwitch STR R2,[R3] ; osRtxInfo.thread.run: curr = next SVC_ContextRestore LDRB R1,[R2,#TCB_SF_OFS] ; Load stack frame information LDR R0,[R2,#TCB_SP_OFS] ; Load SP ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN #ifdef __FPU_PRESENT TST LR,#0x10 ; Check if extended stack frame IT EQ VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31 #endif LDMIA R0!,{R4-R11} ; Restore R4..R11 MSR PSP,R0 ; Set PSP SVC_Exit BX LR ; Exit from handler SVC_User LDR R2,=osRtxUserSVC ; Load address of SVC table LDR R3,[R2] ; Load SVC maximum number CMP R1,R3 ; Check SVC number range BHI SVC_Exit ; Branch if out of range PUSH {R0,LR} ; Save SP and EXC_RETURN LDR R12,[R2,R1,LSL #2] ; Load address of SVC function LDM R0,{R0-R3} ; Load function parameters from stack BLX R12 ; Call service function POP {R12,LR} ; Restore SP and EXC_RETURN STR R0,[R12] ; Store function return value BX LR ; Return from handler PendSV_Handler EXPORT PendSV_Handler IMPORT osRtxPendSV_Handler PUSH {R0,LR} ; Save EXC_RETURN BL osRtxPendSV_Handler ; Call osRtxPendSV_Handler POP {R0,LR} ; Restore EXC_RETURN MRS R12,PSP B SVC_Context SysTick_Handler EXPORT SysTick_Handler IMPORT osRtxTick_Handler PUSH {R0,LR} ; Save EXC_RETURN BL osRtxTick_Handler ; Call osRtxTick_Handler POP {R0,LR} ; Restore EXC_RETURN MRS R12,PSP B SVC_Context END
I have determined that by forcing the LR to 0xFFFFFFF9 instead of 0xFFFFFFE9 upon entry to the SVC_Handler during kernel start, I can avoid the hard fault and the application appears to run correctly. Based on the comments in irq_cm4.S where my code is failing, it seems that the LR is incorrectly indicating that the processor is NOT operating with an "extended stack frame". I am unsure of why this might be, as I don't know the mechanism behind this setting of the LR. I presume the 0xFFFFFFE9 value is set during the jump to the SVC_Handler ISR and that function is baked into the processor core. Therefore, there must be a configuration issue with my project.
posted by Brendan Simpson 27 Sep 2019