uCOS51移植心得Word文档格式.docx

上传人:b****1 文档编号:15309647 上传时间:2022-10-29 格式:DOCX 页数:18 大小:23.70KB
下载 相关 举报
uCOS51移植心得Word文档格式.docx_第1页
第1页 / 共18页
uCOS51移植心得Word文档格式.docx_第2页
第2页 / 共18页
uCOS51移植心得Word文档格式.docx_第3页
第3页 / 共18页
uCOS51移植心得Word文档格式.docx_第4页
第4页 / 共18页
uCOS51移植心得Word文档格式.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

uCOS51移植心得Word文档格式.docx

《uCOS51移植心得Word文档格式.docx》由会员分享,可在线阅读,更多相关《uCOS51移植心得Word文档格式.docx(18页珍藏版)》请在冰豆网上搜索。

uCOS51移植心得Word文档格式.docx

本来我想直接把OS代码嵌到应用程序中,但后来发现没有一个可以直接使用。

有的无法用KEIL直接编译,有的需要修改DLL在软件仿真下使用。

而我需要的是能在串口输入输出,不需要修改任何无关软件,能在软件仿真和硬件上运行的实时多任务操作系统。

没有办法,我只好硬着头皮去改编。

我分析了自己的劣势:

1。

KEIL刚开始使用,不太熟悉;

2。

混合编程以前从没有作过;

3。

时间紧迫,要在1个月内搞定。

而我的优势就是有5个移植实例可供参考,可以上网查资料。

一开始,我用“堆栈”、“混合编程”、“汇编”、“ucos”等关键字在C51BBS和老古论坛上检索相关信息并逐条阅读,读过之后,头脑中的思路逐渐清晰了。

我了解到在KEIL的HLP目录下有A51.PDF和C51.PDF非常全面的介绍了汇编和C51,是KEIL的权威用户手册;

SP初始化、内存清0等操作在STARTUP.A51文件中实现,用户可以改写它;

KEIL的变量,子程序等的分配信息可以在.M51文件里查到;

KEIL自己的论坛里有很多疑难问题的解答……通过阅读并经过思考,解决了堆栈起点、堆栈空间大小的设定等关键问题。

论坛里的问题有些是我没有想到的,这使我发现了自己的疏漏。

在网上获得大量信息后,我开始阅读《uCOSII》中文版,一共读了3遍。

第一遍是浏览,了解到uCOSII包括任务调度、时间管理、内存管理、资源管理(信号量、邮箱、消息队列)四大部分,没有文件系统、网络接口、输入输出界面。

它的移植只与4个文件相关:

汇编文件(OS_CPU_A.ASM)、处理器相关C文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。

有64个优先级,系统占用8个,用户可创建56个任务,不支持时间片轮转。

第二遍主要是把整个工作过程在头脑里过了一下,不懂地方有针对性的查书,重点是思考工作原理和流程。

我发现其实它的思路挺简单的。

就是“近似地每时每刻总是让优先级最高的任务处于运行状态”。

为了保证这一点,它在调用系统API函数、中断结束、定时中断结束时总是执行调度算法。

原作者通过事先计算好数据,简化了运算量,通过精心设计就绪表结构,使得延时可预知。

任务的切换是通过模拟一次中断实现的。

第三遍重点看了移植部分的内容。

对照实例,研究了代码的具体实现方法。

前期准备用了20几天,真正编写代码只用了1.5天,调试用了2天。

具体过程如下:

(1)拷贝书后附赠光盘sourcecode目录下的内容到C:

\YY下,删除不必要的文件和EX1L.C,只剩下p187(《uCOSII》)上列出的文件。

(2)改写最简单的OS_CPU.H

数据类型的设定见C51.PDF第176页。

注意BOOLEAN要定义成unsignedchar类型,因为bit类型为C51特有,不能用在结构体里。

EA=0关中断;

EA=1开中断。

这样定义即减少了程序行数,又避免了退出临界区后关中断造成的死机。

MCU-51堆栈从下往上增长(1=向下,0=向上),OS_STK_GROWTH定义为0

#defineOS_TASK_SW()OSCtxSw()因为MCU-51没有软中断指令,所以用程序调用代替。

两者的堆栈格式相同,RETI指令复位中断系统,RET则没有。

实践表明,对于MCU-51,用子程序调用入栈,用中断返回指令RETI出栈是没有问题的,反之中断入栈RET出栈则不行。

总之,对于入栈,子程序调用与中断调用效果是一样的,可以混用。

在没有中断发生的情况下复位中断系统也不会影响系统正常运行。

详见《uC/OS-II》第八章193页第12行

(3)改写OS_CPU_C.C

我设计的堆栈结构如下图所示:

*********************************************************************************

*

*----------

*|OSTCBCur|

*|

*|---------------------------------

*\---->

|OSTCBCur->

OSTCBStkPtr|SP---->

||

*---------------------------------

*|||

*|---------------------

*|||||.|

*|----------||.|

*|----------|----------

