STM32 重置问题

Posted

技术标签:

【中文标题】STM32 重置问题【英文标题】:STM32 Reset issues 【发布时间】:2021-05-13 11:18:43 【问题描述】:

我已经用 C 和 Rust 对我的 STM32F401 进行了编程,但是在组装时遇到了问题。

当我最初使用 Black Magic Probe 加载代码时,它运行良好 当我的开发板通电或重置时,代码无法运行。 重置后,在 GDB 中,如果我尝试C继续它,它会引发异常。 重置后,在 GDB 中,如果我尝试 Run 它,它运行良好

重置处理程序中的实际代码是常年“闪烁”。 我确定代码没有问题,这“闻起来”是某种“初始化问题”?

我是 GDB 的大菜鸟,但如果我这样做 info registers,PC 始终是我期望的值 - 0x8000198
Disassembly of section .text:

08000000 <vector_table>:
 8000000:   20010000    .word   0x20010000
 8000004:   08000198    .word   0x08000198
 8000008:   08000194    .word   0x08000194
 -- redacted a load from brevity... they're all 0x0800194 
 8000188:   08000194    .word   0x08000194
 800018c:   08000194    .word   0x08000194
 8000190:   08000194    .word   0x08000194

08000194 <Default_handler>:
 8000194:   f7ff bffe   b.w 8000194 <Default_handler>

08000198 <Reset_handler>:

            ; RCC_AHB1ENR := RCC_AHB1ENR OR RCC_AHB1Periph_GPIOC

 8000198:   f643 0030   movw    r0, #14384  ; 0x3830
 800019c:   f2c4 0002   movt    r0, #16386  ; 0x4002
 80001a0:   6802        ldr r2, [r0, #0]
 80001a2:   f042 0204   orr.w   r2, r2, #4
 80001a6:   6002        str r2, [r0, #0]

            ; GPIOC_MODER := GPIO_MODER_13_OUTPUT

 80001a8:   f640 0000   movw    r0, #2048   ; 0x800
 80001ac:   f2c4 0002   movt    r0, #16386  ; 0x4002
 80001b0:   f240 0200   movw    r2, #0
 80001b4:   f2c0 4200   movt    r2, #1024   ; 0x400
 80001b8:   6002        str r2, [r0, #0]

 80001ba:   f240 0220   movw    r2, #32     ;          0b00100000
 80001be:   f2c0 0200   movt    r2, #0

 80001c2:   f640 0019   movw    r0, #2073   ; 0x819    GPIOC_BSRR8
 80001c6:   f2c4 0002   movt    r0, #16386  ; 0x4002
 80001ca:   f640 011b   movw    r1, #2075   ; 0x81b    GPIOC_BSRR24
 80001ce:   f2c4 0102   movt    r1, #16386  ; 0x4002

080001d2 <.loop>:
 80001d2:   7002        strb    r2, [r0, #0] ; set bit

 80001d4:   f240 0300   movw    r3, #0
 80001d8:   f2c0 030d   movt    r3, #13
080001dc <.delay0>:
 80001dc:   3b01        subs    r3, #1
 80001de:   bf18        it  ne
 80001e0:   e7fc        bne.n   80001dc <.delay0>

 80001e2:   700a        strb    r2, [r1, #0] ; reset bit

 80001e4:   f240 0300   movw    r3, #0
 80001e8:   f2c0 030d   movt    r3, #13
080001ec <.delay1>:
 80001ec:   3b01        subs    r3, #1
 80001ee:   bf18        it  ne
 80001f0:   e7fc        bne.n   80001ec <.delay1>

 80001f2:   e7ee        b.n 80001d2 <.loop>

【问题讨论】:

【参考方案1】:
 8000004:   08000198    .word   0x08000198

需要奇数才能启动

您需要使用 .thumb_func 或 .type(如果使用 gnu 汇编程序,如果使用另一种汇编语言,则需要针对该语言对其进行排序)

.cpu cortex-m4
.thumb

vector_table:
.word 0x20001000
.word ResetVector

.thumb_func
.globl ResetVector
ResetVector:
   b .

Disassembly of section .text:

08000000 <vector_table>:
 8000000:   20001000    .word   0x20001000
 8000004:   08000009    .word   0x08000009

08000008 <ResetVector>:
 8000008:   e7fe        b.n 8000008 <ResetVector>

这将启动(或至少会尝试运行重置处理程序)

没有:

.cpu cortex-m4
.thumb

vector_table:
.word 0x20001000
.word ResetVector

.globl ResetVector
ResetVector:
   b .

Disassembly of section .text:

08000000 <vector_table>:
 8000000:   20001000    .word   0x20001000
 8000004:   08000008    .word   0x08000008

08000008 <ResetVector>:
 8000008:   e7fe        b.n 8000008 <ResetVector>

这不会启动

您也可以使用 .type,.type 对手臂和拇指都有效(如果执行 ARM 指令,因为它是 cortex-m,所以这是不可能的)。

.cpu cortex-m4
.thumb

vector_table:
.word 0x20001000
.word ResetVector

.type ResetVector, %function
.globl ResetVector
ResetVector:
   b .

Disassembly of section .text:

08000000 <vector_table>:
 8000000:   20001000    .word   0x20001000
 8000004:   08000009    .word   0x08000009

08000008 <ResetVector>:
 8000008:   e7fe        b.n 8000008 <ResetVector>

其他所有向量(不是 sp 初始值)必须是奇数。使用工具不要做一些加一的事情。

您的调试器可能是直接启动程序而不是重置部件。

【讨论】:

请注意,正在设置的 lsbit 位于内核的 ARM 文档中。 所有其他条目必须将 bit[0] 设置为 1,因为该位定义了异常条目上的 EPSR.T 位。 我错误地认为 thumb_func 用于混合 ARM 和 Thumb 功能(在可能的内核上)并且还忘记了“+1 的东西”......回到我去的文档。 啊,是的,EPSR.T 听起来像是我需要查找的“魔法调用”。谢谢。 认为 ORRed 一个不加一个,如果你用一个 orr 加一个总是正确的,如果你加一个并且工具工作那么加可能会出错。

以上是关于STM32 重置问题的主要内容,如果未能解决你的问题,请参考以下文章

如何重置 STM32 HAL UART 驱动程序 (HAL) 状态?

STM32F030F4P6 仅在从闪存启动时运行中断处理程序。从引导加载程序启动时重置

STM32:STLink 不再通过 SWD 连接

stm32 USB-CDC 硬件复位后

NVIC 系统重置失败

在 STOP 模式之前禁用 STM32 HAL IWDG 或 WWDG(看门狗)