电子发烧友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次下载  |  免费