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
Be the first to answer this question.