×
单片机 > 单片机程序设计 > 详情

ucosii在msp430F5239上的移植步骤

发布时间:2020-08-21 发布时间:
|

移植浅谈:


学习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  移植步骤 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
用Atmega 16单片机驱动字符型液晶显示芯片