Cortex-M3 SysTick double interrupt



我正在创建一个rtos系统,系统tick (1ms)用于实时,触发pendv用于切换任务。systick和pendsv的优先级为0 (group = 16;& lt; SCB.AIRCR。priggroup = 0b011>)。PendSv也由SCB.ICSR触发。PENDSVSET = 1>当当前任务是睡眠时。有时,PendSV和SysTick同时发生,并且先执行SysTick,然后执行PendSV。但是在执行PendSV之后,SysTick会再次发生。我试着改变优先级,并清除SCB.ICSR。PENDSTCLR = 1>在系统tick句柄中,没有任何更改。你知道为什么吗?知道怎么解决吗?logic_analyzer

asm代码:

//#define USING_PUSH_POP
EXTERN GPIOA_BITBAND
EXTERN RTOS_GetCurrentCPU                     //CPU_TypeDef* RTOS_GetCurrentCPU();
EXTERN RTOS_GetNextCPU                        //CPU_TypeDef* RTOS_GetNextCPU();
PUBLIC PendSV_Handler
PUBLIC RTOS_ASM_Begin                         //void RTOS_ASM_ASM_Begin(CPU_TypeDef* CPU);

SECTION rtos_function:CODE
PendSV_Handler:
//PUSH in SP when interrupt
//Here - R0 - R1 - R2 - R3 - R12 - BACK_LR - BACK_PC - EAPSR
PUSH          {LR}

LDR.W         R0, =GPIOA_BITBAND   //(1)
MOV           R1, #1
STR           R1, [R0, #0x180]


BL            RTOS_GetCurrentCPU
CMP           R0, #0
BEQ           BREAK                           //if (NULL): back to current task
BL            RTOS_ASM_SaveCurrentCPU
BL            RTOS_GetNextCPU
CMP           R0, #0
BEQ           BREAK                           //if (NULL): back to current task
B             RTOS_ASM_SwitchNextCPU
BREAK:
POP           {PC}
//===================================
RTOS_ASM_Begin:                               //R0: CPU_TypeDef* MainCPU
PUSH          {R1, LR}
STR           LR , [R0, #28]
STR           R1 , [R0, #24]
ADDS          R1 , R0, #24
MOV           SP , R1
BL            RTOS_ASM_SaveCurrentCPU  
POP           {R1, PC}
//===================================
RTOS_ASM_SaveCurrentCPU:                      //R0: CPU_TypeDef* CurrentCPU
#ifdef USING_PUSH_POP
MOVS          R1 , SP
STR           SP , [R0, #(4 * 16)]
ADDS          R0 , R0, #(4 * 16)
MOVS          SP , R0
PUSH          {R4-R11}
MOVS          SP , R1
#else
STR           R4 , [R0, #(4 * 8 )]
STR           R5 , [R0, #(4 * 9 )]
STR           R6 , [R0, #(4 * 10)]
STR           R7 , [R0, #(4 * 11)]
STR           R8 , [R0, #(4 * 12)]
STR           R9 , [R0, #(4 * 13)]
STR           R10, [R0, #(4 * 14)]
STR           R11, [R0, #(4 * 15)]
STR           SP , [R0, #(4 * 16)]  
#endif
BX            LR
//===================================
RTOS_ASM_SwitchNextCPU:                       //R0: CPU_TypeDef* NextCPU
#ifdef USING_PUSH_POP
ADDS          R1 , R0, #(4 * 8)
MOVS          SP , R1
POP           {R4-R11}
LDR           SP , [R0, #(4 * 16)]
#else
LDR           R4 , [R0, #(4 * 8 )]
LDR           R5 , [R0, #(4 * 9 )]
LDR           R6 , [R0, #(4 * 10)]
LDR           R7 , [R0, #(4 * 11)]
LDR           R8 , [R0, #(4 * 12)]
LDR           R9 , [R0, #(4 * 13)]
LDR           R10, [R0, #(4 * 14)]
LDR           R11, [R0, #(4 * 15)]
LDR           SP , [R0, #(4 * 16)]
#endif
LDR.W         R0, =GPIOA_BITBAND   //(2)
MOV           R1, #0
STR           R1, [R0, #0x180]
POP           {PC}  
//===================================
END

系统滴答句柄:

void SysTick_Handler()
{
GPIOB_BITBAND.ODR._10 ^= 1;   //(3)
System.MsTick++;
if (TaskManager.Running)
RTOS_SWITCH_TRIGGER();
//SCB.ICSR.REG = BIT25;
SCB.ICSR.BITS.PENDSTCLR = 1;
}

我现在的解决方案是使用SVC而不是PendSV

相关内容

  • 没有找到相关文章

最新更新