- 1、本文档共4页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
μC/OS-Ⅱ中通过中断返回指令实现任务切换
胡蔷
【摘要】μC/OS-Ⅱ是一个源码公开的实时嵌入式操作系统,它的特点在于公开的源代码,很强的移植性,占先式多任务,每个任务有单独的栈,中断管理及很强的稳定性与可靠性等,目前越来越受到实时嵌入式系统设计者的关注,而要使用μC/OS-Ⅱ就要针对不同的处理器进行移植,本文通过对在80x86和MCU-51上移植实例的分析,给出了在移植μC/OS-Ⅱ系统时如何通过中断指令实现任务切换,解决移植的核心问题。
【关键字】μC/OS-Ⅱ 嵌入式操作系统 移植 任务切换
中图分类号TP313 文献标识码 A
一.μC/OS-Ⅱ的工作原理
μC/OS-Ⅱ是一个占先式多任务实时嵌入式操作系统,它的每个任务都有单独的栈,通过时钟中断来控制各个任务的切换,即时钟节拍是μC/OS-Ⅱ工作的脉搏,但要这个脉搏对工作起作用则是通过任务调度函数中的最后一条指令――中断返回指令来实现的。因此要使中断返回指令工作时返回到正确的任务的入口地址来实现任务切换。
二.μC/OS-Ⅱ的移植
1.要使用μC/OS-Ⅱ正常工作,处理器必须满足以下要求:
(1).处理器的C编译器能产生可重入代码。
(2).用C语言就可以打开和关闭中断。
(3)处理器支持中断,并且能产生定时中断(通常在10至100Hz之间)
(4)处理器支持能够容纳一定量数据(可能是几千字节)的硬件堆栈。
(5)处理器有堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。
2.需要移植的文件有:
OS_CPU.H OS_CPU_A.ASM OS_CPU_C.C
3.时钟定时器的硬件设定
三.μC/OS-Ⅱ中中断返回指令实现任务切换
1.CPU中的中断返回指令的作用是:
从工作堆栈中恢复断点和恢复标志寄存器。
2.μC/OS-Ⅱ中的任务控制块TCB和任务堆栈(本文只给出与任务切换有关的TCB结 构体定义部分):
typedef unsigned int OS_STK; //任务堆栈的栈单元宽度与编译相关
typedef struct os_tcb{
OS_STK *OSTCBStkptr; //任务堆栈指针
.………………
}OS_TCB; //任务控制块
OS_TCB *OSTCBCur; 指向任务控制块的指针
3.任务堆栈的栈增长方式:
#define OS_STK_GROWTH 1 // 0 向上,1 向下;与处理器相关
4.针对不同的处理器采用相应的汇编指令从指向任务控制块的指针中得到任务堆栈的指针,把当前工作堆栈转到要切换的任务堆栈上,通过中断返回指令切换到新的任务。
5.实例:
(1)80x86中的实现:
80x86 工作在实模式下,C和ASM都用大模式编译,应用程序和数据最大寻址空间为1MB,程序指针为32位即由16位段地址和16位偏移量组成。
a. 与处理器和编译器相关量的定义:
#define OS_STK_GROWTH 1
typedef unsigned int OS_STK;
typedef unsigned int INT16U;
b. 堆栈初始化:
任何一个新建任务都要做这个初始化他与处理器相关对于中断返回后正确切换到新任务至关重要。
void OSTaskStkInit (void (*ask)(void *pd),void *pdata,void *ptos, INT16U opt)
{
OS_STK *stk;
stk=(INT16U *)ptos;
*stk-- = (INT16U)FP_SEG(pdata); //获得任务的附加数据区指针
*stk-- = (INT16U)FP_OFF(pdata);
*stk-- = (INT16U)FP_SEG(task); //本任务的入口地址(段值:偏移值)
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0x0202; //标志寄存器设为使中断允许
*stk-- = (INT16U)FP_SEG(task); //本任务的入口地址(段值:偏移值)
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0xAAAA; //AX ,CX,DX,BX,SP,BP,
文档评论(0)