嵌入式学习小组
直播中

余煌木

7年用户 234经验值
私信 关注

UCOS-III中断程序编写找不到相关代码该怎么办?

1.在学习ucos-iii时,看到资料的工程---SYSTEM文件夹---usatr.c中的串口中断中断服务程序void USART1_IRQHandler(void) 如下:
void USART1_IRQHandler(void)                //串口1中断服务程序
{
……
OSIntEnter();   
………………//省略了串口的代码。
OSIntExit();   
……
}
在这个程序中,体现了ucos-iii中断的编写模板。
对于Cortex-M3内核的异常来说,进入异常自动保存SRPCR12R0~R3,那剩下的R4~R11寄存器的保存怎么在如上的“串口1中断服务程序”找不到相关代码呢?查看了一下OSIntEnter()中确实没有啊。源代码如下:
void  OSIntEnter (void)
{
    if (OSRunning != OS_STATE_OS_RUNNING) {                 /* Is OS running?                                         */
        return;                                             /* No                                                     */
    }
    if (OSIntNestingCtr >= (OS_NESTING_CTR)250u) {          /* Have we nested past 250 levels?                        */
        return;                                             /* Yes                                                    */
    }
    OSIntNestingCtr++;                                      /* Increment ISR nesting level                            */
}
为什么?

回帖(4)

周梦斌

2019-8-2 08:29:07
问题已经解决。详见cortex-M3权威指南的136页
举报

侯晓萃

2019-8-2 08:48:23
剩下的R4~R11是手动不保存的,典型的看资料不认真!我们的UCOS教程对这个有非常详细的讲解!
举报

常静娜

2019-8-2 09:03:48
对于初始化阶段OSStartHighRdy和任务级调度器OSCtxSw、中断级调度器OSIntCtxSw来说都是通过挂起PendSV异常实现的任务切换。因此重点在PendSV异常的编写。
由于OSStartHighRdy之前已经使用C语言编写的OSTaskStkInit()函数(位于cpu_core.c)将现场初始化完毕,因此进入PendSV后执行执行PendSVHandler_nosave 之后的代码。而任务级调度器OSCtxSw、中断级调度器OSIntCtxSw将会执行PendSV异常所有的代码。
 我的疑问如下:
除PendSV异常之外的其他异常的模型和初始化阶段OSStartHighRdy和任务级调度器OSCtxSw、中断级调度器OSIntCtxSw稍稍有些不同,不难发现PendSV一开始就赶紧保存R4~R11,但为什么其他异常刚进入后却不需要先保存R4~R11,而仅在最后才使用OSIntExit()在确定会发生调度时才保存R4~R11。
 
