电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>接口技术>UCOSIII移植中的汇编接口函数讲解

UCOSIII移植中的汇编接口函数讲解

2017-12-06 | rar | 未知 | 次下载 | 1积分

资料介绍

 1:开始多任务函数 void OSStartHighRdy(void)
  在OSInit()初始化完毕之后,会调用OSStart(),在OS开始函数里面会调用void OSStartHighRdy(void)函数,这是一个纯汇编编写的函数,在os_cpu_a.s这个汇编文件里面实现,具体的如下,我已经给每一句代码都添加了注释。
    ; 开始多任务
  ; void OSStartHighRdy(void)
  ;
  ; 注意 : 1) 这个函数触发了一个PendSV异常,导致第一个任务开始运行。
  ;
  ; 2) OSStartHighRdy() 必须:
  ; a) 设置PendSV的优先级为最低;
  ; b) 初始化进程堆栈指针PSP等于0, 表明这是第一次上下文切换;
  ; c) 设置主堆栈指针等于OS_CPU_ExceptStkBase
  ; d) 触发PendSV异常;
  ; e) 使能中断,任务开始运行。
    ;********************************************************************************************************
  ; 开始多任务
  ; void OSStartHighRdy(void)
  ;
  ; 注意 : 1) 这个函数触发了一个PendSV异常,导致第一个任务开始运行。
  ;
  ; 2) OSStartHighRdy() 必须:
  ; a) 设置PendSV的优先级为最低;
  ; b) 初始化进程堆栈指针PSP等于0, 表明这是第一次上下文切换;
  ; c) 设置主堆栈指针等于OS_CPU_ExceptStkBase
  ; d) 触发PendSV异常;
  ; e) 使能中断,任务开始运行。
  ;********************************************************************************************************
  OSStartHighRdy
  ; 设置PendSV中断优先级
  LDR R0, =NVIC_SYSPRI14
  LDR R1, =NVIC_PENDSV_PRI
  STRB R1, [R0] ;*R0=R1(低字节),因为表达优先级只需要8bit
  ; 初始化PSP=0
  MOVS R0, #0 ; 把0加载到R0
  MSR PSP, R0 ; 把R0的值加载到特殊寄存器PSP
  ; 初始化MSP地址
  LDR R0, =OS_CPU_ExceptStkBase ; 把OS_CPU_ExceptStkBase这个指针变量的地址加载到R0
  LDR R1, [R0] ; *R0 = R1,实际上就是把OS_CPU_ExceptStkBase的值加载到R1
  MSR MSP, R1 ; 把R1的值加载到MSP,此时MSP=OS_CPU_ExceptStkBase
  ; 触发PendSV异常 (进入上下文切换)
  LDR R0, =NVIC_INT_CTRL
  LDR R1, =NVIC_PENDSVSET
  STR R1, [R0] ; *R0 = R1
  ; 打开中断
  CPSIE I
  ; 正常情况下,永远不会运行到这,因为这是一个死循环
  OSStartHang
  B OSStartHang
  1:PendSV 异常服务函数 void OS_CPU_PendSVHandler(void)
 
OS_CPU_PendSVHandler
    CPSID   I                                                          ; 关中断,执行上下文切换的时候不能被中断,属于临界段
    MRS     R0, PSP                                                ; 加载PSP(即R13)的值到R0
    CBZ     R0, OS_CPU_PendSVHandler_nosave     ; R0的值为0则跳转到OS_CPU_PendSVHandler_nosave; CBZ:比较,如果结果为0就跳转
                                                                           ; 第一次进行上下文切换的时候PSP等于0,所以要进行跳转
                                                                                                                                                                                                                                                                
    SUBS    R0, R0, #0x20                                     ; 压栈之前先调整堆栈指针,要压栈的寄存器R4-R11有8个,所以偏移为8*0x04=0x20
    STM     R0, {R4-R11}                                       ; 手动将R4-R11压栈
 
    ; 实现 OSTCBCurPtr->OSTCBStkPtr = SP;
    LDR     R1, =OSTCBCurPtr                              ; R1=&OSTCBCurPtr,这个时候R1里面存的是OSTCBCurPtr这个指针变量的地址                
    LDR     R1, [R1]                                             ; R1=*R1=OSTCBCurPtr,这个时候,R1等于OSTCBCurPtr这个指针变量
    STR     R0, [R1]                                             ; *R1=R0,这个时候OSTCBCurPtr指向的TCB的第一个成员(即OSTCBCurPtr->OSTCBStkPtr)等于R0
                                                                        ; R0又是一开始进行压栈的PSP,所以OSTCBCurPtr->OSTCBStkPtr = SP
                                                                        ; 程序运行到这个点上,进入上下文切换的过程已经保存好了
