0.uCOSII简介
0.0 uCOSii背景
μC/OS-II由Micrium公司提供,是一个可移植、可固化的、可裁剪的、占先式多任务实时内核,它适用于多种微处理器,微控制器和数字处理芯片(已经移植到超过100种以上的微处理器应用中)。同时,该系统源代码开放、整洁、一致,注释详尽,适合系统开发。
μC/OS-II已经通过联邦航空局(FAA)商用航行器认证,符合航空无线电技术委员会(RTCA)DO-178B标准。
0.1 特点及组成
μC/OS-II可以提供如下服务:
信号量
互斥信号量
事件标识
消息邮箱
消息队列
任务管理
固定大小内存块管理
时间管理
另外,在μC/OS-II内核之上,有如下独立模块可供用户选择:
μC/FS文件系统模块
μC/GUI图形软件模块
μC/TCP-IP协议栈模块
μC/USB协议栈模块
μC/OS-II可以大致分成核心、任务处理、时间处理、任务同步与通信,CPU的移植等5个部分。
(1) 核心部分(OSCore.c)
是操作系统的处理核心,包括操作系统初始化、操作系统运行、中断进出的前导、时钟节拍、任务调度、事件处理等多部分。能够维持系统基本工作的部分都在这里。
(2) 任务处理部分(OSTask.c)
任务处理部分中的内容都是与任务的操作密切相关的。包括任务的建立、删除、挂起、恢复等等。因为μC/OS-II是以任务为基本单位调度的,所以这部分内容也相当重要。
(3) 时钟部分(OSTime.c)
μC/OS-II中的最小时钟单位是timetick(时钟节拍)。任务延时等操作是在这里完成的。
(4) 任务同步和通信部分
为事件处理部分,包括信号量、邮箱、邮箱队列、事件标志等部分;主要用于任务间的互相联系和对临界资源的访问。
(5) 与CPU的接口部分
是指μC/OS-II针对所使用的CPU的移植部分。由于μC/OS-II是一个通用性的操作系统,所以对于关键问题上的实现,还是需要根据具体CPU的具体内容和要求作相应的移植。这部分内容由于牵涉到SP等系统指针,所以通常用汇编语言编写。主要包括中断级任务切换的底层实现、任务级任务切换的底层实现、时钟节拍的产生和处理、中断的相关处理部分等内容。
以上就是些基础知识,不多说,进入正题!
1.0 移植准备
环境:KEIL-MDK v-5.25
硬件:STM32F103VET6核心板
模板程序:点灯程序即可
Uocsii源码:http://micrium.com/downloadcenter/download-results/?searchterm=mp-uc-os-ii&supported=true下载即可
得到文件解压后如下图:
Doc-此文件夹为一些关于uCOSII的文档,可以看一下,我们所需要的移植文件都在Souce文件夹下。
1.1 移植文件
在我们的模板程序的工程目录下新建一个 UCOS 空文件夹,用来放置我们的移植文件,同时在UCOS路径下新建三个文件夹 1.CORE, 2.CONFIG,
3.CONFIG文件夹如下图
在我们的Source下找到我们所需的文件,将它们添加复制到我们的三个文件夹中;如下所示:
CORE:
CONFIG:此文件夹只需要两个文件
includes.h:为一些配置文件,我复制出来了
/*
************************************************************************************************
主要的包含文件
文 件: INCLUDES.C ucos包含文件
作 者: Jean J. Labrosse
************************************************************************************************
*/
#ifndef __INCLUDES_H__
#define __INCLUDES_H__
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include "ucos_ii.h"
#include "os_cpu.h"
#include "os_cfg.h"
#include <stm32f10x.h>
#endif
接下来就是我们的最后一个文件夹
PORT:
这个文件需要另外下载,我就把整个文件夹打包出来,https://pan.baidu.com/s/1-ZGLL-fc_cRwGfF87UaTsw
我们现在将所有文件都添加进来了,但是我们只是添加到文件路径中,还没有真正添加到工程中,接下来我们将我们的文件添加到工程中;
2.0 工程配置
将所需文件添加至工程中
注意:
1.千万不要吧ucos_ii.c文件添加到UCOS-CORE分组中吗,不然会出现很多的报错。
2.记得同时将头文件路径添加进去
添加完成后我们可以尝试编译工程,结果我们会出现出现很多报错, 但是有很多报错提示我们找不到头文件 app_cfg.h.
解决方法:
1.打开ucosii.h,注释以下其app_cfg.h的声明,因为我们没有用到这个头文件。同时将我们的 includes.h 头文件声明。
2.打开 stm32f103x_it.c,将中断函数 void PendSV_Handler(void) 及其内容注释掉 :
3.打开sys.h文件,将此处定义修改以下,另其为1,因为本人用的是正点的模板,所以此处必须修改才可以支持OS:
#define SYSTEM_SUPPORT_OS 1 //定义系统文件夹是否支持UCOS
到此我们的UCOSii的配置基本就完成了,没有报错,那我们就把我们的点灯程序加入OS欢乐的跑起来吧。
#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);
}
}
代码已粘贴出,我移植UCOSii的资料来自原子哥,在配置完成后,他会出现一个报错:
…\OBJ\LED.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by delay.o and stm32f10x_it.o).
此时只需要屏蔽 void SysTick_Handler(void)中断即可
声明:此文仅用来记录学习和加深印象,毕竟类文太多了,我也是一路COPY过来的。
来源:https://blog.csdn.net/weixin_42349855/article/details/102759980