Void xxxxx_xxxHandler(void)  //除endSV异常之外的其他异常的“C代码”模型
{OSIntEnter();   
    中断服务代码; 
OSIntExit();   

 
在进入异常时切换为handler mode,这种模式下是“privileged LEVEL特权模式”,所有的通用寄存器R0~R7(Low registers)+R8~R12(high registers)都可以使用。对于使用C编写的中断服务函数(如上模型),编译为机器码后难道只使用R0~R3、R12而不会对R4~R11造成破坏?
 版主大人,怎么看?

 
;//////////////////////////////////os_cpu_a.s///////////////////////////////////////////
OSStartHighRdy
    LDR     R0, =NVIC_SYSPRI4                                  ; Set the endSV exception priority
    LDR     R1, =NVIC_PENDSV_PRI
    STRB    R1, [R0]
;NVIC_SYSPRI4是配置PendSV优先级的寄存器的物理地址。NVIC_PENDSV_PRI是将要配置的PendSV的优先级别,通过宏定义可知,
;要将PendSV的优先级设置为255.注:这是cortex-M3的最低优先级。
 
 
;Cortex-M3内核提供了两个堆栈指针MSP和PSP。在《Cortex-M3 Devices Generic User Guide.pdf》的2.13节的介绍如下
;////////////////////////////
;Stack ointer
;The Stack ointer (SP) is register R13. In Thread mode, bit[1] of the CONTROL register
;indicates the stack pointer to use:
; 0 = Main Stack ointer (MSP). This is the reset value.
; 1 = rocess Stack ointer (PSP).
;On reset, the processor loads the MSP with the value from address 0x00000000.
;///////////////////////////////////
;下面5句话的作用:将PSR清零+将“异常的堆栈基地址赋”给MSP。
    MOVS    R0, #0                                              ; Set the SP to 0 for initial context switch call
    MSR     SP, R0
 
    LDR     R0, =OS_CPU_ExceptStkBase                           ; Initialize the MSP to the OS_CPU_ExceptStkBase
    LDR     R1, [R0]
    MSR     MSP, R1    
;uC/OS-III专门为异常提供了一个堆栈空间,其基地址为OS_CPU_ExceptStkBase
;如上3句话的作用:将异常的堆栈的基地址给堆栈指针MSP.
 
 
    LDR     R0, =NVIC_INT_CTRL                                  ; Trigger the endSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
;上边的三句汇编完成了对PendSV的挂起(触发)。挂起PendSV的唯一方法就是置位ICSR的bit[28]位。
;NVIC_INT_CTRL就是ICSR寄存器的地址。NVIC_PENDSVSET=0x10000000。都是宏定义。
;第1句: 将ICSR寄存器的地址NVIC_INT_CTRL放在R0中。
;第2句: 将NVIC_PENDSVSET放在R1中。
;第3句: 将R1放进R0所指向的存储器地址。也就是说向存储器的NVIC_INT_CTRL处(即ICSR寄存器)写入NVIC_PENDSVSET。
;说白了,这3句的作用就是将0x10000000写入到ICSR寄存器。这样一来,ICSR的bit[28]位被置位,即将PendSV挂起了。
    CPSIE   I                                                   ; Enable interrupts at processor level
 
;///////////
OSStartHang
    B       OSStartHang                                         ; Should never get here
 
;/////////
 
OSCtxSw
    LDR     R0, =NVIC_INT_CTRL    ; Trigger the endSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR
;//////////////
 
OSIntCtxSw
    LDR     R0, =NVIC_INT_CTRL         ; Trigger the PendSV exception (causes context switch)
    LDR     R1, =NVIC_PENDSVSET
    STR     R1, [R0]
    BX      LR


;/////////////////////
 
PendSV_Handler
    CPSID   I                                        ; Prevent interruption during context switch;关中断
    MRS     R0, PSP                                  ; PSP is process stack pointer;将PSP的值写入到R0中。
    CBZ     R0, PendSVHandler_nosave                 ; Skip register save the first time
;如果R0=0则跳转到PendSVHandler_nosave处执行。PendSVHandler_nosave是个汇编编写的子函数。
;c代码的等价转化:   if(R0==0)PendSVHandler_nosave();
 
    SUBS    R0, R0, #0x20                                       ; Save remaining regs r4-11 on process stack
    STM     R0, {R4-R11}
 
    LDR     R1, =OSTCBCurPtr                                    ; OSTCBCurPtr->OSTCBStkPtr = SP;
    LDR     R1, [R1]
    STR     R0, [R1]                                            ; R0 is SP of process being switched out
 
                                                                ; At this point, entire context of process has been saved
PendSVHandler_nosave  
    PUSH    {R14}                                               ; Save LR exc_return value
    LDR     R0, =OSTaskSwHook                                   ; OSTaskSwHook();
    BLX     R0
    POP     {R14}
 
    LDR     R0, =OSPrioCur                                      ; OSPrioCur   = OSPrioHighRdy;
    LDR     R1, =OSPrioHighRdy
    LDRB    R2, [R1]
    STRB    R2, [R0]
 
    LDR     R0, =OSTCBCurPtr                                    ; OSTCBCurPtr = OSTCBHighRdyPtr;
    LDR     R1, =OSTCBHighRdyPtr
    LDR     R2, [R1]
    STR     R2, [R0]
 
    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr;
    LDM     R0, {R4-R11}                                        ; Restore r4-11 from new process stack
    ADDS    R0, R0, #0x20
    MSR     PSP, R0                                             ; Load PSP with new process SP
    ORR     LR, LR, #0x04                                       ; Ensure exception return uses process stack
    CPSIE   I
    BX      LR                                                  ; Exception return will restore remaining context
 
    END
举报

冉屹芳

2019-8-2 09:21:57
以本为本还是有道理的,学习了
举报

更多回帖

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