STM32迷你板UCOSII系统移植
写在前面:
所需要下载的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系统移植相关推荐
- 基于全志A33开发板linux系统移植学习记录(Boot0)
基于全志A33开发板linux系统移植学习记录 第一章 Boot0基于ARMGCC的编译与修改 文章目录 基于全志A33开发板linux系统移植学习记录 前言 一.全志A33简介以及上电引导流程 二. ...
- 【来袭】iTOP-3568开发板Android11系统移植视频教程
迅为电子嵌入式视频教程更新啦!这次新推出了「Android11系统移植篇」,目前共计25讲,后续还会继续添加视频,完善内容.想学习这方面知识的小伙伴赶紧一睹为快吧! 迅为以iTOP-RK3568开发板 ...
- 基于ARM的COTEX-A9系列开发板的系统移植
在原始的板子上是没有操作系统的,如果能够在板子上装上操作系统就可以在板子上运行程序,以linux系统为例. 一,使用TFTP服务下载操作系统文件 想要在开发板上运行操作系统得先将所需要得操作系统映像文 ...
- 基于STM32的uc/OS系统移植及用Saleae Logic 16抓取分析波形
文章目录 一.关于uc/OS系统 1.操作系统与裸机的区别 2.uc/OS运行流程 二.详细移植过程 1.STM32Cubex创建工程 2.为工程添加源码 3.添加头文件路径 4.添加代码 1)bsp ...
- 玩转开发板--Linux系统移植至开发板fl2440实践过程
一.开发板介绍 CPU:S3C2440(SAMSUNG).ARM920T.400MHz Pone/mic:耳机和话筒 JTAG:可以通过外部插入直接控制CPU,因此在初始化内存时,起到 ...
- iTOP-4418开发板Linux系统移植modbus
首先确保开发板和虚拟机 Ubuntu 可以 ping 通,如下图所示,作者虚拟机的 IP 为"192.168.2.200" 通过开发板可以 ping 通 Ubuntu. 其次,注意 ...
- uc-osII系统移植
任务调度 ucosii 为保证实时性,给每个任务分配一个不同的优先级.当发生任务切换时, 总是切换到就绪的最高优先级任务.有 2 种情况会发生任务切换. 1.任务等待资源就绪或自我延时: 2.退出中断 ...
- iTOP-4418开发板Linux系统移植modbus-arm的测试程序
进入目录/home/minilinux/libmodbus-3.1.4/tests/,查看测试程序 random-testserver.c,如下图所示 已经编译出来了,但是还是需要修改一下源码中的几个 ...
- STM32无系统移植CanFestival小白教程
首先,如果对CANOPEN的一些基本概念不懂的话,先去看看<CANopen轻松入门>,看了那么多资料觉得这个写得最好. 链接:https://pan.baidu.com/s/1KxO_TO ...
最新文章
- 对象的引用和clone
- web项目性能优化--网络、js、渲染
- 【邓侃】哈佛大学机器翻译开源项目 OpenNMT的工作原理
- Haroopad安装与配置: Linux系统下最好用的Markdown编辑器
- from mysql_MySQL的FROM
- 零起步的Hadoop实践日记(更改hadoop数据存储位置)
- 真正厉害的人,早就戒掉了“贫穷思维”
- 同学,要开学了,你的导师也很焦虑
- 系统架构师学习笔记-软件架构设计
- Python 机器学习 随机森林 天气最高温度预测任务(二)
- springcloud基于ribbon的canary路由方案 1
- mobilenet cpu 加速_UP手游加速器苹果版下载安装-UP手游加速器iOS苹果版下载
- Zemax操作25--像差理论和修正(球差、慧差、像散)
- html旋转相册,css3 旋转相册
- Oracle 实验:建立和配置Oracle数据库服务器
- 【实例】VBA excel 隔行插入行与列
- oracle 查找不重复的数据,oracle不用distinct查找不重复记录和删除重复记录
- 802.11协议帧间间隔-SIFS,DIFS,PIFS,EIFS
- Kafka Broker
- Gitte (https://gitee.com/) 常用git指令--实例
热门文章
- C#_List转换成DataTable
- Android上下左右滑动,显示底层布局
- jQuery 人脸识别插件,支持图片和视频
- gdbserver yum 安装_(OK) 编译cBPM—CentOS7—gdb—gdbserver—成功—调试
- python自动创建目录_python自动目录环境
- 0.0 目录-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
- C++中类的多态与虚函数的使用
- Android + kernel USB host 如何判断插入的设备是高速还是低速的设备
- 【LSTM】基于LSTM网络的人脸识别算法的MATLAB仿真
- 异部时钟电路的FPGA设计