ClassB example hard fault
Monika KUNCOVA
Visitor II
Options
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Email to a Friend
- Printer Friendly Page
- Report Inappropriate Content
on 2020-11-13 3:05 AM
[FAQ][STM32F4]: During debugging ClassB library example is giving me hard-faults. What is the problem?Issue can be caused by corruption of CPU registers that modern compiler produced code uses during run-time. One of the requirements is that each subroutine keeps the content of core registers R4 to R11. Information regarding this issue can be found also in document AN4435 chapter 6.
Testing subroutines for ClassB libraries are located in assembly files (XXX is name of compiler. For example GCC, IAR).
Assembly files need to be modified to store register content at the beginning of test routines and restore the content at the end of test routines.
For memory test (STL_FullRamMarchC routine in stm32fxx_STLRamMcMxXXX.s file) SRAM memory cannot be used as backup location because its content is destroyed during test routine. One of the approaches can be to use some MCU peripheral to store register content. It can be for example DMA controller, because it is present in most of microcontrollers and has enough 32-bit registers. DMA memory address registers can be used for that purpose.
For CPU test(STL_StartUpCPUTest routine in stm32f4xx_STLcpustartXXX.s file) stack or peripheral(DMA) can be used for registry backup.
The registry store process needs to include
Example for STM32F4 family and IAR compiler:
Backing-up the registers in STL_FullRamMarchC procedure in file stm32fxx_STLRamMcMxIAR.s.
Restoring the registers at the end of procedure:
Backing-up the registers in STL_StartUpCPUTest procedure in file stm32l0xx_STLcpustartIAR.s:
Restoring the registers at the end of procedure:
Testing subroutines for ClassB libraries are located in assembly files (XXX is name of compiler. For example GCC, IAR).
- stm32f4xx_STLcpustartXXX.s
- STL_StartUpCPUTest routine
- stm32fxx_STLRamMcMxXXX.s
- STL_FullRamMarchC routine
Assembly files need to be modified to store register content at the beginning of test routines and restore the content at the end of test routines.
For memory test (STL_FullRamMarchC routine in stm32fxx_STLRamMcMxXXX.s file) SRAM memory cannot be used as backup location because its content is destroyed during test routine. One of the approaches can be to use some MCU peripheral to store register content. It can be for example DMA controller, because it is present in most of microcontrollers and has enough 32-bit registers. DMA memory address registers can be used for that purpose.
For CPU test(STL_StartUpCPUTest routine in stm32f4xx_STLcpustartXXX.s file) stack or peripheral(DMA) can be used for registry backup.
The registry store process needs to include
- DMA enable
- Store registers into DMA controller channel memory address registers
- Restore of registers from DMA controller channel memory address registers
- Restore DMA state before assembly routine call (most probably disable DMA)
Example for STM32F4 family and IAR compiler:
Backing-up the registers in STL_FullRamMarchC procedure in file stm32fxx_STLRamMcMxIAR.s.
STL_FullRamMarchC:
//-----R4 - R7 BACKUP SEQUENCE-----
//backup R2 and R3, used in following DMA backup procedure
PUSH {R1-R3}
//store R4-R7
//enable DMA1 to store backup of registers
LDR R3, =0x40021030 //AHBENR register address
LDR R1, [R3] //R1 backup of AHBENR
LDR R3, [R3]
MOVS R2, #0x01 //DMA1EN clock enable bit position
ORRS R3, R3, R2 //set DMA1EN bit, default after MCU reset
LDR R2, =0x40021030
STR R3, [R2]
//store registers R4-R7
LDR R3, =0x40020000 // DMA1 base address -> R3
STR R4, [R3, #+0x14] // R4 -> DMA CMAR1
STR R5, [R3, #+0x28] // R5 -> DMA CMAR2
STR R6, [R3, #+0x3C] // R6 -> DMA CMAR3
STR R7, [R3, #+0x50] // R7 -> DMA CMAR4
STR R1, [R3, #+0x64] // R1 -> DMA CMAR5
//restore R1 - R3 backup
POP {R1-R3}
//---------------------------------
Restoring the registers at the end of procedure:
//-----R4 - R7 RESTORE SEQUENCE------
//backup R2 and R3, used in following DMA backup procedure
PUSH {R2-R3}
//restore R4-R7
LDR R3, =0x40020000 // DMA1 base address -> R3
MOVS R2, #0 //default CMAR value by reference manual
LDR R4, [R3, #+0x14] // DMA CMAR1 -> R4
LDR R5, [R3, #+0x28] // DMA CMAR2 -> R5
LDR R6, [R3, #+0x3C] // DMA CMAR3 -> R6
LDR R7, [R3, #+0x50] // DMA CMAR4 -> R7
LDR R2, [R3, #+0x64] // DMA CMAR5 -> R2
//restore AHBENR
LDR R3, =0x40021030 //AHBENR register address
STR R2, [R3]
//restore R2 and R3 backup
POP {R2-R3}
//------------------------------------
Backing-up the registers in STL_StartUpCPUTest procedure in file stm32l0xx_STLcpustartIAR.s:
PUSH {R4-R7} /* Safe critical registers */
//R8 - R11 BACKUP SEQUENCRE
//backup R1 - R3, used in following DMA backup procedure
PUSH {R1-R3}
//BACKUP R8-R11
//enable DMA1 to store backup of registers
LDR R3, =0x40021030 //AHBENR register address
LDR R1, [R3] //R1 backup of AHBENR
LDR R3, [R3]
MOVS R2, #0x01 //DMA1EN clock enable bit position
ORRS R3, R3, R2 //set DMA1EN bit, default after MCU reset
LDR R2, =0x40021030 //AHBENR register address
STR R3, [R2]
//store registers
LDR R3, =0x40020000 // DMA1 base address -> R3
MOV R2,R8
STR R2, [R3, #+0x14] // R8 -> DMA CMAR1
MOV R2,R9
STR R2, [R3, #+0x28] // R9 -> DMA CMAR2
MOV R2,R10
STR R2, [R3, #+0x3C] // R10 -> DMA CMAR3
MOV R2,R11
STR R2, [R3, #+0x50] // R11 -> DMA CMAR4
STR R1, [R3, #+0x64] // R1 -> DMA CMAR5
//restore R1 - R3 backup
POP {R1-R3}
Restoring the registers at the end of procedure:
POP {R4-R7} /* Restore critical registers */
//------R8 - R11 RESTORE SEQUENCE------
//backup R2 and R3, used in following DMA backup procedure
PUSH {R2-R3}
//RESTORE BACKUP OF R8-R11
//restore registers
LDR R3, =0x40020000 // DMA1 base address -> R3
LDR R2, [R3, #+0x14] // DMA CMAR1 -> R8
MOV R8, R2
LDR R2, [R3, #+0x28] // DMA CMAR2 -> R9
MOV R9, R2
LDR R2, [R3, #+0x3C] // DMA CMAR3 -> R10
MOV R10, R2
LDR R2, [R3, #+0x50] // DMA CMAR4 -> R11
MOV R11, R2
LDR R2, [R3, #+0x64] // DMA CMAR5 -> R2, CMAR5 contained AHBENR backup
//RESTORE AHBENR (DMA state)
LDR R3, =0x40021030 //AHBENR register address
STR R2, [R3] //write to AHBENR
//restore R2 and R3 backup
POP {R2-R3}
//---------------------------------------------------