写在前面:
所需要下载的UCOSII代码链接:https://pan.baidu.com/s/1D_IyXhODEa5oVUdDv-GJrQ 提取码:mte3

本文结构

  • 1.UCOSII简介
  • 2.UCOSII移植具体步骤
  • 3.移植后的测试
  • 4.总结

1.UCOSII简介

UCOSII 是一个可以基于ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可
移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统
(RTOS)。

UCOSII 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C 语言编写的。CPU 硬
件相关部分是用汇编语言编写的、总量约200 行的汇编语言部分被压缩到最低限度,为的是便
于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C 交叉编译器,有汇编器、连
接器等软件工具,就可以将UCOSII 嵌人到开发的产品中。UCOSII 具有执行效率高、占用空间
小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。UCOSII 已经移植到了几
乎所有知名的CPU 上。

UCOSII体系结构如图所示

从上图可以看出,UCOSII 的移植,我们只需要修改:os_cpu.h、os_cpu_a.asm 和os_cpu.c
等三个文件,其中:os_cpu.h,进行数据类型的定义,以及处理器相关代码和几个函数原
型;os_cpu_a.asm,是移植过程中需要汇编完成的一些函数,主要就是任务切换函数;os_cpu.c,定义一些用户HOOK函数。

2.UCOSII移植具体步骤

新建基础工程,这里以跑马灯工程为例。
UCOSII移植具体步骤
1.在基础工程下建立相应的文件夹:CONFIG,CORE,PORT
新建UCOSII文件夹

UCOSII文件夹下新建三个文件夹

2.向core文件夹添加UCOSII的源码
在这个路径下,找到UCOSII的源码,也就是正点原子所带的软件资料:

6,软件资料\2,UCOS学习资料\UCOSII资料\UCOS II源码\Micrium\Software\uCOS-II\Source


将上面所有文件复制到CORE文件夹下,复制完的CORE文件夹下内容:

3.向CONFIG文件添加内容
此处的内容需要在该路径下找到,同样为正点原子所带的资料

4,程序源码\3,扩展例程\4,UCOS扩展例程\例1-1 UCOSII移植\UCOSII\CONFIG

添加好文件的CONFIG文件夹

4.向PORT文件夹下添加文件
文件路径:

4,程序源码\3,扩展例程\4,UCOS扩展例程\例1-1 UCOSII移植\UCOSII\PORT

添加完的PORT文件夹

5.将上述三个文件添加到工程中
打开工程
点击Manage Project Items,新建三个分组:UCOSII-CORE,UCOSII-CONFIG,UCOSII-PORT


向分组中添加文件
UCOSII-CORE分组添加如下,但是需要删除掉ucos_ii.c文件,否则会报错。

删除掉ucos_ii.c文件之后

UCOSII-PORT分组添加如下
只需要添加如下三个文件os_cpu.h和os_cpu_a.asm和os_cpu_c.c

UCOSII-CONFIG分组添加如下
添加includes.h和os_cfg.h文件

添加完成后会发现工程目录下多了三个文件夹

但是我们发现UCOSII-CORE文件下都是加锁的

解决办法是:找到CORE文件夹,更改文件夹属性:去掉只读

回过头来查看发现文件枷锁已经去掉

下面需要将路径包含进来
点击魔法棒,选择C/C++,找到include paths

点击后面的添加按钮

添加进来CORE,PORT,CONFIG文件

下面进行编译,发现报错

..\UCOSII\CORE\ucos_ii.h(44): error:  #5: cannot open source input file "app_cfg.h":
No such file or directory


双击该错误,进入到ucos_ii.h文件,找到该头文件,由于我们不需要该头文件,注释掉即可


然后再次编译
又发现另一个错误:PendSV_Handler 函数被重定义

..\OBJ\LED.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by os_cpu_a.o and stm32f10x_it.o).


解决办法:删除其中一个定义,由于汇编语言执行起来更快,所以删除stm32f10x_it.c文件下PendSV_Handler 函数的定义,这里采用注释掉的方法

先找到重定义的地方
os_cpu_a.asm这是一个汇编文件

在stm32f10x_it.c文件下

解决:注释掉

再次编译,发现没有错误

6.修改sys.h文件

打开该文件:位于SYSTEM文件夹下,找到sys.c文件

