μC/OS-II在C8051F上的移植

来源:本站
导读:目前正在解读《μC/OS-II在C8051F上的移植》的相关信息,《μC/OS-II在C8051F上的移植》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《μC/OS-II在C8051F上的移植》的详细说明。
简介:文章简单介绍了μC/OS-II在C8051F上的移植

在嵌入式应用中,使用RTOS的最主要原因是提高系统的可靠性,其次是提高开发效率、缩短开发周期。μC/OS-II 是一个基于优先级的抢占式实时内核,支持56 个用户任务,90%的代码使用标准的ANSI C语言书写,程序可读性强,移植性好,代码可固化,可裁剪,非常灵活。C8051F是美国Cygnal公司生产的与51系列兼容的微控制器,流水线指令结构70%的指令的执行时间为1个或2个系统时钟周期。当时钟频率为25MHz时,速度可达25MIPS,是一款不错的片上系统。

1 开发工具和运行环境

实现μC/OS-II的移植,要求所用的C编译器支持混合编程。KEIL C51可为众多的8051派生器件编程。我们选用的是KEIL7.02集成开发环境,仿真板基于C8051F015芯片。

2 移植中所需修改的文件

和CPU相关的文件主要有三个,分别是汇编文件OS_CPU_A.ASM、C语言文件 OS_CPU_C.C和头文件OS_CPU.H。

2.1 OS_CPU.H文件

OS_CPU.H文件中定义了数据类型及与硬件相关的基本信息。其中改动部分如下:

typedef unsigned char OS_STK; /* 堆栈的宽度为8位 */

OS_CPU_EXT INT8U IE_SHADOW;

#define OS_ENTER_CRITICAL() IE_SHADOW = IE; IE &= 0x7F /* 关中断 */

#define OS_EXIT_CRITICAL() IE = IE_SHADOW

/* 恢复中断 */

#define OS_STK_GROWTH 0

#define OS_TASK_SW() OSCtxSw()

在C8051F中,堆栈都是按字节操作的,故数据类型OS_STK声明为8位。方向从低地址向高地址方向递增,所以OS_STK_GROWTH设置为0。μC/OS-II在进入系统临界代码区之前要关中断,等到退出临界区后再打开,以保护核心数据不被多任务环境下的其它任务或中断破坏。开、关中断可通过设置SFR中的中断屏蔽位实现。在关中断时,先将IE的内容保存在全局变量IE_ SHADOW中,然后关中断;退出临界区时,还原IE_SHADOW的值。OS_TASK_SW()用来实现任务切换。就绪任务的堆栈初始化应该模拟一次中断发生后的样子,堆栈中应该按入栈次序设置好各个寄存器。OS_TASK_SW()函数模拟一次中断过程,在中断返回的时候进行任务切换。由于C8051F015没有软中断,故直接定义宏OS_TASK_SW()为函数OSCtxSw()。

2.2 OS_CPU_A.ASM文件

编译器将每个文件作为一个模块,编译模块以主名命名,称为编译模块名,用NAME 来声明。因此,应在文件头部声明NAME OS_CPU_A。

函数有程序部分和局部变量部分,它们分别放在独立的段中。在大模式下,段名声明的固定格式为 ?PR?函数名?模块名 SEGMENT CODE。因此需要将OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()和OSTickISR()用上面的格式一一声明。如?PR?OSStartHighRdy?OS_CPU_A SEGMENT CODE,本模块实现的函数需要用PUBLIC声明,如PUBLIC OSStartHighRdy等。

C51将所有定义说明的数据标识符转换为大写字符,对函数则根据有无寄存器参数传送和函数是否可重入进行换名,如:void OSIntEnter(void) reentrant函数的名字OSIntEnter换成_?OSIntEnter。这些规则可从编译后的LST文件中看出。程序中声明引用的五个全局变量为OSTCBCur、OSTCBHighRdy、OSRunning、OSPrioCur、OSPrioHighRdy,声明格式是EXTRN IDATA (OSTCBCur)等。调用四个外部子程序OSTaskSwHook()、OSIntEnter()、OSIntExit()、OSTimeTick(),固定格式为:EXTRN CODE (_?OSTaskSwHook)等。

由于C8051F的堆栈指针只有8位,只能指向内部数据区的256个字节,因此,当前运行的任务的堆栈在IDATA区,堆栈大小为40H(64字节),堆栈起点由KEIL决定。通过标号可以获得KEIL分配的SP起点,代码如下:

?STACK SEGMENT IDATA

RSEG ?STACK

OSStack:

DS 40H

OSStkStart IDATA OSStack-1

为简化子程序特定义压栈出栈宏。压栈的次序为PSW、ACC、B、DPL、DPH、R0~R7,出栈的次序与入栈相反。

PUSHALL MACRO

IRP REG, <PSW,ACC, B, DPL, DPH, 0, 1, 2, 3, 4, 5, 6, 7>

PUSH REG

ENDM

POPALL MACRO

IRP REG, <7, 6, 5, 4, 3, 2, 1, 0, DPH, DPL, B, ACC, PSW>

POP REG

ENDM

2.3 OS_CPU_C.C文件

移植μC/OS-II 需要在OS_CPU_C.C中定义六个函数,而实际上需要定义的只有OSTaskStkInit()一个函数。该函数用来初始化任务的堆栈。初始状态的堆栈只须初始化?C_XBP (仿真堆栈指针)、任务地址及堆栈的长度。由于只有INC DPTR指令,故返回栈的最低地址,且最低地址处存放栈的长度,方便用汇编语言实现任务的切换。堆的大小可根据任务的实际情况自行确定,由参数ppdata所指的值确定。

void *OSTaskStkInit (void (*task)(void *pd), void *ppdata,

void *ptos, INT16U opt) reentrant

{

OS_STK *stk;

INT8U HeapSize;

HeapSize=*(INT8U *)ppdata;

opt = opt;

stk = (OS_STK *)ptos+HeapSize+2;

*stk++ = 15;

*stk++ = (INT16U)task & 0xFF;

*stk++ = (INT16U)task >> 8;

stk = (OS_STK *)ptos+HeapSize+2;

*--stk = (INT16U) (ptos+HeapSize-1) >> 8;

*--stk = (INT16U) (ptos+HeapSize-1) & 0xFF;

return ((void *)stk);

}

3 可重入函数

因为51系列堆栈空间的限制, KEIL编译器没有像大系统那样使用调用堆栈。一般C语言调用过程中,会把过程的参数和使用的局部变量入栈。为了提高效率,编译器没有提供这种堆栈,而是提供一种压缩栈,每个过程被给定一个空间用于存放局部变量。过程中的每个变量都放在这个空间的固定位置,当递归调用这个过程时,会导致变量被覆盖。编译器允许将函数定义成可重入函数,由reentrant关键字指定,可重入函数可被单独保存。因为这些堆栈是模拟的,可重入函数一般都比较大,运行起来也比较慢。模拟栈不允许传递bit类型的变量,也不能定义局部位标量。移植中最好是将可能被多个任务使用的函数定义成可重入函数。

提醒:《μC/OS-II在C8051F上的移植》最后刷新时间 2024-03-14 01:05:23,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《μC/OS-II在C8051F上的移植》该内容的真实性请自行鉴别。