我造轮子,你造车,创客一块儿造起来!塔克创新资讯【塔克社区 www.xtark.cn 】【塔克博客 www.cnblogs.com/xtark/ 】 程序员
简单的小型系统设计通常是基于先后台的或者无限循环的系统。包含一个无限循环的模块实现须要的操做(后台)。中断处理程序实现异步事件(前台)。前台也叫作中断级,后台也叫做任务级。临界操做应该在任务级中被执行,不可避免地必须在中断处理程序中执行也要确保是在很短的时间内完成。由于这会致使ISR 占用更长的时间。一般的,ISR 中使能相关的信息而在后台程序中执行相应的操做。这叫作任务级响应。任务级响应的时间依赖于后台循环一次所需的时间,一般这不是一个固定常量。另外,若是其中的代码稍有改动,那么循环一次所用的时间也将有所变化。 数据结构
大多数高产量低成本微控制器的应用软件(例如微波炉,电话玩具等)都是基于先后台系统的。 架构
实时内核是一个能管理MPU、MCU、DSP 时间和资源的软件。实时内核的应用包括迅速地响应,可靠地完成工做的各个部分。任务(也叫作线程)是一段简单的程序,运行时彻底地占用CPU。 app
在单CPU 中,任什么时候候只有1 个任务被执行。内核的责任是管理任务,也作多任务处理。多任务处理的做用是协调和切换多个任务依次享用CPU。多任务处理最大化CPU 的功能同时会让咱们感受是多个CPU 在同时运行。多任务处理也有利于处理模块化的应用。多任务处理一个最重要的方面在于它容许程序员管理复杂的实时应用。在多任务处理中程序员能够简单的维护和升级产品。 异步
uC/OS-III 是一个抢占式内核,这意味着uC/OS-III 老是执行最重要的就绪任务,以下图。 模块化
uC/OS-III是一个可扩展的,可固化的,抢占式的实时内核,它管理的任务个数不受限制。它是第三代内核,提供了现代实时内核所指望的全部功能包括资源管理、同步、内部任务交流等。uC/OS-III 也提供了不少特性是在其余实时内核中所没有的。好比能在运行时测量运行性能,直接得发送信号或消息给任务,任务能同时等待多个信号量和消息队列。如下列出uC/OS-III 的特色: 函数
源代码:uC/OS-III 彻底根据ANSI-C 标准写的。代码的规范是Micrium 团队的一种文化。虽然不少商业内核供应商提供他们产品的源代码,可是这些产品颇有多是笨重且难以利用的。除非代码严格地遵循标准而且产品有完整的带例子的说明书以展现代码是怎样工做的。经过这本书,你将会对uC/OS-III 内部的工做状况有一个很深的了解。 oop
应用程序接口(API):uC/OS-III 是很直观的。若是你熟悉相似的编码规范,你能轻松地知道函数名所对应的服务,以及须要怎样的参数。例如:指向对象的指针一般是第一个参数,指向错误代码的指针一般是最后一个参数。 性能
抢占式多任务处理:uC/OS-III 是一个抢占式多任务处理内核,所以,uC/OS-III 正在运行的常常是最重要的就绪任务。 学习
时间片轮转调度:uC/OS-III 容许多个任务拥有相同的优先级。当多个相同优先级的任务就绪时,而且这个优先级是目前最高的。uC/OS-III 会分配用户定义的时间片给每一个任务去运行。每一个任务能够定义不一样的时间片。当任务用不完时间片时可让出CPU 给另外一个任务。
快速响应中断: uC/OS-III 有一些内部的数据结构和变量。uC/OS-III 保护临界段能够经过锁定调度器代替关中断。所以关中断的时间会很是少。这样就使uC/OS-III 能够响应一些很是快的中断源了。
肯定性的:uC/OS-III 的中断响应时间是可肯定的,uC/OS-III 提供的大部分服务的执行时间也是可肯定的。
可扩展的:根据应用的需求,代码大小能够被调整。编译时经过调整uC/OS-III 源代码中的大约40 个#define(见OS_CFG.H)能够在添加或移除一些功能。uC/OS-III 的服务还提供一些实时检查功能。特别的,uC/OS-III 能检传递的参数是否为NULL 指针,ISR 是否就绪了任务级服务。参数有容许范围,指定选项都是有用的。检测功能能够被关闭(在编译时)以提供更好的性能和缩减代码大小。实际上,可扩展的uC/OS-III 支持更普遍的应用和项目。
易移植的:uC/OS-III 能够被移植到大部分的CPU 架构中。大部分的支持uC/OS-II 的器件经过改动就能支持uC/OS-III。而uC/OS-II已经移植到45 种CPU 架构中了。
可固化的:uC/OS-III 专为嵌入式系统设计,它能够跟应用程序代码一块儿被固化。
可实时配置的:uC/OS-III 容许用户在运行时配置内核。特别的,全部的内核对象如任务、堆栈、信号量、事件标志组、消息队列、消息、互斥信号量、内存分区、软件定时器等都是在运行时分配的,以避免在编译时的过分分配。
任务数无限制:uC/OS-III 对任务数量无限制。实际上,任务的数量限制于处理器能提供的内存大小。每个任务须要有本身的堆栈空间,uC/OS-III 在运行时监控任务堆栈的生长。uC/OS-III 对任务的大小无限制。
优先级数无限制:uC/OS-III 对优先级的数量无限制。然而,配置uC/OS-III 的优先级在32 到256 之间已经知足大多数的应用了。
内核对象数无限制:uC/OS-III 支持任何数量的任务、信号量、互斥信号量、事件标志组、消息队列、软件定时器、内存分区。用户在运行时分配全部的内核对象。
服务:uC/OS-III 提供了高档实时内核所须要的全部功能,例如任务管理、时间管理、信号量、事件标志组、互斥信号量、消息队列、软件定时器、内存分区等。
互斥信号量(Mutexes):互斥信号量用于资源管理。它是一个内置优先级的特殊类型信号量,用于消除优先级反转。互斥信号量能够被嵌套,所以,任务可申请同一个互斥信号量多达250 次。固然,互斥信号量的占有者须要释放同等次数。
嵌套的任务中止:uC/OS-III 容许任务中止自身或者中止另外的任务。中止一个任务意味着这个任务将再也不执行直到被其余的任务恢复。中止能够被嵌套到250 级。换句话说,一个任务能够中止另外的任务多达250 次。固然,这个任务必须被恢复同等次数才有资格再次得到CPU。
软件定时器:能够定义任意数量的一次性的、周期性的、或者二者兼有的定时器。定时器是倒计时的,执行用户定义的行为一直到计数减为0。每个定时器能够有本身的行为,若是一个定时器是周期性的,计数减为0 时会自动重装计数值并执行用户定义的行为。
挂起多个对象:uC/OS-III 容许任务等待多个事件的发生。特别的,任务能够同时等待多个信号量和消息队列被提交。等待中的任务在事件发生的时候被唤醒。
任务信号量:uC/OS-III 容许ISR 或者任务直接地发送信号量给其它任务。这样就避免了必须产生一个中间级内核对象如一个信号量或者事件标志组只为了标记一个任务。提升了内核性能。
任务消息:uC/OS-III 容许ISR 或者任务直接发送消息到另外一个任务。这样就避免产生一个消息队列,提升了内核性能。
任务寄存器:每个任务能够拥有用户可定义的任务寄存器,不一样于CPU 寄存器。
错误检测:uC/OS-III 能检测指针是否为NULL、在ISR 中调用的任务级服务是否容许、参数在容许范围内、配置选项的有效性、函数的执行结果等。每个uC/OS-III 的API 函数返回一个对应于函数调用结果的错误代号。
内置的性能测量:uC/OS-III 有内置性能测量功能。能测量每个任务的执行时间,每一个任务的堆栈使用状况,任务的执行次数,CPU的使用状况,ISR 到任务的切换时间,任务到任务的切换时间,列表中的峰值数,关中断、锁调度器平均时间等。
可优化: uC/OS-III 被设计于可以根据CPU 的架构被优化。uC/OS-III 所用的大部分数据类型可以被改变,以更好地适应CPU 固有的字大小。优先级调度法则能够经过编写一些汇编语言而获益于一些特殊的指令如位设置、位清除、计数清零指令(CLZ),find-first-one(FF1)指令。
死锁预防:uC/OS-III 中全部的挂起服务均可以有时间限制,预防死锁。
任务级的时基处理:uC/OS-III 有时基任务,时基ISR 触发时基任务。uC/OS-III 使用了哈希列表结构,能够大大减小处理延时和任务超时所产生的开支。
用户可定义的钩子函数:uC/OS-III 容许程序员定义hook 函数,hook 函数被uC/OS-III 调用。hook 函数容许用户扩展uC/OS-III 的功能。有的hook 函数在任务切换的时候被调用,有的在任务建立的时候被调用,有的在任务删除的时候被调用。
时间戳:为了测量时间,uC/OS-III 须要一个16 位或者32 位的时时间戳计数器。这个计数器值能够在运行时被读取以测量时间。例如:当ISR 提交消息到任务时,时间戳计数器自动读取并保存做为消息。当接收者接收到这条消息,时间戳被提供在消息内。经过读取如今的时间戳,消息的响应时间能够被肯定。
嵌入的内核调试器:这个功能容许内核调试器查看uC/OS-III 的变量和数据结构经过一个用户定义的通道。(可是只能在调试器遇到断点的时候查看)。uC/OS-III 内核也支持uC/Probe(探针)在运行时显示信息。
对象名称:每一个uC/OS-III 的内核对象有一个相关联的名字。这样就能很容易的识别出对象所指定的做用。分配一个ASCII 码的名字给任务、信号量、互斥信号量、事件标志组、消息队列、内存块、软件定时器。对象的名字长度没有限制,可是必须以空字符结束。
各版本对比
uC/OS-III的源码已经跟前面版本的源码相差很大,不少方面都作了更加规范的修改,建议没有了解过uC/OS的用户直接上手uC/OS-III,不要再学习uC/OS-II。
如今市面上讲解uC/OS-III的书籍或资料大都基于《嵌入式实时操做系统 uC/OS-III》修改,想系统学习uC/OS-III的用户,了解更多uC/OS-III细节,建议直接阅读该书,讲解很是全面。
uC/OS-III细节内容较多,须要通常专著讲解,本教程旨在引导用户使用uC/OS-III系统,包括将uC/OS-III移植X-CTR100控制器,并经过A、B、C三个任务设计经典RTOS应用例程,经过简单的例程使用户更容易学习uC/OS-III的使用。
本小节讲解将uC/OS-III移植到X工程模板的过程。
uC/OS-III文件结构以下图
①配置文件,经过定义这些文件里宏的值能够轻易地裁剪uC/OS-III 的功能。
②用户应用文件,定义和声明应用任务。
③内核服务文件,其代码与 CPU 无关,能够不作任何修改移植到任何CPU。
④底层函数库,好比字符串的常规操做,经常使用的数学计算等等。
⑤CPU移植文件,用户若是想要移植uC/OS-III到不一样平台上,须要修改这部分代码。
⑥CPU 配置文件,主要是CPU的一些工做模式和服务函数。
⑦其余CPU 相关文件。
配置文件
文件名 |
做用 |
lib_cfg.h |
uC/LIB配置文件,若是使用uC/LIB调用函数Mem_Init()初始化 |
os_cfg.h |
uC/OS相关函数配置 |
os_cfg.h |
内核任务配置(中断管理,空闲/统计任务,定时器) |
app_cfg.h |
用户任务配置 |
cpu_cfg.h |
uC/CPU相关配置 |
os_type.h |
变量类型定义 |
下载源码
登录Micrium公司官方网站(http://micrium.com/),下载源码,本文使用uC/OS-III V3.04.04版本,资料里面下载好的源码,目录结构以下图,移植过程将从该源码向X工程拷贝文件。
步骤一:建立文件夹,复制官方源码对应文件夹到移植工程。
复制文件夹到移植工程uC-CPU、uC-LIB、uCOS-III文件夹
删除不用的编译器文件夹
复制以下文件到uCOS-APP
复制文件到uCOS-BSP
步骤二:修改工程配置。
以下图添加工程目录和文件,具体文件位置可根据文件名称对应目录查找。
添加时注意选择All file,添加.h和.asm文件。
添加工程路径
步骤三:修改工程文件
首先修改工程的启动文件" startup_stm32f40xx.s"。
其中将PendSV_Handler 和SysTick_Handler 分别改成OS_CPU_PendSVHandler 和OS_CPU_SysTickHandler,共有两处修改位置两处。
初始化时,使能硬件浮点。
修改bsp.h,头文件包括ax_basis.h基础板载资源文件。
保留三个函数名称。
修改bsp.c文件,BSP_Init()函数,调用AX_Init()初始化函数。
修改ax_basis.c文件,删除滴答时钟及延时函数部份内容,保留LED、BEEP、拨码开关、串口操做内容,具体查看源文件。
修改app_cfg.h,该文件为app配置文件,作以下修改。
修改app.c文件,该文件是应用程序文件,main()函数位于该文件,包括uC/OS-III系统初始化和初始任务建立。
int main(void) { OS_ERR err;
OSInit(&err); /* Init uC/OS-III. */
OSTaskCreate((OS_TCB *)&AppTaskStartTCB, /* Create the start task */ (CPU_CHAR *)"App Task Start", (OS_TASK_PTR)AppTaskStart, (void *)0, (OS_PRIO)APP_TASK_START_PRIO, (CPU_STK *)&AppTaskStartStk[0], (CPU_STK_SIZE)APP_TASK_START_STK_SIZE / 10, (CPU_STK_SIZE)APP_TASK_START_STK_SIZE, (OS_MSG_QTY)5u, (OS_TICK)0u, (void *)0, (OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR), (OS_ERR *)&err);
OSStart(&err); /* Start multitasking (i.e. give control to uC/OS-III). */
}
static void AppTaskStart(void *p_arg) { OS_ERR err;
(void)p_arg;
CPU_Init();
/* Initialize BSP functions */ BSP_Init(); BSP_Tick_Init(); //Configure and Initialize the OS Tick Services (SysTick).
Mem_Init(); //Initialize Memory Management Module
#if OS_CFG_STAT_TASK_EN > 0u OSStatTaskCPUUsageInit(&err); /* Compute CPU capacity with no task running */ #endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN CPU_IntDisMeasMaxCurReset(); #endif
/* Task body, always written as an infinite loop. */ while (1) { AX_LEDG_Toggle(); OSTimeDly(500, OS_OPT_TIME_DLY, &err); } } |
开始任务循环体,每隔0.5S翻转绿色LED灯,以便观察系统启动状况。
至此,移植完成,编译后下载到X-CTR100,系统运行正常,绿色LED灯闪烁。
曾鸣等,《嵌入式实时操做系统 uC/OS-III》
秉火《uCOS-III 应用开发指南》
正点原子《STM32F4 UCOS开发手册_V3.0》
屈环宇 译《uC/OS-III手册中文翻译》