右击sys.h选择Open document sys.h

将SYSTEM_SUPPORT_OS 改为1,表示支持UCOS系统
修改前:

修改后:


再次编译,有报错:还是重定义的问题,同样的,这里我们还是注释掉stm32f10x_it.c文件下SysTick_Handler 函数

..\OBJ\LED.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by delay.o and stm32f10x_it.o).


再次编译发现没有错误
这里需要注意的是os_cpu_c.h文件夹下的OSTaskStkInit函数,当移植时发现和下面的不一致时,需要替换成下面的OSTaskStkInit函数。

/*
*********************************************************************************************************
*                                        INITIALIZE A TASK'S STACK
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
*              stack frame of the task being created.  This function is highly processor specific.
*
* Arguments  : task          is a pointer to the task code
*
*              p_arg         is a pointer to a user supplied data area that will be passed to the task
*                            when the task first executes.
*
*              ptos          is a pointer to the top of stack.  It is assumed that 'ptos' points to
*                            a 'free' entry on the task stack.  If OS_STK_GROWTH is set to 1 then
*                            'ptos' will contain the HIGHEST valid address of the stack.  Similarly, if
*                            OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
*                            of the stack.
*
*              opt           specifies options that can be used to alter the behavior of OSTaskStkInit().
*                            (see uCOS_II.H for OS_TASK_OPT_xxx).
*
* Returns    : Always returns the location of the new top-of-stack once the processor registers have
*              been placed on the stack in the proper order.
*
* Note(s)    : 1) Interrupts are enabled when your task starts executing.
*              2) All tasks run in Thread mode, using process stack.
*********************************************************************************************************
*/
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{OS_STK *stk;(void)opt;                                   /* 'opt' is not used, prevent warning                 */stk       = ptos;                            /* Load stack pointer                                 *//* Registers stacked as if auto-saved on exception    */*(stk)    = (INT32U)0x01000000L;             /* xPSR                                               */*(--stk)  = (INT32U)task;                    /* Entry Point                                        */*(--stk)  = (INT32U)0xFFFFFFFEL;             /* R14 (LR) (init value will cause fault if ever used)*/*(--stk)  = (INT32U)0x12121212L;             /* R12                                                */*(--stk)  = (INT32U)0x03030303L;             /* R3                                                 */*(--stk)  = (INT32U)0x02020202L;             /* R2                                                 */*(--stk)  = (INT32U)0x01010101L;             /* R1                                                 */*(--stk)  = (INT32U)p_arg;                   /* R0 : argument                                      *//* Remaining registers saved on process stack         */*(--stk)  = (INT32U)0x11111111L;             /* R11                                                */*(--stk)  = (INT32U)0x10101010L;             /* R10                                                */*(--stk)  = (INT32U)0x09090909L;             /* R9                                                 */*(--stk)  = (INT32U)0x08080808L;             /* R8                                                 */*(--stk)  = (INT32U)0x07070707L;             /* R7                                                 */*(--stk)  = (INT32U)0x06060606L;             /* R6                                                 */*(--stk)  = (INT32U)0x05050505L;             /* R5                                                 */*(--stk)  = (INT32U)0x04040404L;             /* R4                                                 */return (stk);
}

3.移植后的测试

