uC/OS-III 概要

本章主要对 uC/OS-III 实时操作系统做一些概要介绍,使读者对 uC/OS-III 有个整体的浅

认识,为后面的章节的详细讲解做一个铺垫。
下图是 uC/OS-III 系统从底层到上层的文件结构。

①配置文件,通过定义这些文件里宏的值可以轻易地裁剪 uC/OS-III 的功能。
②用户应用文件, 定义和声明应用任务。
③内核服务文件,其代码与 CPU 无关,可以不做任何修改移植到任何 CPU。 本书主要讲解这部分内容。
④底层函数库,比如字符串的常规操作, 常用的数学计算, 等等。
⑤CPU 移植文件, 用户如果想要移植 uC/OS-III 到不同平台上,需要修改这部分代码。
⑥CPU 配置文件,主要是 CPU 的一些工作模式和服务函数。
⑦其他 CPU 相关文件。

uC/OS-III 数据结构
uC/OS-III 中的内核对象大多都是以结构体的形式存在的,例如出现最多的任务的任务控
制块的数据结构如下所示,结构体中的每个成员代表任务具有的一种属性。在结构体中,可
以看到很多宏,通过定义这些宏,就可以轻易地裁剪任务控制块具有的属性(任务的功能)。

不再一一列举。

在 uC/OS-III 中,对内核对象的管理大多采用线性链表的数据结构,包括单向链表和双
向链表。链表就是将要管理的对象按照方便管理的规则一个接一个串联在一起,提高管理效
率。

任务
在 uC/OS-III 中,可以创建无数多个任务, 让这些任务并发运行,就好像有多个主函数
在运行一样。 在 uC/OS-III 初始化的时候, 至少会创建空闲任务 OS_IdleTask()和时基任务
OS_TickTask()这两个任务, 另外还有三个可选择的内部任务,软件定时器任务
OS_TmrTaks() 、中断延迟提交任务 OS_IntQTask()和统计任务 OS_StatTask()。
从用户的角度来看, uC/OS-III 中的任务可以分为 5 种状态, 分别是休眠态、就绪态、
运行态、挂起态和中断态, 如下表所示。

从 uC/OS-III 任务管理的角度来看, uC/OS-III 中的任务 9 种状态, 如下表所示。 分别是
休眠态、就绪态、运行态、挂起态和中断态,如下表所示。

软件定时器
软件定时器的功能跟硬件定时器一样,主要用于定时,但其精度达不到硬件定时器的标
准,可以用于定时一些精度要求不是特别严格的事件。理论上, uC/OS-III 可以创建无数个
软件定时器,这是硬件定时器无法媲美的。
多值信号量
多值信号量主要用于管理资源和标志事件的发生。管理资源的一个常用仿例就是停车场,
把总停车位看做信号量,每次申请一个停车位信号量就减 1,如果停车位为 0,就申请不到,
但可以等待其它汽车释放停车位。 标志事件的发生类似于裸机里常用的事件标志变量,就是
标志某事是否发生,然后通知任务。

互斥信号量
互斥信号量的作用是保护共享资源,避免共享资源正在被重写时被其它任务读取,这样
读取到的数据就有错误。 互斥信号量的作用跟多值信号量的作用有些重叠,多值信号量的执
行时间少于互斥信号量,但多个任务访问共享资源时,容易出现优先级反转的问题,这会降
低系统的可预知性, 而互斥信号量可以防止优先级反转,所以建议在互斥信号量可以解决需
要时,就优先使用互斥信号量。
消息队列
消息队列是由多个消息串联而成的一个机制,需要消息的任务就从消息队列的出口端获

取,如果消息队列里没有消息了,可以选择等待或者不等待消息的到来。消息可以比信号量
携带更丰富的信息, 可以是任意长度的消息内容。
事件标志组
事件标志组用于标志若干个事件否发生的组合。这个功能可以轻易地实现键盘的按键组合。
任务信号量
任务信号量的作用与多值信号量的一样,但多值信号量是所有任务都可以申请使用,而
任务信号量却只能给一个特定任务使用,也就是说任务信号量是一个任务本身的属性,但其
他任务都可以给这个任务发送任务信号量。
任务消息队列
任务消息队列的作用与(普通)消息队列的一样,但(普通)消息队列是所有任务都可
以申请它的消息,而任务任务消息队列的消息却只能给一个特定任务使用,也就是说任务消
息队列是一个任务本身的属性,但其他任务都可以给这个任务发送任务消息。
内存管理(分区)
内存管理(分区)主要是为了尽量减少内存在不断分配和释放过程造成的内存碎片,避
免过多的浪费内存。 内存分区就是一次性开辟一大块连续内存,然后将内存分区平均分成若
干个内存块,需要使用内存时就申请一个内存块,用完了再释放回内存分区, 这样就实现内
存块的循环使用。

uC/OS-III 常用程序段
临界段
临界段主要是为了某段代码在执行时避免被其它任务或中断打断。临界段根据是否是使
能了中断延迟提交(OS_CFG_ISR_POST_DEFERRED_EN) 大体可以分为两种。当使能中断延迟提交时,中断级任务会转换成任务级任务,这种情况下进入和退出临界
段主要分别是锁调度器和解锁调度器。当禁用中断延迟提交时,进入和退出临界段的方式分
别是关中断和开中断。

OS_CRITICAL_ENTER()和 OS_CRITICAL_ENTER_CPU_EXIT() 为进入临界段,
OS_CRITICAL_EXIT() 和 OS_CRITICAL_EXIT_NO_SCHED() 为 退 出 临 界 段 ,
CPU_CRITICAL_ENTER()为关中断, CPU_CRITICAL_EXIT()为开中断。

