微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > uCOS51移植心得

uCOS51移植心得

时间:09-12 来源:互联网 点击:

题的,反之中断入栈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位数据 详

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top