下面进行UCOSII操作系统的测试
将下面代码复制到main.c中,替换掉原来的代码

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "includes.h"//START 任务
//设置任务优先级
#define START_TASK_PRIO         10  ///开始任务的优先级为最低
//设置任务堆栈大小
#define START_STK_SIZE          128
//任务任务堆栈
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);//LED0任务
//设置任务优先级
#define LED0_TASK_PRIO          7
//设置任务堆栈大小
#define LED0_STK_SIZE           64
//任务堆栈
OS_STK LED0_TASK_STK[LED0_STK_SIZE];
//任务函数
void led0_task(void *pdata);//LED1任务
//设置任务优先级
#define LED1_TASK_PRIO          6
//设置任务堆栈大小
#define LED1_STK_SIZE           64
//任务堆栈
OS_STK LED1_TASK_STK[LED1_STK_SIZE];
//任务函数
void led1_task(void *pdata);//浮点测试任务
#define FLOAT_TASK_PRIO         5
//设置任务堆栈大小
#define FLOAT_STK_SIZE          128
//任务堆栈
//如果任务中使用printf来打印浮点数据的话一点要8字节对齐
__align(8) OS_STK FLOAT_TASK_STK[FLOAT_STK_SIZE];
//任务函数
void float_task(void *pdata);int main(void)
{delay_init();       //延时初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断分组配置uart_init(115200);    //串口波特率设置LED_Init();      //LED初始化OSInit();       //UCOS初始化OSTaskCreate(start_task,(void*)0,(OS_STK*)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); //创建开始任务OSStart();   //开始任务
}//开始任务
void start_task(void *pdata)
{OS_CPU_SR cpu_sr=0;pdata=pdata;OSStatInit();  //开启统计任务OS_ENTER_CRITICAL();  //进入临界区(关闭中断)OSTaskCreate(led0_task,(void*)0,(OS_STK*)&LED0_TASK_STK[LED0_STK_SIZE-1],LED0_TASK_PRIO);//创建LED0任务OSTaskCreate(led1_task,(void*)0,(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-1],LED1_TASK_PRIO);//创建LED1任务OSTaskCreate(float_task,(void*)0,(OS_STK*)&FLOAT_TASK_STK[FLOAT_STK_SIZE-1],FLOAT_TASK_PRIO);//创建浮点测试任务OSTaskSuspend(START_TASK_PRIO);//挂起开始任务OS_EXIT_CRITICAL();  //退出临界区(开中断)
}//LED0任务
void led0_task(void *pdata)
{while(1){LED0=0; delay_ms(80);LED0=1;delay_ms(100);}
}//LED1任务
void led1_task(void *pdata)
{while(1){LED1=0;delay_ms(300);LED1=1;delay_ms(300);}
}//浮点测试任务
void float_task(void *pdata)
{OS_CPU_SR cpu_sr=0;static float float_num=0.01;while(1){float_num+=0.01f;OS_ENTER_CRITICAL();  //进入临界区(关闭中断)printf("float_num的值为: %.4f\r\n",float_num); //串口打印结果OS_EXIT_CRITICAL();      //退出临界区(开中断)delay_ms(500);}
}

编译之后没有错误,下载到开发板上

开发板出现led灯的交替闪烁,
再进行串口测试,也就是浮点测试:每个500ms进行+0.01的操作

至此,UCOSII操作系统移植成功。

4.总结

1) 移植UCOSII

要想UCOSII在STM32正常运行,首先是需要移植UCOSII,正点原子提供的SYSTEM文件夹里面的系统函数直接支持UCOSII,只需要在sys.h文件里面将:SYSTEM_SUPPORT_UCOS宏定义改为1,即可通过delay_init函数初始化UCOSII的系统时钟节拍,为UCOSII提供时钟节拍。

2) 编写任务函数并设置其堆栈大小和优先级等参数。
编写任务函数,以便UCOSII调用。
设置函数堆栈大小,需要根据函数的需求来设置,如果任务函数的局部变量多,嵌套层数多,那么相应的堆栈就得大一些,如果堆栈设置小了,很可能出现的结果就是CPU进入HardFault,遇到这种情况,就必须把堆栈设置大一点了。另外,有些地方还需要注意堆栈字节对齐的问题,如果任务运行出现莫名其妙的错误(比如用到sprintf出错),请考虑是不是字节对齐的问题。
设置任务优先级,这个需要根据任务的重要性和实时性设置,记住高优先级的任务有优先使用CPU的权利。

3) 初始化UCOSII,并在UCOSII中创建任务
调用OSInit初始化UCOSII,通过调用OSTaskCreate函数创建任务。

4) 启动UCOSII
调用OSStart启动UCOSII。
通过以上4个步骤,UCOSII就开始在STM32上面运行。