为方便 uC/OS对中断的管理,在进入中断服务函数时需要调用 OSIntEnter() 函数将中断嵌套计数
OSIntNestingCtr 加 1,并且在退出中断服务函数时需要调用 OSIntExit() 函数将中断嵌套计
数 OSIntNestingCtr 减 1

时间: 2024-07-29 22:22:48

uC/OS-III 概要的相关文章

uc/os iii移植到STM32F4---IAR开发环境

也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢出警告(为何keil没有报堆栈溢出??),网上有人说不用理会,但是实际使用时发生了错误(定义的常量数组值被改变,怀疑是堆栈溢出导致),发现使用的IAR版本不能完美支持使用的STM32芯片,换用高版本测试..(高版本正确,与低版本对芯片的支持有关) 2.开始时虽然会堆栈溢出,但是能够进入异常中断,进入

【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

1 LES BX, DWORD PTR DS:_OSTCBCur ;取得任务堆栈指针ES:[BX] 2 MOV ES:[BX+2], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务堆栈的2,3内存单元 3 MOV ES:[BX+0], SP ;将当前SP(栈顶的偏移量)存放至当前任务堆栈的0,1内存单元 首先讲讲LES指针的功能:LES的功能有点像C语言的*. LES REG,MEM 参与操作的寄存器不仅有REG,还有ES寄存器.在16位系统中,寄存器为16位,很显然,MEM所指向的内存

uC/OS II 任务切换原理

今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引发一次中断,自动将CS.IP寄存器压入堆栈,再利用中断返回,将新任务的任务断点指针弹出到CPU的CS.IP寄存器中,实现任务切换.虽然明白个大概,但是其中的细节却有点模糊,为什么调用IRET中断返回指令后,弹入CPU的CS.IP寄存器的断点指针是新任务的断点指针,而不是当前任务的,UCOS II是如

uC/OS 的任务调度解析 (转)

uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS使用的是OSStartHighRdy OSStartHighRdy LDR R0, =NVIC_SYSPRI14 ; Set the PendSV exception priority LDR R1, =NVIC_PENDSV_PRI STRB R1, [R0] MOVS R0, #0 ; Set

关于uC/OS的简单学习(转)

1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数,且处理函数非常简单,一般仅是向相应的Task发消息,唤醒该Task来处理中断任务. 一个高效的调度器,这是OS的灵魂,实现多任务间的调度(包括调度点.调度算法.任务切换等). 好像就这么点,呵呵.它不支持内存保护,即不像Linux那样分用户空间.内核空间.如一个Task运行时,可调用内核函数Task

uc os相关的C语言知识点1-函数指针

开始读uc os的代码了,发现很多C语言的东西,之前没搞懂的,慢慢积累. 就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的.这样,我就可以通过这个函数指针变量来调用所指向的函数了. 形式1:返回类型(*函数名)(参数表) ,例子如下: #include<stdio.h> void (*funp)(int); //定义一个函数指针,注意函数的返回类型和参数类型和指针的一致,才可以用. void print(int n); //函数申明 int

uc/os 笔记(转)

1.uC/OS-II中使用互斥信号对象应该注意 互斥信号对象(Mutual Exclusion Semaphore)简称Mutex,是uC/OS-II的内核对象之一,用于管理那些需要独占访问的资源,并使其适应多任务环境. 创建每一个Mutex,都需要指定一个空闲的优先级号,这个优先级号的优先级必须比所有可能使用此Mutex的任务的优先级都高! uC/OS-II的Mutex实现原理大致如下:    当一个低优先级的任务A申请并得到了Mutex,于是它获得资源访问权.如果此后有一个高优先级的任务B开

UC/OS操作系统 (转)

1.和其他一些著名的嵌入式操作系统不同,uC/OS-II在单片机系统中的启动过程比较简单,不像有些操作系统那样,需要把内核编译成一个映像文件写入ROM中,上电复位后,再从ROM中把文件加载到RAM中去,然后再运行应用程序.uC/OS-II的内核是和应用程序放在一起编译成一个文件的,使用者只需要把这个文件转换成HEX格式,写入ROM中就可以了,上电后,会像普通的单片机程序一样运行. 2.uC/OS-II的移植也是一件需要值得注意的工作.如果没有现成的移植实例的话,就必须自己来编写移植代码.虽然只需

整理uc/os的46个函数

Void OSInit(void); 所属文件 OS_CORE.C     调用者 启动代码    开关量 无 OSinit()初始化μC/OS-Ⅱ,对这个函数的调用必须在调用OSStart()函数之前,而OSStart()函数真正开始运行多任务. Void OSIntEnter(void); 所属文件 OS_CORE.C     调用者 中断      开关量 无 OSIntEnter()通知μC/OS-Ⅱ一个中断处理函数正在执行,这有助于μC/OS-Ⅱ掌握中断嵌套的情况.OSIntEnter

uc/os学习入门:在32位pc机上搭建编译环境

由于学习ucos的入门资料中所使用的编译器大多都是Borland c ++ 3.1或者Borland c++4.5,为了降低学习的难度最好所用的编译器与书本上的一致.由于4.5版本稍高,所以最终决定用Borland C++ 4.5,毕竟是很老的东西,甚是难找,最后也不知道在哪找到了,经测试能在windows xp上安装(在64位系统上是不能用的,我所采用的方法是虚拟机中装Windows xp)编译器下载链接http://pan.baidu.com/s/1bO3nVS 解压bc45_setup.z