移植浅谈:
学习MSP430时间不长,μC/OS-II原来只是听过,当时跑到stm32上带有GUI图形界面,当时感觉跑的很吃力,所以就没有学习它,直接去学习linux的开发,回过头来,发现linux也没有透彻的理解其中的核心,最近由于工作需求接触研究μC/OS-II,刚开始直接移植到Msp430编译都没有成功,觉得非常困难,无从下手,所以想先移植到stm32f103vct6的火牛开发板上,毕竟对这款单片机太熟悉不过了,从此网上找资料开始移植,最终移植成功,跑起来了,然后学习这个系统的各个功能,任务调度、信号量管理、事件标志组、邮箱、消息队列以及内存管理。这里略去STM32的移植步骤,网上太多了,下面开始移植到MSP430F5239这款单片机的移植之路。移植中也许会有错误,有什么问题,望大家不吝赐教。
第一步:准备工作
下载μC/OS-II源码;
点击红色区域下载MSP430F5438的源码。
下载编译工具:
网上下载IAR For MSP430我这里版本是5.60.7,老版本可能不支持这款芯片,注意区分。
第二步:开始移植
建立好文件夹
首先在你的工作路径建立一个文件,这里我建在D盘,名称:“MSP430_Ucosii”,这个大家任意起名都可以;然后在“D: MSP430_Ucosii”下建立“src”;即“D:MSP430_Ucosiisrc”;这里主要是为了方便管理源码,然后在src文件下建立4个文件夹,分别是 。
其中app下主要是用户的文件,主要是业务和主函数;bsp下主要是用户的驱动源码,ucos_kernal下主要是ucosii的内核文件,这里的文件几乎不用作修改,ucos_port下是跟cpu有关的文件,移植需要修改。
拷贝需要的文件
下载的uCOS-II-MSP-EXP430F5438.exe进行解压缩,假设解压在“D:”下,解压后名称“Micrium”;
拷贝:
“D:MicriumSoftwareuCOS-IISource”下所有文件和D:MicriumSoftwareEvalBoardsTIMSP-EXP430F5438IARuCOS-II”的“os_cfg.h”复制到“D: MSP430_Ucosiisrcucos_kernal”
拷贝:
D:MicriumSoftwareuCOS-IIPortsMSP430XIARMSP430x5xx下所有文件复制到“D: MSP430_Ucosiisrcucos_port”下;
拷贝:
“D:MicriumSoftwareuCOS-IISource”下所有文件和D:MicriumSoftwareEvalBoardsTIMSP-EXP430F5438IARuCOS-II”的“includes.h”拷贝到“D: MSP430_Ucosiisrcapp”下。
至此拷贝工作告一段落。
建立工程。
打开IAR软件,选择新建工程,Project->Creat New Project保存到我们建立的“D: MSP430_Ucosii”下,起个名字即可,然后
建立四个group,并把当时拷贝好的四个文件夹下文件Add到上面4个工作组里,并在app文件下新建个app.c,添加到app工作组中。最终效果如下 。
配置工程
右击红色位置,选择第一个options,修改Device为我们要移植的单片机,这里选择5239的单片机,然后在C/C++ Compiler 下的Preprocessor添加路径如下图。
5、修改与CPU有关的部分,也是重点。
我们需要关注的是与处理器相关的的代码,也就是前面所说的ucosii_port文件夹下的几个文件:OS_CPU.H、OS_CPU_C.C、OS_CPU_A.S43。
5.1 OS_CPU.H
此文件主要包括与处理器相关的常量、宏及结构体的定义。
A.设置数据长度。
由于不同微处理器的字长都不同,这里就要定义一些数据类型。主要是更改OS_STK设置为16位以及OS_CPU_SR状态寄存器。主要定义如下:
B、设置开关中断方法。
为了隐蔽编译器厂商提供不同的实现方法,增加一致性,这里用两个宏来禁止和允许中断:OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()。为了访问临界区必须先禁止中断,在访问代码临界区,最后在打开中断。在源码中给出了3种中断方法。代码如下,主要通过宏定义选择哪一种。
这里选择第三种方法,执行 OS_ENTER_CRITICAL()的第三种方法是先将中断关闭的状态保存到堆栈中,然后关闭中断。与之对应的 OS_EXIT_CRITICAL()的操作是从堆栈中恢复中断状态。采用此方法,不管用户是在中断关闭还是允许的情况下调用µC/OS-Ⅱ中的函数,在调用过程中都不会改变中断状态。这里我们选择方法3。
C.设置栈的增长方向
MSP430 处理器的堆栈是由高地址向低地址方向增长的,所以常量 OS_STK_GROWTH 必须设置为 1。
D.任务切换宏OS_TASK_SW()
在 µC/OS-II中, 就绪任务的堆栈初始化应该模拟一次中断发生后的样子,堆栈中应该按进栈次序设置好各个寄存器的内容。OS_TASK_SW()函数模拟一次中断过程,在中断返回的时候进行任务切换。中断服务程序(ISR)的入口点必须指向汇编函数OSCtxSw()(请参看文件OS_CPU_A.s43)。
5.2 OS_CPU_C.C
µC/OS-II 的移植需要用户改写OS_CPU_C.C中的10个函数:
OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskIdleHook()
OSTaskStatHook()
OSTimeTickHook()
OSInitHookBegin()
OSInitHookEnd()
OSTCBStkInit()
实际需要修改的只有 OSTaskStkInit()函数,其他9个函数是接口,需要声明,但不一定有实际内容。这9个函数都是用户定义的,所以 OS_CPU_C.C 中没有给出代码。如果用户需要使用这些函数,请将文件 OS_CFG.H 中的#defineconstant OS_CPU_HOOKS_EN 设为 1,设为 0 表示不使用这些函数。
OSTaskStkInit()函数修改如下:
该函数由OSTaskCreate()或OSTaskCreateExt()调用,用来初始化任务的堆栈。初始状态的堆栈模拟发生一次中断后的堆栈结构。当调用OSTaskCreate()或OSTaskCreateExt()创建一个新任务时,需要传递的参数是:任务代码的起使地址,参数指针(pdata) ,任务堆栈顶端的地址,任务的优先级。OSTaskCreateExt()还需要一些其他参数,但与OSTaskStkInit()没有关系。OSTaskStkInit(),只需要以上提到的3个参数(task, pdata,和ptos)。
5.3 OS_CPU_A.S43
这个是汇编代码,主要是写了几个与硬件相关的代码,为了提高内核的效率和速度,我们最好使用汇编来编写任务调度代码。
1 让优先级最高的就绪任务开始运行函数OSStartHighRdy();
2 中断级任务切换函数OSIntCtxSw();
3 任务级任务切换函数OS_TASK_SW();
4 中断服务子程序OSTickISR()。
5 关中断函数OS_ENTER_CRITICAL (OS_CPU_SR_Save)
6 开中断函数OS_EXIT_CRITICAL (OS_CPU_SR_Restore)
这里在5438移植文件已经定义好,这里不再修改,直接添加进我们的库里就可以了。至此修改与CPU相关的就完成了。
至此工程配置完成,下面进行源码的移植。
添加源码
在新建的app.c下编写主函数。
#include"includes.h"
#defineTASK1_STK_SIZE 256
#defineTASK2_STK_SIZE 256
OS_STK Task1STK[TASK1_STK_SIZE];
OS_STK Task2STK[TASK2_STK_SIZE];
void Task1 (void *pdata); /* 前导声明任务(函数) */
void Task2 (void *pdata);
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; /* 禁止看门狗 */
OSInit(); /* 初始化uCOS-II */
WDTCTL = WDT_MDLY_32; /* 设置时钟节拍间隔为32ms */
SFRIE1 |= 1; /* 开看门狗定时器中断 */
P6DIR = 0x03;
P6OUT = 0x00;
OSTaskCreate(Task1, (void *)0, &Task1STK[TASK1_STK_SIZE- 1], 5);
OSTaskCreate(Task2, (void *)0,&Task2STK[TASK2_STK_SIZE - 1], 6);
OSStart(); /* 开始任务调度 */
}
void Task1 (void *pdata)
{
while(1)
{
P6OUT |= (1<<0);
OSTimeDly(10); /* 延时10个时钟节拍,挂起本任务等待延时结束 */
P6OUT &= ~(1<<0);
OSTimeDly(10); /* 延时10个时钟节拍,挂起本任务等待延时结束 */
}
}
void Task2 (void *pdata)
{
while(1)
{
P6OUT |= (1<<1);
OSTimeDly(10); /* 延时10个时钟节拍,挂起本任务等待延时结束 */
P6OUT &= ~(1<<1);
OSTimeDly(10); /* 延时10个时钟节拍,挂起本任务等待延时结束 */
}
}
然后在include.h下添加#include
上面代码主要是执行两个任务,分别点灯来演示ucosii最基本的任务,其中我用的时P60和P61来点灯,你可以改成其他的端口测试。
编译下载
编译下载后下载到单片机,两个LED同时以1s的频率闪烁,至此,ucosii系统移植结束,编译完只有6k,可谓是小之又小,这里说明下,我这里移植的主要是ucosii的内核,没有GUI部分,如果加上它,可能就很难移植进来了,这里这款单片机的RAM只有8K,Flash有128k。
关键字:ucosii msp430F5239 移植步骤『本文转载自网络,版权归原作者所有,如有侵权请联系删除』