"); //-->
之前我并没有实际用过uCOS,就知道这个操作系统相对比较简单,用户熟悉其原理和移植同样也比较容易,适合刚接触多任务操作系统的人进行学习。去年瑞萨在EEPW送了一批SH7125的评估板,也有瑞萨的工程师专门将uCOS移植到SH7125上,同时共享有演示工程和简单说明,虽然工程可以直接编译运行,但对于刚接触uCOS的朋友还是难以知道到底应该如何移植uCOS,这里我对移植说几点个人看法,以帮助大家进一步理解移植过程。
1.
多任务操作系统都是通过软件方式实现的,uCOS也一样,当操作系统启动后,会先把一个段后台管理程序运行起来,然后利用这段管理程序来进行任务的切换管理。uCOS是要用户自己写一个函数,函数中调用后台管理程序,再将这个函数放到一个每秒10~100次的定时中断中,这样就保证了后台管理程序的持续运行。
2.
移植工作相对比较简单,只需要用户编写几个规定的函数,再和uCOS官方基础移植包一起编译就已完成,代码的工作量并不大。
通常需要用户自己编写这几个源文件,也可以不用下面的名字,但为了规范统一最好还是用约定的名字。文件是OS_CPU.H、OS_CPU_C.C和OS_CPU_A.ASM。
2.1.
OS_CPU.H用来定义uCOS需要的几个宏定义,这些宏会在移植包中用到。
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
//定义uCOS约定的变量类型,避免不同平台编译得到不同宽度的数据类型
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U;
typedef signed short INT16S;
typedef unsigned long INT32U;
typedef signed long INT32S;
typedef float FP32;
typedef double FP64;
typedef unsigned long OS_STK;
#define BYTE INT8S
#define UBYTE INT8U
#define WORD INT16S
#define UWORD INT16U
#define LONG INT32S
#define ULONG INT32U
#define OS_CRITICAL_METHOD 1
#if (OS_CRITICAL_METHOD == 1)
#define OS_ENTER_CRITICAL() set_imask(15) //屏蔽所有的中断,uCOS调用这个宏来关中断
#define OS_EXIT_CRITICAL() set_imask(0) // 打开中断,uCOS调用这个宏来开中断
#endif
#define OS_STK_GROWTH 1 // uCOS通过这个宏来决定堆栈的操作方向,1为向下,0为向上
#define OS_TASK_SW() trapa(32) // uC/OS-II context switch
// 声明os_cpu_a.src中的函数,留意这里对应OS_CPU_A.ASM,瑞萨汇编文件扩展名是.src
#pragma interrupt OSCtxSw
extern void OSCtxSw(void); // 任务切换
#pragma interrupt OSTickISR
extern void OSTickISR(void); // 定时器中断,每秒10~100次的定时中断需要调用这个函数
extern void OSStartHighRdy(void); // 开始任务
extern void OSIntCtxSw(void); // 中断任务切换
2.2.
OS_CPU_C.C需要编写这六个函数,后五个函数可以为空函数。
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
#if (OS_CPU_HOOKS_EN > 0)
void OSTaskCreateHook (OS_TCB *ptcb)
void OSTaskDelHook (OS_TCB *ptcb)
void OSTaskSwHook (void)
void OSTaskStatHook (void)
void OSTimeTickHook (void)
#endif // OS_CPU_HOOKS_EN > 0
这些HOOK函数是uCOS留给用户扩展功能的接口,在一些特定的系统函数中会调用这些函数,这样就可以从相应系统函数中跳出来执行用户自己的代码,执行完再返回系统函数,所以用户移植时必须提供这几个函数,不然编译无法通过。
第一个函数是任务初始化函数,这是瑞萨SH7125的具体代码,可以把所有内容都改为0,uCOS每个任务都会用一段RAM来保存自己的寄存器内容,切换到下一个任务之前会把当前的寄存器内容都保存在这段RAM中,从别的任务切换回来又会从这段RAM中把所有寄存器内容都恢复,这样就可以保证后面的代码能继续正常运行。
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
OS_STK *stk; // OS_STK是在OS_CPU.H中定义的
opt = opt;
stk = (OS_STK *)ptos;
*stk-- = 0x00000000; /* SR 任务启动后允许中断(interrupt mask bits set to 0) */
*stk-- = (OS_STK)task; /* PC */
*stk-- = 0xeeeeeeee; /* R14 */
*stk-- = 0xdddddddd; /* R13 */
*stk-- = 0xcccccccc; /* R12 */
*stk-- = 0xbbbbbbbb; /* R11 */
*stk-- = 0xaaaaaaaa; /* R10 */
*stk-- = 0x99999999; /* R9 */
*stk-- = 0x88888888; /* R8 */
*stk-- = 0x77777777; /* R7 */
*stk-- = 0x66666666; /* R6 */
*stk-- = 0x55555555; /* R5 */
*stk-- = (OS_STK)pdata; /* R4 */
*stk-- = 0x33333333; /* R3 */
*stk-- = 0x22222222; /* R2 */
*stk-- = 0x11111111; /* R1 */
*stk-- = 0x00000000; /* R0 */
*stk-- = 0x11000000; // GBR
*stk-- = 0x22000000; // MACH
*stk-- = 0x33000000; // MACL
*stk = 0x44000000; // PR
return ((OS_STK *)stk);
}
2.3.
OS_CPU_A.ASM需要编写void OSCtxSw(void)、void OSTickISR(void)、void OSStartHighRdy(void)和void OSIntCtxSw(void)四个函数,OSCtxSw由uCOS的32号软中断调用,OSTickISR直接由硬件定时中断调用。OS_CPU_A.ASM中的四个函数可以直接放到OS_CPU_C.C中,但用C代码效率会不好,最好还是用汇编代码来编写。
这几个函数是汇编编写的,这里就不做解释。
3.
在SH7125上建立一个带uCOS的大致流程。
3.1.
按照SH7125评估板所带光盘上的说明文档先建立一个工程。
3.2.
按照SH7125评估板所带光盘上的说明文档修改工程的配置参数,找到main()函数,随便加入一些代码能够编译下载执行。
3.3.
把uCOS的移植基础包中的文件全复制到工程所在目录下,并将所有C文件加入工程,要注意的是这些文件在#include时是用<>,需要改为""。
3.4.
自己编写OS_CPU.H、OS_CPU_C.C和OS_CPU_A.ASM这三个文件,具体内容可参考瑞萨提供的工程。
3.5.
自己编写硬件初始化的相关函数,最重要的是初始化好定时中断,函数放置位置不限,可以在进入main()之后马上调用。
3.6.
把OSTickISR函数挂到对应定时中断上。
3.7.
修改OS_CFG.H中的宏定义,只要看名字和说明就知道相应作用,完成对uCOS功能的配置。
3.8.
按下面方式创建任务
OS_STK task1_stack[100]; // 任务栈
void task1(void *pdata)
{
pdata = pdata;
set_imask(0); // 开总中断
MTU2.TSTR.BIT.CST0 = 1; // 启动定时器
while(1){
PE.DRL.BIT.B13 = 1;
OSTimeDlyHMSM(0, 0, 1, 0);
PE.DRL.BIT.B13 = 0;
OSTimeDlyHMSM(0, 0, 1, 0);
}
}
void main(void)
{
// 要先初始化硬件
OSInit();
OSTaskCreate(task1, (void *)0, &task1_stack[100 - 1], TSK1_PRIO);
OSStart();
}
到此对于uCOS在SH7125上的移植就基本完成,建议不要用瑞萨已经移植好的工程改,而是先自己创建一个新的空工程,再用对照瑞萨的工程逐步添加修改,这样才知道到底哪些地方需要自己进行修改。当自己创建的工程能跑起来,再去尝试修改代码,最后将所有移植地方的代码都弄懂。
附件一:
uCOS移植参考文档
第8章.doc
附件二:
瑞萨提供的uCOS演示工程
sh_stick_ucosii.rar
附件三:
uCOS官方移植包V2.84(只供参考,不要用此版本进行移植)
ucos_ii284.rar
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。
1500536942 阅读:2444
eleaction01 阅读:3716