*||.|长度||+1

*||.||----------

*||.||OSStack---->

||0

*||||OSStkStart---->

|不关心|-1低地址

*\-------->

|长度|低地址系统堆栈

*用户堆栈长度=SP-OSStkStart

TCB结构体中OSTCBStkPtr总是指向用户堆栈最低地址,该地址空间内存放用户堆栈长度,其上空间存放系统堆栈映像,即:

用户堆栈空间大小=系统堆栈空间大小+1。

SP总是先加1再存数据,因此,SP初始时指向系统堆栈起始地址(OSStack)减1处(OSStkStart)。

很明显系统堆栈存储空间大小=SP-OSStkStart。

任务切换时,先保存当前任务堆栈内容。

方法是:

用SP-OSStkStart得出保存字节数,将其写入用户堆栈最低地址内,以用户堆栈最低地址为起址,以OSStkStart为系统堆栈起址,由系统栈向用户栈拷贝数据,循环SP-OSStkStart次,每次拷贝前先将各自栈指针增1。

其次,恢复最高优先级任务系统堆栈。

获得最高优先级任务用户堆栈最低地址,从中取出“长度”,以最高优先级任务用户堆栈最低地址为起址,以OSStkStart为系统堆栈起址,由用户栈向系统栈拷贝数据,循环“长度”数值指示的次数,每次拷贝前先将各自栈指针增1。

用户堆栈初始化时从下向上依次保存:

用户堆栈长度(15),PCL,PCH,PSW,ACC,B,DPL,DPH,R0,R1,R2,R3,R4,R5,R6,R7。

不保存SP,任务切换时根据用户堆栈长度计算得出。

OSTaskStkInit函数总是返回用户栈最低地址。

操作系统tick时钟我使用了51单片机的T0定时器,它的初始化代码用C写在了本文件中。

最后还有几点必须注意的事项。

本来原则上我们不用修改与处理器无关的代码,但是由于KEIL编译器的特殊性,这些代码仍要多处改动。

因为KEIL缺省情况下编译的代码不可重入,而多任务系统要求并发操作导致重入,所以要在每个C函数及其声明后标注reentrant关键字。

另外,“pdata”、“data”在uCOS中用做一些函数的形参,但它同时又是KEIL的关键字,会导致编译错误,我通过把“pdata”改成“ppdata”,“data”改成“ddata”解决了此问题。

OSTCBCur、OSTCBHighRdy、OSRunning、OSPrioCur、OSPrioHighRdy这几个变量在汇编程序中用到了,为了使用Ri访问而不用DPTR,应该用KEIL扩展关键字IDATA将它们定义在内部RAM中。

(4)重写OS_CPU_A.ASM

A51宏汇编的大致结构如下:

NAME模块名;

与文件名无关

;

定义重定位段必须按照C51格式定义,汇编遵守C51规范。

段名格式为:

?

PR?

函数名?

模块名

声明引用全局变量和外部子程序注意关键字为“EXTRN”没有‘E’

全局变量名直接引用

无参数/无寄存器参数函数FUNC

带寄存器参数函数_FUNC

重入函数_?

FUNC

分配堆栈空间

只关心大小,堆栈起点由keil决定,通过标号可以获得keil分配的SP起点。

切莫自己分配堆栈起点,只要用DS通知KEIL预留堆栈空间即可。

?

STACK段名与STARTUP.A51中的段名相同,这意味着KEIL在LINK时将把两个同名段拼在一起,我预留了40H个字节,STARTUP.A51预留了1个字节,LINK完成后堆栈段总长为41H。

查看yy.m51知KEIL将堆栈起点定在21H,长度41H,处于内部RAM中。

定义宏

宏名MACRO实体ENDM

子程序

OSStartHighRdy

OSCtxSw

OSIntCtxSw

OSTickISR

SerialISR

END;

声明汇编源文件结束

一般指针占3字节。

+0类型+1高8位数据+2低8位数据详见C51.PDF第178页

低位地址存高8位值,高位地址存低8位值。

例如0x1234,基址+0:

0x12基址+1:

0x34

(5)移植串口驱动程序

在此之前我写过基于中断的串口驱动程序,包括打印字节/字/长字/字符串,读串口,初始化串口/缓冲区。

把它改成重入函数即可直接使用。

系统提供的显示函数是并发的,它不是直接显示到串口,而是先输出到显存,用户不必担心IO慢速操作影响程序运行。

串口输入也采用了同样的技术,他使得用户在CPU忙于处理其他任务时照样可以盲打输入命令。

(6)编写测试程序Demo(YY.C)

Demo程序创建了3个任务A、B、C优先级分别为2、3、4,A每秒显示一次,B每3秒显示一次,C每6秒显示一次。

从显示结果看,显示3个A后显示1个B,显示6个A和2个B后显示1个C,结果显然正确。

显示结果如下:

AAAAAA111111isactive

BBBBBB333333isactive

AAAAAA11111

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 环境科学食品科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1