历史上的今天
今天是:2025年03月05日(星期三)
2020年03月05日 | ucosii在msp430F5239上的移植步骤
2020-03-05 来源:eefocus
移植浅谈:
学习MSP430时间不长,μC/OS-II原来只是听过,当时跑到stm32上带有GUI图形界面,当时感觉跑的很吃力,所以就没有学习它,直接去学习linux的开发,回过头来,发现linux也没有透彻的理解其中的核心,最近由于工作需求接触研究μC/OS-II,刚开始直接移植到Msp430编译都没有成功,觉得非常困难,无从下手,所以想先移植到stm32f103vct6的火牛开发板上,毕竟对这款单片机太熟悉不过了,从此网上找资料开始移植,最终移植成功,跑起来了,然后学习这个系统的各个功能,任务调度、信号量管理、事件标志组、邮箱、消息队列以及内存管理。这里略去STM32的移植步骤,网上太多了,下面开始移植到MSP430F5239这款单片机的移植之路。移植中也许会有错误,有什么问题,望大家不吝赐教。
第一步:准备工作
下载μC/OS-II源码;
网址:
http://micrium.com/downloadcenter/download-results/?searchterm=mp-uc-os-ii&supported=true
找到
点击红色区域下载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。
史海拾趣
|
本文章转自网络,本来想自己整理 但由于时间关系只能贴上原帖,这篇文章不错,教会大家如何看懂复杂难懂的datasheet 希望对大家有帮助 DS18B20时序 Author:exploer CIEE ,CAU 2008-9-16: 本文档参照M ...… 查看全部问答> |
|
(1)vxworks有一个 tickGet 函数可获取当前tick值,这个返回的是什么单位? SYS_CLK_RATE这个参数来设置1000,即系统时钟1秒发生1000次中断,两个时间差就是1ms,也就是1tick = 1ms. 那tickGet 两次调用后的差值是不 ...… 查看全部问答> |
|
我的目的是通过写一个空的设备dll,再写个上层的简单程序来访问我的设备驱动dll,就是一个简单的HelloWorld,看看对于dll入口和接口十否设计对,注册设备、上层访问,这3步能否走通。 我用EVC编译出一个dll,并通过EVC上载到设备上: cpp代码如下 ...… 查看全部问答> |
|
如题: TI官网提供了使用Stellaris加上TI cc3000 wifi芯片开发的方案. 下载连接为:http://www.ti.com/tool/cc3000-stellarissw其中Stellaris LM4F 使用WiFi连接方式,既可以作为Web Server服务器端,也可以作为客户端. Web server 服务器支持多个 ...… 查看全部问答> |
|
CH452按键扩展只要2个IO口实现16个用N5110液晶显示 用CH452驱动4*4矩阵键盘行列行列式+N5110液晶显示 CH452按键扩展只要2个IO口实现16个按键的扩展适合MSP430G2553用N5110液晶显示… 查看全部问答> |