STM32迷你板UCOSII系统移植相关推荐

  1. 基于全志A33开发板linux系统移植学习记录(Boot0)

    基于全志A33开发板linux系统移植学习记录 第一章 Boot0基于ARMGCC的编译与修改 文章目录 基于全志A33开发板linux系统移植学习记录 前言 一.全志A33简介以及上电引导流程 二. ...

  2. 【来袭】iTOP-3568开发板Android11系统移植视频教程

    迅为电子嵌入式视频教程更新啦!这次新推出了「Android11系统移植篇」,目前共计25讲,后续还会继续添加视频,完善内容.想学习这方面知识的小伙伴赶紧一睹为快吧! 迅为以iTOP-RK3568开发板 ...

  3. 基于ARM的COTEX-A9系列开发板的系统移植

    在原始的板子上是没有操作系统的,如果能够在板子上装上操作系统就可以在板子上运行程序,以linux系统为例. 一,使用TFTP服务下载操作系统文件 想要在开发板上运行操作系统得先将所需要得操作系统映像文 ...

  4. 基于STM32的uc/OS系统移植及用Saleae Logic 16抓取分析波形

    文章目录 一.关于uc/OS系统 1.操作系统与裸机的区别 2.uc/OS运行流程 二.详细移植过程 1.STM32Cubex创建工程 2.为工程添加源码 3.添加头文件路径 4.添加代码 1)bsp ...

  5. 玩转开发板--Linux系统移植至开发板fl2440实践过程

    一.开发板介绍     CPU:S3C2440(SAMSUNG).ARM920T.400MHz     Pone/mic:耳机和话筒 JTAG:可以通过外部插入直接控制CPU,因此在初始化内存时,起到 ...

  6. iTOP-4418开发板Linux系统移植modbus

    首先确保开发板和虚拟机 Ubuntu 可以 ping 通,如下图所示,作者虚拟机的 IP 为"192.168.2.200" 通过开发板可以 ping 通 Ubuntu. 其次,注意 ...

  7. uc-osII系统移植

    任务调度 ucosii 为保证实时性,给每个任务分配一个不同的优先级.当发生任务切换时, 总是切换到就绪的最高优先级任务.有 2 种情况会发生任务切换. 1.任务等待资源就绪或自我延时: 2.退出中断 ...

  8. iTOP-4418开发板Linux系统移植modbus-arm的测试程序

    进入目录/home/minilinux/libmodbus-3.1.4/tests/,查看测试程序 random-testserver.c,如下图所示 已经编译出来了,但是还是需要修改一下源码中的几个 ...

  9. STM32无系统移植CanFestival小白教程

    首先,如果对CANOPEN的一些基本概念不懂的话,先去看看<CANopen轻松入门>,看了那么多资料觉得这个写得最好. 链接:https://pan.baidu.com/s/1KxO_TO ...

最新文章

  1. 对象的引用和clone
  2. web项目性能优化--网络、js、渲染
  3. 【邓侃】哈佛大学机器翻译开源项目 OpenNMT的工作原理
  4. Haroopad安装与配置: Linux系统下最好用的Markdown编辑器
  5. from mysql_MySQL的FROM
  6. 零起步的Hadoop实践日记(更改hadoop数据存储位置)
  7. 真正厉害的人,早就戒掉了“贫穷思维”
  8. 同学,要开学了,你的导师也很焦虑
  9. 系统架构师学习笔记-软件架构设计
  10. Python 机器学习 随机森林 天气最高温度预测任务(二)
  11. springcloud基于ribbon的canary路由方案 1
  12. mobilenet cpu 加速_UP手游加速器苹果版下载安装-UP手游加速器iOS苹果版下载
  13. Zemax操作25--像差理论和修正(球差、慧差、像散)
  14. html旋转相册,css3 旋转相册
  15. Oracle 实验:建立和配置Oracle数据库服务器
  16. 【实例】VBA excel 隔行插入行与列
  17. oracle 查找不重复的数据,oracle不用distinct查找不重复记录和删除重复记录
  18. 802.11协议帧间间隔-SIFS,DIFS,PIFS,EIFS
  19. Kafka Broker
  20. Gitte (https://gitee.com/) 常用git指令--实例

热门文章

  1. C#_List转换成DataTable
  2. Android上下左右滑动,显示底层布局
  3. jQuery 人脸识别插件,支持图片和视频
  4. gdbserver yum 安装_(OK) 编译cBPM—CentOS7—gdb—gdbserver—成功—调试
  5. python自动创建目录_python自动目录环境
  6. 0.0 目录-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  7. C++中类的多态与虚函数的使用
  8. Android + kernel USB host 如何判断插入的设备是高速还是低速的设备
  9. 【LSTM】基于LSTM网络的人脸识别算法的MATLAB仿真
  10. 异部时钟电路的FPGA设计