[常见问题解答][STM32F4]:在调试ClassB库的过程中,示例给了我一些硬错误。问题出在哪里?问题可能是由现代编译器生成的代码在运行时使用的CPU寄存器损坏引起的。其中一个要求是每个子程序保持核心寄存器R4至R11的内容。我关于这个问题的信息也可以在文件中找到安4435第六章。
ClassB库的测试子例程位于程序集文件中(XXX是编译器的名称。例如GCC、IAR)。

 
  • stm32f4x_STLc持续XXX.s
    • STL_StartUpCPUTest例行程序
  • stm32fxx_STRAmMcMXXXX.s
    • STL_FullRamMarchC例程

需要修改程序集文件,以便在测试例程开始时存储注册内容,并在测试例程结束时恢复内容。
对于内存测试(stm32fxx_STLRamMcMxXXX.s文件中的STL_FullRamMarchC例程),SRAM内存不能用作备份位置,因为其内容在测试例程中被破坏。其中一种方法可以是使用一些MCU外围设备来存储寄存器内容。它可以是例如DMA控制器,因为它存在于大多数微控制器中,并且有足够的32位寄存器。DMA存储器地址寄存器可以用于该目的。
对于CPU测试(stm32f4x_STLcpustartXXX.s文件中的STL_StartUpCPUTest例程),堆栈或外围设备(DMA)可用于注册表备份。

注册表存储过程需要包括
  • DMA启用
  • 将寄存器存储到DMA控制器通道内存地址寄存器中
注册表恢复过程需要包括
  • 从DMA控制器通道内存地址寄存器恢复寄存器
  • 在程序集例程调用之前恢复DMA状态(很可能禁用DMA)

STM32F4系列和IAR编译器示例:
备份中的寄存器
STL_满RamMarchC文件stm32fxx_STLRamMcMxIAR.s中的过程。
STL_FullRamMarchC://-----R4-R7 BACKUP SEQUENCE----//备份R2和R3,用于以下DMA备份过程PUSH{R1-R3}//存储R4-R7//启用DMA1以存储寄存器LDR R3的备份,=0x40021030//AHBENR寄存器地址LDR R1,[R3]//AHBENR LDR R3备份的R1,[R3]MOVS R2,#0x01//DMA1EN时钟使能位位置ORRS R3,R3,R2//设置DMA1EN位,MCU重置LDR R2后默认,=0x40021030 STR R3,[R2]//存储寄存器R4-R7 LDR R3,=0x40020000//DMA1基地址->R3 STR R4,[R3,#+0x14]//R4->DMA CMAR1 STR R5,[R3、#+0x28]//R5->DMA CMAR2 STR R6,[R3和#+0x3C]/R6->DMA CMAR3 STR R7,[R三、#+0x50]//R7->DMA CMAR4 STR R1,[R三,#+0x64]//R1->DMA CMAR5//还原R1-R3备份POP{R1-R3}//---------------------------------

在过程结束时恢复寄存器:
//-----R4-R7 RESTORE SEQUENCE------//备份R2和R3,在以下DMA备份过程中使用PUSH{R2-R3}//还原R4-R7 LDR R3,=0x40020000//DMA1基地址->R3 MOVS R2,#0//默认CMAR值,通过参考手动LDR R4,[R3,#+0x14]//DMA CMAR1->R4 LDR R5,[R3、#+0x28]//DMA CMAR2->R5 LDR R6,[R3 4->R7 LDR R2,[R3,#+0x64]//DMA CMAR5->R2//恢复AHBENR LDR R3,=0x40021030//AHBENR寄存器地址STR R2,[R3]//恢复R2和R3备份POP{R2-R3}//------------------------------------

备份中的寄存器STL_启动CPUTest文件stm32l0xx_STLcpustartIAR.s中的过程:
PUSH{R4-R7}/*安全关键寄存器*//R8-R11 BACKUP SEQUENCRE//备份R1-R3,在以下DMA备份过程中使用PUSH{R1-R3}//BACKUP R8-R11//使能DMA1以存储寄存器LDR R3的备份,=0x40021030//AHBENR寄存器地址LDR R1,[R3]//AHBENR LDR R3备份的R1,[R3]MOVS R2,#0x01//DMA1EN时钟使能位位置ORRS R3,R3,R2//设置DMA1EN位,MCU重置LDR R2后的默认值,=0x40021030//AHBENR寄存器地址STR R3,[R2]//存储寄存器LDR R3,=0x400 20000//DMA1基地址->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,#1+0x3C]//R10->DMA CMAR3 MOV R1,R11 STR R2,[R3,#+0x50]//R11->DMA CMAR4 STR R1,[R3,#+0x64]//R1->DMA CMAR5//恢复R1-R3备份POP{R1-R3}

在过程结束时恢复寄存器:
POP{R4-R7}/*还原关键寄存器*//-R8-R11 Restore SEQUENCE------//备份R2和R3,在以下DMA备份过程中使用PUSH{R2-R3}//Restore backup OF R8-R11//还原寄存器LDR R3,=0x40020000//DMA1基地址->R3 LDR R2,[R3,#+0x14]//DMA CMAR1->R8 MOV R8,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包含AHBENR备份//恢复AHBENR(DMA状态)LDR R3,=0x40021030//AHBENR寄存器地址STR R2,[R3]//写入AHBENR//恢复R2和R3备份POP{R2-R3}//---------------------------------------------------