OS_CPU_PendSVHandler_nosave
    PUSH    {R14}                                               ; 保存 LR exc_return 的值
    LDR     R0, =OSTaskSwHook                         ; 调用OSTaskSwHook()
    BLX     R0
    POP     {R14}
 
    ; 实现 OSPrioCur = OSPrioHighRdy;
    LDR     R0, =OSPrioCur                                ; R0=&OSPrioCur                                
    LDR     R1, =OSPrioHighRdy                         ; R1=&OSPrioHighRdy
    LDRB    R2, [R1]                                         ; R2=*R1(低字节),因为优先级是8bit的,所以是低字节
    STRB    R2, [R0]                                          ; R0=*R2(低字节),因为优先级是8bit的,所以是低字节
 
    ; 实现 OSTCBCurPtr = OSTCBHighRdyPtr;
                LDR     R0, =OSTCBCurPtr                ; R0=&OSTCBCurPtr                                  
    LDR     R1, =OSTCBHighRdyPtr                     ; R1=&OSTCBHighRdyPtr
    LDR     R2, [R1]                                           ; R2=*R1
    STR     R2, [R0]                                           ; R0=*R2
 
    LDR     R0, [R2]                                          ; R0等于新的进程的SP; SP = OSTCBHighRdyPtr->StkPtr
                                                                      ; R2=OSTCBHighRdyPtr,则[R2]=*R2=OSTCBHighRdyPtr=StkPtr,因为TCB的第一个成员就是StkPtr
    LDM     R0, {R4-R11}                                  ; 从新的堆栈中弹出R4-R11
    ADDS    R0, R0, #0x20                                ; 重新调整堆栈指针,R4-R11为8个寄存器,每个寄存器为四个字节,8*4=32=0X20
    MSR     PSP, R0                                          ; 更新PSP的值
    ORR     LR, LR, #0x04                                ; 判断LR寄存器的位4是否为1,确保异常返回用用的是PSP
    CPSIE   I                                                    ; 打开中断,上下文切换结束
    BX      LR                                                   ; 异常返回
 
    END                                                          ; 汇编程序结束
  ; 只有在特权级下,才可以访问下面三个寄存器
  ; PRIMASK :这是个只有单一比特的寄存器。 在它被置 1 后,就关掉所有可屏蔽的异常,只剩下 NMI 和硬 fault 可以响应。它的缺省值是 0,表示没有关中断。
  ; FAULTMASK:这是个只有 1 个位的寄存器。当它置 1 时,只有 NMI 才能响应,所有其它的异常,甚至是硬 fault,也通通闭嘴。它的缺省值也是 0,表示没有关异常。
  ; BASEPRI :这个寄存器最多有 9 位( 由表达优先级的位数决定)。它定义了被屏蔽优先级的阈值。当它被设成某个值后,所有优先级号大于等于此值的中断都被关(优先级号
  ; 越大,优先级越低)。但若被设成 0,则不关闭任何中断, 0 也是缺省值。
  ;
  ; 为了快速的开关中断,CM3专门设置了一条CPS指令,有4种用法
  ; CPSID I //PRIMASK = 1, ;关中断
  ; CPSIE I //PRIMASK = 0, ;开中断
  ; CPSID F //FAULTMASK = 1, ;关异常
  ; CPSIE F //FAULTMASK = 0, ;开异常
 
下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1电子电路原理第七版PDF电子教材免费下载
  2. 0.00 MB  |  1497次下载  |  免费
  3. 2TC358743XBG评估板参考手册
  4. 1.36 MB  |  330次下载  |  免费
  5. 3单片机典型实例介绍
  6. 18.19 MB  |  99次下载  |  1 积分
  7. 4S7-200PLC编程实例详细资料
  8. 1.17 MB  |  28次下载  |  1 积分
  9. 5笔记本电脑主板的元件识别和讲解说明
  10. 4.28 MB  |  18次下载  |  4 积分
  11. 6开关电源原理及各功能电路详解
  12. 0.38 MB  |  14次下载  |  免费
  13. 79天练会电子电路识图
  14. 5.91 MB  |  6次下载  |  免费
  15. 8100W短波放大电路图
  16. 0.05 MB  |  4次下载  |  3 积分

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234313次下载  |  免费
  3. 2PADS 9.0 2009最新版 -下载
  4. 0.00 MB  |  66304次下载  |  免费
  5. 3protel99下载protel99软件下载(中文版)
  6. 0.00 MB  |  51209次下载  |  免费
  7. 4LabView 8.0 专业版下载 (3CD完整版)
  8. 0.00 MB  |  51043次下载  |  免费
  9. 5555集成电路应用800例(新编版)
  10. 0.00 MB  |  33564次下载  |  免费
  11. 6接口电路图大全
  12. 未知  |  30321次下载  |  免费
  13. 7Multisim 10下载Multisim 10 中文版
  14. 0.00 MB  |  28588次下载  |  免费
  15. 8开关电源设计实例指南
  16. 未知  |  21540次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537794次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420026次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234313次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191183次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183278次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138039次下载  |  免费