ARM Cortex M4 - 当PRIMASK设置为1时,SysTick中断请求会发生什么?

时间:2018-04-19 21:00:42

标签: arm semaphore interrupt rtos cortex-m

我正在学习RTOS,而我正在谈论信号量。这本书实现了一个自旋锁定信号量,但是我很难理解SysTick会发生什么,它用于实现上下文切换。

 void OS_Wait(int32_t *s){
  while( (*s) == 0 )
  {
       EnableInterrupts(); //Does SysTick "wait" until this line?
       Disableinterrupts();
  }
  (*s) = (*s) - 1;
  EnableInterrupts();
}

EnableInterrupts()是一个装配子程序

 EnableInterrupts
  CPSIE I
  BX LR

我的另一本ARM书中说CPSIE I的等效代码是

MOVS r0, #0
MSR PRIMASK, r0

我在其他地方问过这个问题,而我从其中一个答案中得到的理解是,特定中断的RIS值在服务之前一直保持高位,因为它们必须在其处理程序中设置为0,所以请求等待"等待"直到再次启用中断。我不确定这是否正确。 SysTick会发生什么?它没有RIS位请求它的处理程序。那么,当中断被禁用时,SysTick究竟发生了什么?我阅读了电路板(TM4C123)的参考手册,并说每次发生中断时STCTRL寄存器COUNT位都会被提升。这是它的等效RIS位吗?参考手册没有明确说明。谢谢!

编辑:我查阅了参考手册。 PRIMASK取值为1以禁用具有可配置优先级的所有异常,因此我认为之前的代码是错误的。它应该是1.

MOVS r0, #1
MSR PRIMASK, r0

编辑:修正了错字。

1 个答案:

答案 0 :(得分:0)

arm docs state

The CPSIE i instruction is equivalent to writing a 0 into PRIMASK.
The CPSID i instruction is equivalent to writing a 1 into PRIMASK.
The CPSIE f instruction is equivalent to writing a 0 into FAULTMASK.
The CPSID f instruction is equivalent to writing a 1 into FAULTMASK.

试试吧......

.equ GPIOEBASE, 0x40021000
.equ RCCBASE  , 0x40023800
.equ STK_BASE , 0xE000E000

.thumb

.thumb_func
.global _start
_start:
stacktop: .word 0x20001000
.word reset
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word hang
.word systick_handler


.thumb_func
reset:
    ldr r0,=RCCBASE
    ldr r1,[r0,#0x30]
    ldr r2,=0x00000010
    orr r1,r2
    str r1,[r0,#0x30]

    ldr r0,=GPIOEBASE

    ldr r1,[r0,#0x00]
    ldr r2,=0x00000003
    bic r1,r2
    ldr r2,=0x00000001
    orr r1,r2
    str r1,[r0,#0x00]

    ldr r1,[r0,#0x04]
    ldr r2,=0x00000001
    bic r1,r2
    str r1,[r0,#0x04]

    ldr r1,=0x00000001
    str r1,[r0,#0x18]

    ldr r2,=STK_BASE
    ldr r3,=0x00004;
    str r3,[r2,#0x10]
    ldr r3,=0x10000;
    str r3,[r2,#0x14]
    ldr r3,=0x0000;
    str r3,[r2,#0x18]
    ldr r3,=0x00007;
    str r3,[r2,#0x10]

    ldr r3,=0
    msr PRIMASK,r3

.thumb_func
hang:   b .

.thumb_func
systick_handler:
    ldr r1,=0x00010000
    str r1,[r0,#0x18]
    b .
.align
.word 0x12345678
.end

led开启

ldr r3,=1
msr PRIMASK,r3

led停止

cpsie i

领导

cpsid i

领导

cpsid / cpsie是小型单指令

 8000076:   2300        movs    r3, #0
 8000078:   f383 8810   msr PRIMASK, r3
 800007c:   b662        cpsie   i
 800007e:   2301        movs    r3, #1
 8000080:   f383 8810   msr PRIMASK, r3
 8000084:   b672        cpsid   i

我会选择cpsid / cpsie。