ST意法半导体
直播中

乐侨珂

7年用户 992经验值
擅长:控制/MCU
私信 关注
[问答]

如何在STM32上终止IRQ或者为什么单片机不更新IPSR?

我的代码在这里:
  • ...
  • @ some code
  • ...
  • end:
  •   nop
  •   b   end
  • thread0:
  •   mov32 r1, 0x4001100C  @ GPIOC_CRH address
  •   ldr   r0, [r1]
  •   orr   r0, 0x8000      @ switch_on C15 only
  •   str   r0, [r1]
  •   b     end
  • nvic_systick:
  •   push  { lr }
  •   @cpsid i
  •   mov32 r1, 0x4001100C  @ GPIOC_CRH address
  •   ldr   r0, [r1]
  •   eor   r0, 0xA000      @ toggle pin state on C13 & C15
  •   str   r0, [r1]
  •   adr   r2, thread0+1
  •   @push  { r2 }         <<<<----   EVIL INSTRUCTION
  •   pop   { lr }
  •   bx    lr
代码运行良好,但我希望控制器在从中断返回后转到“thread0”函数。
GDB 说:
  • (gdb) info all-registers
  • r0             0x0      0
  • r1             0xed04   60676
  • r2             0x1e1    481
  • r3             0x8a1e8883       -1977710461
  • r4             0xef5fffff       -278921217
  • r5             0xfffbffee       -262162
  • r6             0x21136d6a       554921322
  • r7             0x7a8191d        128456989
  • r8             0xf7efbf75       -135282827
  • r9             0xfffffffb       -5
  • r10            0xca444668       -901495192
  • r11            0xc2378b49       -1036547255
  • r12            0xff5bbfdf       -10764321
  • sp             0x20005000       0x20005000
  • lr             0xffffffff       0xffffffff
  • pc             0x1ce    0x1ce
  • xpsr           0x41000000       1090519040
  • msp            0x20005000       0x20005000
  • psp            0x9f48dd14       0x9f48dd14
  • primask        0x0      0 '00'
  • basepri        0x0      0 '00'
  • faultmask      0x0      0 '00'
  • control        0x0      0 '00'
  • (gdb)
注意 xpsr 寄存器。控制器停留在线程模式,现在指向“结束”函数内的指令。
取消注释“邪恶线”后:
  • ...
  • @ code
  • ...
  • nvic_systick:
  •   push  { lr }
  •   @cpsid i
  •   mov32 r1, 0x4001100C  @ GPIOC_CRH address
  •   ldr   r0, [r1]
  •   eor   r0, 0xA000      @ toggle pin state on C13 & C15
  •   str   r0, [r1]
  •   adr   r2, thread0+1
  •   push  { r2 }             @ THAT LINE
  •   pop   { lr }
  •   bx    lr
控制器执行一次 IRQ 处理程序,然后停留在“结束”循环。
在那种情况下,GDB 说:
  • (gdb) info all-registers
  • r0             0x0      0
  • r1             0xe000ed04       -536810236
  • r2             0x1e1    481
  • r3             0x8a1e8883       -1977710461
  • r4             0xef5fffff       -278921217
  • r5             0xfffbffee       -262162
  • r6             0x21136d6a       554921322
  • r7             0x7a8191d        128456989
  • r8             0xf7efbf75       -135282827
  • r9             0xfffffffb       -5
  • r10            0xca444668       -901495192
  • r11            0xc2378b49       -1036547255
  • r12            0xff5bbfdf       -10764321
  • sp             0x20004fdc       0x20004fdc
  • lr             0x1e1    0x1e1
  • pc             0x1dc    0x1dc
  • xpsr           0x4100000f       1090519055
  • msp            0x20004fdc       0x20004fdc
  • psp            0x9f48dd14       0x9f48dd14
  • primask        0x0      0 '00'
  • basepri        0x0      0 '00'
  • faultmask      0x0      0 '00'
  • control        0x0      0 '00'
  • (gdb)
这里 xpsr 包含 IPSR 的值,并且 0xf = 当前正在运行 SysTick_IRQ。
问题:如何从中断成功返回?








回帖(1)

郭雨桐

2023-2-7 09:39:35
现在可以了!


  • end:
  •   nop
  •   b   end

  • thread0:
  •   mov32 r1, 0x4001100C  @ GPIOC_CRH address
  •   ldr   r0, [r1]
  •   orr   r0, 0x8000      @ switch_on C15 only
  •   str   r0, [r1]

  •   b     end

  • nvic_systick:
  •   mov32 r1, 0x4001100C  @ GPIOC_CRH address
  •   ldr   r0, [r1]
  •   eor   r0, 0xA000      @ toggle pin state on C13 & C15
  •   str   r0, [r1]

  •   adr   r0, thread0+1
  •   str   r0, [sp, #24]
  •   
  •   bx    lr

但也许我做错了?直接写入堆栈是否正确?
所有值和地址都是通过从 RAM 读取堆栈找到的。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分