UCOS-II-信号量的理解

合集下载

转:一步一步教你使用uCOS-II

转:一步一步教你使用uCOS-II

转:⼀步⼀步教你使⽤uCOS-II第⼀篇 UCOS介绍第⼀篇 UCOS介绍这个⼤家都知道。

呵呵。

考虑到咱们学习的完整性还是在这⾥唠叨⼀下。

让⼤家再熟悉⼀下。

⾼⼿们忍耐⼀下吧! uC/OS II(Micro Control Operation System Two)是⼀个可以基于ROM运⾏的、可裁减的、抢占式、实时多任务内核,具有⾼度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。

为了提供最好的移植性能,uC/OS II最⼤程度上使⽤ANSI C语⾔进⾏开发,并且已经移植到近40多种处理器体系上,涵盖了从8位到64位各种CPU(包括DSP)。

uC/OS II可以简单的视为⼀个多任务调度器,在这个任务调度器之上完善并添加了和多任务操作系统相关的系统服务,如信号量、邮箱等。

其主要特点有公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好,可裁剪,可固化。

内核属于抢占式,最多可以管理60个任务。

µC/OS-II 的前⾝是µC/OS,最早出⾃于1992 年美国嵌⼊式系统专家Jean brosse 在《嵌⼊式系统编程》杂志的5 ⽉和6 ⽉刊上刊登的⽂章连载,并把µC/OS 的源码发布在该杂志的B B S 上。

µC/OS 和µC/OS-II 是专门为计算机的嵌⼊式应⽤设计的,绝⼤部分代码是⽤C语⾔编写的。

CPU 硬件相关部分是⽤汇编语⾔编写的、总量约200⾏的汇编语⾔部分被压缩到最低限度,为的是便于移植到任何⼀种其它的CPU 上。

⽤户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件⼯具,就可以将µC/OS-II嵌⼈到开发的产品中。

µC/OS-II 具有执⾏效率⾼、占⽤空间⼩、实时性能优良和可扩展性强等特点,最⼩内核可编译⾄ 2KB 。

µC/OS-II 已经移植到了⼏乎所有知名的CPU 上。

uCOS原理及应用

uCOS原理及应用
周立功单片机
• 多任务系统工作原理
操作系统的调度程序对所有任务实现运行控制 调度程序对所有任务实现运行控制; 任务切换实际就是把当前任务所占用的CPU资源用其它任务来替 任务切换 换; CPU资源包括寄存器R0-R15、CPSR、SPRS和其它一些全局变量; 调度程序由系统节拍驱动 系统节拍驱动。
移植时需要 编写的代码
用于产生 系统时钟
周立功单片机
移植简介
• 概述
要移植 移植一个操作系统到一个特定的CPU体系结构 上并不是一件很容易的事情 并不是一件很容易的事情,它对移植者有以下要求: 1. 对目标体系结构要有很深了解; 2. 对OS原理要有较深入的了解; 3. 对所使用的编译器要有较深入的了解; 4. 对需要移植的操作系统要有相当的了解; 5. 对具体使用的芯片也要一定的了解。
栈底 任务环境开始
SP
周立功单片机
• 堆栈初始化函数
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) { OS_STK *stk; opt = opt; stk = ptos; *stk = (OS_STK) task; *--stk = (OS_STK) task; *--stk = 0; 栈底 任务入栈的 *--stk = 0; 其它数据 *--stk = 0; *--stk = 0; PC *--stk = 任务环境开始 0; LR *--stk = 0; R12 *--stk = 0; R11 *--stk = 0; R10 *--stk = 0; R9 *--stk = 0; R8 *--stk = 0; ... *--stk = 0; R2 *--stk = (unsigned int) pdata; R1 *--stk = (USER_USING_MODE|0x00); R0 *--stk = 0; OSEnterSum SP return (stk); 空闲空间 } 周立功单片机

UCOS-II-II、FreeRTOS、RTX四大RTOS系统性能对比

UCOS-II-II、FreeRTOS、RTX四大RTOS系统性能对比

UCOS-II/II、FreeRTOS、RTX四大RTOS系统性能对比大家好,感谢社区提供的板卡。

这次的使用对象是安富莱的STM32-V6板卡。

由于之前用过安富莱的V4板卡,所以安富莱给我留下了很深的印象,他们开发板的资料很过硬,售后完善,线上QQ技术支持也很给力,作为学习,确实是一款很不错的板卡。

唯一的是,安富莱很少出视频,其主要是编写PDF教学手册和程序例程。

另外他们的按键检测代码,很紧凑,有单发、连发、长按、短按、上升沿触发、下降沿触发等功能,是我见到最棒的按键检测代码。

STM32-V6是一款基于STM32F429单片机的开发板,整板采用4层板设计,本次选择它的目的,除了测试其能做常用外设开发驱动,安富莱还对它做了一个示波器的例程。

虽然示波器的性能不强,但是去十分有意思。

另外其支持VNC虚拟屏幕功能。

开发者可以不用LCD显示屏幕,直接使用PC屏幕作为自己的开发板屏幕,十分方便。

所以这个板子真的很强大。

拿到板子,在我查看他们的网络示波器例程后,发现安富莱只做了基于RTX的例程,并没有做基于uCOS、FreeRTOS的例程,这样我感到很奇怪。

因为安富莱的每个例程都会做三个OS版本,唯独这个例程却只制作了一个基于RTX的。

他们的技术支持回复是:“FreeRTOS的性能不行,所以对这个网络示波器的的应用来说,没有制作这方面的例程”,这让我感到很疑惑,FreeRTOS作为一款开源RTOS,性能真有这么差么?到底他们之间的差距又有多大?所以才有这次做UCOS-II、UCOS-III、FreeRTOS、RTX系统性能对比测试,本次我只是站在一个使用者的角度,测试四个RTOS单一的系统调度性能。

尽量使4个RTOS处在同一水平上测试:l 使用相同的硬件平台和相同的资源l 单片机都使用相同的主频,只是单片机的Uart资源。

uCOS-II互斥信号量

uCOS-II互斥信号量

μCOS-II互斥信号量Application NoteAN-1002Jean J. Labrossebrosse@概述:使用互斥信号(Mutual Exclusion Semaphores)或者简单的互斥(mutexes)实现对资源的独占访问,互斥信号本身是一种二进制信号,具有超出μCOS-II提供的一般信号机制的特性。

本手册描述了C/OS-II V2.04增加的mutex一系列服务。

简介:在应用程序中使用互斥信号是为了减少优先级翻转问题(priority inversion problem),如μC/OS-II, The Real-Time kernel (ISBN 0-87930-543-6), section 2.16, page 47中描述的。

当一个高优先级的任务需要的资源被一个低优先级的任务使用是,就会发生优先级翻转问题。

为了减少优先级翻转问题,内核可以提高低优先级任务的优先级,先于高优先级的任务运行,释放占用的资源。

为了实现互斥,实时内核需要具有支持在同一优先级具有多个任务的能力。

不幸的是,μC/OS-II不允许在相同的优先级有多个任务,必须只有一个任务。

但是我们有另外的方法解决这个问题。

可以把需要资源的高优先级任务上面的一个任务使用Mutex保留,允许提高低优先级任务的优先级。

举一个mutexes信号工作的例子,如listing1所示。

Listing 1中有三个任务可以使用共同的资源,为了访问这个资源,每个任务必须在互斥信号ResourceMutex上等待(pend),任务#1有最高优先级10,任务#2优先级为15,任务#3优先级为20,一个没有使用的正好在最高优先级之上的优先级#9用来作为优先级继承优先级(Priority Inheritance Priority-PIP)。

如main()所示,L1(1)进行μC/OS-II初始化,并通过调用OSMutexCreate() L1(2)创建了一个互斥信号。

ucos中关于信号量的使用总结

ucos中关于信号量的使用总结
}
void task0(void *dat)//任务0
{
while(1)
{
con1++;
OSSemPost(sem);//发送信号量
OSTimeDly(2);
}
}
void task1(void *dat)//任务1
{
u16 value;
OSSemPost(Fun_Semp); //发送信号量
YouTaskRun++;
OSTimeDlyHMSM(0, 0, 2, 0); //等待2秒
}
}
在上例中,MyTask 一直在等待信号量,在信号量没有到来之前无法执行。只有在YouTask 运行了5次,YouTaskRun==5之后,OSSemPost(Fun_Semp); //发送信号量,MyTask 才得以执行。如果按上例所示,MyTask 只能执行一次,因为YouTask 以后再也不可能使得YouTaskRun==5了。MyTask 也就因为无法得到信号量而不能运行。
2、OSSemCreate (1);
.....
OS_EVENT *Fun_Semp;
.....
Fun_Semp = OSSemCreate (1);
.....
void MyTask (void *pdata)
{
.....
for (;;)
{
信号量的结构为:
typedef struct {
INT8U OSEventType;
INT8U OSEventGrp;
1、Semp = OSSemCreate(0), 该信号量表示等待一个事件或者多个事件的发生。

ucosii对于信号量,互斥信号量,事件标志组的个人理解

ucosii对于信号量,互斥信号量,事件标志组的个人理解

ucosii对于信号量,互斥信号量,事件标志组的个人理解ucos看了也有一周多了,索性源码都能开得懂,并且能去理解。

昨天一开始看事件标志组的时候确实不知道怎么回事,后来百度一下,明白了事件标志组的作用以后,再去看书上的讲解和原码就清晰多了,很容易就明白了他的基本运行机理。

这也给了我一点启示,学一个东西,看一个东西之前,你最少要知道他干嘛用的,如果连干嘛用的都知道书看的再熟也是枉然。

ucos中提供了好几个用于同步事件以及共享资源访问的机制,目前我看明白的有信号量,互斥信号量,事件标志组。

下面谈谈自己对他们的理解:1.互斥信号量:互斥互斥,意思就是我用了你就不能用,你用了我就不能用。

永远都只有一个人独占这个东西~!举个例子:比如说打印机。

我任务1现在让他打印《静夜思》,那么在我还没打印完之前,别的任务就不能命令打印机去打印别的东西。

否则如果任务2让他打印《春晓》,那最后打印出来的会是什么~????反正肯定不是任务1想要的,肯定也不是任务2想要的。

上面讲的比较通俗。

打印机就是共享资源,谁都可以访问他~!但是同一时间,肯定要保证只有1个任务再操作打印机。

那样才能得到大家想要的结果。

也就是要独占共享资源的访问权~!ucos2中通过互斥信号量来解决这个问题。

简单说就是任务1开始访问打印机的时候,先去查询这个互斥信号量是否有效,有效,说明没人在访问打印机,这时任务1就把这个互斥信号量置无效,然后开始操作打印机。

这样,每个任务再操作打印机前都要去查询这个互斥信号量时候有效。

无效就等,等到有效才可以访问,或者等到不耐烦了(术语叫等待超时)就不等了~!任务一直到用完了打印机后才把信号量置有效,这时其他任务才有可能去访问,操作打印机。

这里又有一个问题:再任务1操作打印机器件,可能有多个任务申请打印机的所有权。

那么再任务1结束后,我应该给谁用呢~~??也许我们马上就反应过来了~废话~!!当然是排队了~~谁先到的谁用啊~~~。

详解UCOS中的互斥信号量

详解UCOS中的互斥信号量

详解UCOS中的互斥信号量二值信号量主要用于进行共享资源的独占式访问,比如我们用一个变量来标志一个资源是否可用,当这个变量为1的时候表示资源可用,当这个资源为0的时候表示资源不可用,但是二值信号量容易产生优先级反转,影响系统的实时性。

互斥信号量一般用于降解优先级反转,优先级反转就是高优先级的任务的优先级被拉低了。

具体如下:我们有三个任务Task1,Task2,Task3,三个任务的优先级依次降低。

void Task1(){while(1){OSSemPend();//获取信号量......OSSemPost();//释放信号量}}void Task2(){while(1){//注意任务2不需要信号量}}void Task3(){while(1){OSSemPend();//获取信号量OSSemPost();//释放信号量}}void main(){OSInit();CreateTask(Task1);//1最高CreateTask(Task2);//2CreateTask(Task3);OSStart();}如上图所示:在任务2获得信号量的时候,任务1恢复就绪态之后因为没有获得信号量而挂起,所以任务3继续执行,直到任务3执行完毕之后,任务1才开始执行。

虽然任务1的优先级最高,但是因为信号量的原因而是任务1的优先级降到任务3的优先级水平。

而且任务2加重了优先级反转的程度。

当我们使用了互斥信号量之后,就可以在某种程度上缓解优先级反转的问题了。

当高优先级的任务请求互斥信号量时,如果低优先级的任务占有该信号量,则先提升低优先级任务的优先级,使之尽快执行完以释放互斥信号量,这样高优先级的任务也能尽快执行,在某种程度上缓解了优先级反转问题。

使用了互斥信号量之后的运行图如下:如图所示,在任务3执行的过程中,任务1请求互斥信号量,提升任务3的优先级到最高,使任务3尽快执行完,任务3执行完后释放信号量,任务1开始执行。

ucosii互斥信号量的用法

ucosii互斥信号量的用法

ucosii互斥信号量的用法
ucosii是一个嵌入式操作系统,提供了互斥信号量(Mutex Semaphore)作为一种同步机制。

互斥信号量是一个二进制信号量,用
于在多任务环境中保护共享资源。

它可以用来解决并发访问共享资源
可能引起的数据竞争问题。

互斥信号量主要有两个状态:锁定和非锁定。

只有一个任务可以
拥有互斥信号量的锁定状态,其他任务在请求锁定时会被阻塞。

当任
务完成对共享资源的操作后,会释放互斥信号量的锁定状态,允许其
他任务获取锁。

在ucosii中,可以使用以下函数来创建、获取和释放互斥信号量:
1.函数OSMutexCreate():用于创建一个互斥信号量。

可以设置互斥信号量的初始状态,创建成功后返回一个信号量控制块(OS_MUTEX)的指针。

2.函数OSMutexPend():用于获取一个互斥信号量的锁。

如果互斥信号量的锁已被其他任务获取,则当前任务会被阻塞,直到互斥信号
量的锁可用并成功获取。

3.函数OSMutexPost():用于释放一个互斥信号量的锁。

只有拥有互斥信号量锁的任务才能调用该函数进行释放。

4.函数OSMutexDel():用于删除一个互斥信号量。

如果互斥信号
量的锁被多个任务同时获取,则删除操作可能引起不可预测的行为。

需要注意的是,对于一个互斥信号量的获取和释放应该成对出现,即当前任务在获取互斥信号量后,应该在不再需要共享资源时及时释
放锁,以避免死锁等问题。

除了ucosii中提供的互斥信号量,还可以通过使用其他同步机制
如信号量、事件标志等来实现资源的同步和互斥访问。

uOSII函数介绍

uOSII函数介绍
6.7.4 向消息队列发送一个消息(LIFO),OSQPostFront() 37
6.7.5 无等待地从一个消息队列中取得消息, OSQAccept() 39
6.7.6 清空一个消息队列, OSQFlush() 40
6.7.7 查询一个消息队列的状态,OSQQuery() 41
6.7.8 使用消息队列读取模拟量的值 42
c2, //OS_STK *ptos , //任务堆栈栈顶的指针
d2); //INT8U prio //任务的优先级别
//可以再加其他任务
//可以再加其他初始化
OSStart(); //开始多任务处理
}
//比如都要用公共资源UART,不能同时用,可分别用
{
OSSemPend(UART_Flag,0,&err); //请求信号量UART_Flag
Function(UART); //使用信号量UART_Flag
OSSemPost(UART_Flag); //发送信号量UART_Flag
第6章 任务之间的通讯与同步 1
6.0 事件控制块ECB 2
6.1 初始化一个ECB块,OSEVENTWAITLISTINIT() 6
6.2 使一个任务进入就绪状态,OSEVENTTASKRDY() 7
6.3 使一个任务进入等待状态, OSEVENTTASKWAIT() 9
6.4 由于等待超时将一个任务置为就绪状态, OSEVENTTO() 9
void a1(void *dataptr)
{
……;
while(1) //任务体1
{
OSSemPend(UART_Flag,0,&err); //请求信号量UART_Flag

ucosII任务间通信详解

ucosII任务间通信详解

ucos II 任务间通信详解ucos II 任务间通信之一 :全局变量任务创建好了之后,只是完成了系统编程的一小步,更为重要的是任务间的通信。

比如在mcu21的项目里,有通信任务,有液晶显示任务,有控制任务。

控制任务需要用到通信任务接受到的数据,液晶显示任务也显示控制任务的数据。

这就需要用到任务间的通信了。

Mcu21总结了一下,在ucos II 里任务间通信可以采用以下几种方式。

z共享全局变量,这是最快捷有效的方式,实现这种通信可以采用以下两种方式:一是利用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()来关闭中断和打开中断,二是利用函数OSSchedLock()和OSSchedUnlock()对μC/OS‐II中的任务调度函数上锁和开锁.z使用信号量z使用邮箱z使用消息队列下面介绍下共享全局变量的实现过程。

(1)宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()是在移植ucos II过程中由用户定义的。

在os_cpu.h这个文件中。

代码如下,这部分代码的作用是关,开中断,具体和CPU有关。

当我们调用OS_ENTER_CRITICAL()时,系统中断被关闭,我们知道,任务切换时基于定时器中断的,当系统中断别关闭时,其它中断,包括定时器中断也就被关闭,任务切换也不可能发生,所以确保在访问变量的时候,不会有其它的任务或中断也在同时访问这个变量。

这两个宏非常好用,在mcu21的项目里经常用到。

尤其在中断处理函数里面。

因为现在的很多CPU是支持中断嵌套的,为了防止中断执行的时候不被其它的中断打断,就可以调用这两个宏。

(2)第二种方法是给任务调度函数上锁,开锁。

这种方法和使用宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()最大的区别是:中断是可以执行的。

尽管不执行任务切换,变量依然有可以被中断函数访问。

给任务调度器上锁的函数如下void OSSchedLock (void){if (OSRunning == TRUE) {OS_ENTER_CRITICAL();OSLockNesting++;OS_EXIT_CRITICAL();}}给任务调度器解锁的函数如下void OSSchedUnlock (void){if (OSRunning == TRUE) {OS_ENTER_CRITICAL();if (OSLockNesting > 0) {OSLockNesting‐‐;if ((OSLockNesting | OSIntNesting) == 0) { (1)OS_EXIT_CRITICAL();OSSched(); (2)} else {OS_EXIT_CRITICAL();}} else {OS_EXIT_CRITICAL();}}}它实现的原理大致是这样的。

ucosii互斥信号量的用法

ucosii互斥信号量的用法

ucosii互斥信号量的用法在嵌入式系统中,互斥信号量是一种非常重要的同步机制,它可以用来保护对共享资源的访问,防止多个任务同时访问而造成的数据冲突。

ucosii实时操作系统就提供了这种机制,使用互斥信号量可以保证在任何时刻只有一个任务在访问共享资源。

一、什么是互斥信号量在ucosii中,互斥信号量是一种特殊的二进制信号量,它的值可以为0或1,用来表示该资源是否被占用。

如果该资源的所有者允许其他任务访问,则该信号量的值为1;否则为0。

在任何时刻,只有一个任务能够访问被保护的资源,因此互斥信号量也被称为互斥锁。

二、互斥信号量的使用在使用互斥信号量时,需要先定义一个信号量对象,然后在需要保护的临界区前面使用semop()函数来设置信号量的值。

当其他任务需要访问被保护的资源时,需要先获取该信号量,进入临界区后释放该信号量。

具体步骤如下:1.定义一个信号量对象semaphorelock;2.在需要保护的临界区前,使用semop()函数设置信号量的值为1;3.其他任务需要访问被保护的资源时,使用semop()函数获取该信号量;4.进入临界区后释放该信号量;5.避免在其他任务释放信号量之前访问临界区,否则可能会发生竞争条件(racecondition)。

三、使用示例下面是一个使用ucosii互斥信号量的示例代码:#include"os.h"#defineKEY1#defineNO_KEY0voidtask1(void*arg){while(1){//获取互斥锁if(semop(lock,&req,1)==-1){//获取失败,等待其他任务释放锁}else{//进入临界区//对共享资源进行操作}}}voidtask2(void*arg){while(1){//释放互斥锁semop(lock,&rel,1);}}在上面的代码中,task1和task2分别代表两个任务。

task1在访问共享资源之前需要获取互斥锁,否则会一直等待;task2则负责释放互斥锁,以便其他任务可以访问共享资源。

ucOSII学习笔记(标志事件组_信号量_邮箱_互斥)

ucOSII学习笔记(标志事件组_信号量_邮箱_互斥)

目前因项目开发要用到ucOSII,在网上查找到了一些资料,为方便其他同仁,把我个人认为写得很好的文档摘抄到一个文件中,并上传到百度空间,希望对初学都有所帮助。

UCOS事件标志组管理笔记Ⅰ说明:本文摘自网上,来源已忘记,望原作者见谅。

当某个任务需要与多个任务同步时,须要使用事件标志组。

1、弄清楚OS_FLAG_GRP、OS_FLAG_NODE和OS_TCB之间的关系。

当一个任务开始等待某些事件标志位时,就回建立一个事件标志节点OS_FLAG_NODE数据结构,并且将任务所要等待的事件标志位写入OS_FLAG_NODE的分量.OSFlagNodeFlags。

然后将该数据结构分量.OSFlagNodeFLagGrp指向事件标志组OS_FLAG_GRP,将.OSFlagNodeTCB 指向该任务的控制块OS_TCB,建立起任务与事件标志组之间的联系,说明该任务是等待该事件标志组中某些事件标志位的任务。

当有多个任务都需要等待某个事件标志组中某些事件标志位时,这些任务分别建立自己的事件标志节点。

并且将这些事件标志节点通过分量.OS FlagNodeNext和.OSFlagNodePrev连接成链。

⒉、任务可以等待事件标志组中某些位置位1,也可以等待事件标志组中某些位清0,而置1(或清0)又可以分为所有事件都发生的“与”型和任何一个事件发生的“或”型。

这样便有了4种不同的类型存放在.OSFlagNodeWaitType(OS_FLAG_NODE)中。

3、事件标志组和信号量我觉得是有不同的。

信号量建立以后,假设初始值为N,前N个任务调用OSSemPend()函数都会得到信号量。

之后如果第N+1个任务调用OSSemPend()函数申请信号量,该任务将会被置为等待事件发生的状态(睡眠态)。

只到前N个任务中有任务运行完了所要运行的程序,调用OSSenmP ost()函数,释放了所占用了信号量,第N+1个任务。

(这里假设该任务是所有等待信号量任务中优先级最高的任务)才会获得信号量,被从睡眠态转入就绪态。

uCOSII原理及应用

uCOSII原理及应用
通过任务函数实现特定的功能,每个任务函数 对应一个独立的执行线程。
任务控制块
用于存储任务的运行状态和控制信息,包括任 务的优先级、状态、堆栈指针等。
任务切换函数
用于实现任务之间的切换,包括保存当前任务的上下文和恢复下一个任务的上 下文。
ucosii的任务管理
创建任务
通过调用ucosii提供的函数, 创建新的任务并分配相应的 资源。
在物联网应用中,ucosii能够为各种智能硬件提供统一的操 作系统平台,实现设备的互联互通和智能化管理。同时, ucosii还提供了丰富的中间件和驱动程序,方便开发者快速 开发出各种智能硬件和应用软件。
ucosii在嵌入式系统中的应用
嵌入式系统是指嵌入到硬件中的计算机系统,具有特定的功能和性能要求。ucosii作为一种实时操作 系统,在嵌入式系统中也有着广泛的应用。
调试工具
使用JTAG、SWD等调试工具,通过串口、网络等方式与目标板进行通信,实现程序的 下载、运行、断点设置等操作。
调试步骤
首先确认硬件连接正确,然后通过调试工具将程序下载到目标板中,设置断点并运行程 序,观察程序运行过程中变量的变化和程序的执行流程。
常见问题
硬件连接问题、调试工具配置问题、程序编译错误等。
ucosii的性能分析
性能指标
响应时间、吞吐量、资源利用率等。
分析方法
通过代码审查、性能测试、瓶颈分析等方法,找出影响性能的 关键因素,如算法复杂度、内存访问模式、IO性能等。
优化建议
针对分析结果,提出优化建议,如改进算法、优化数据结 构、减少IO操作等。
ucosii的优化建议
算法优化
通过改进算法,减少计算量和复杂度,提高程序执行效率。
易用性

uCOS-II嵌入式操作系统介绍与移植

uCOS-II嵌入式操作系统介绍与移植

OSStartHighRd
1、该函数是在OSStart函数中调用 2、负责从最高优先级任务的TCB中获得该任务的堆
栈指针sp,并依次将cpu现场恢复,这时系统就将 控制权交给用户创建的该任务进程,直到该任务被 阻塞或者被其他更高优先级的任务抢占cpu 3、该函数仅在多任务启动时被执行一次,用来启 动之前创建的第一个,也就是最高优先级的任务执 行
3、可从网站上获 得全部源码及其在各种体系结构平 台上的移植范例。
uC/OS-II特点
1、uC/OS-II内核具有可抢占的实时 多任务调度功能
2、提供了许多系统服务,如信号量、 消息队列、邮箱、内存管理、时间 函数等
3、这些功能可以根据不同的需求进 行裁减。
uC/OS-II的移植
ARM处理器相关宏定义
1、退出临界区
#defineOS_ENTER_CRITICAL() ARMDisableInt()
2、进入临界区
#defineOS_EXIT_CRITICAL() ARMEnableInt()
堆栈增长方向
1、堆栈由高地址向低地址增长,这个也 是和编译器有关的,当进行函数调用时, 入口参数和返回地址一般都会保存在当 前任务的堆栈中,编译器的编译选项和 由此生成的堆栈指令就会决定堆栈的增 长方向。
#define OS_STK_GROWTH 1
OS_CPU.c的移植
1、任务堆栈初始化 2、系统hook函数 3、中断级任务切换函数
任务堆栈初始化OSTaskStkInit
1、由OSTaskCreate或OSTaskCreateExt调用 2、用来初始化任务的堆栈并返回新的堆栈指针stk。
退出/进入临界区函数 ARMDisableInt/ARMEnableInt

uCOS-II简介

uCOS-II简介

4.1OC/OS-II简介UC/OS-II 是一种基于优先级的可抢先的硬实时内核。

自从92 年发布以来,在世界各地都获得了广泛的应用,它是一种专门为嵌入式设备设计的内核,目前已经被移植到40 多种不同结构的CPU 上,运行在从8 位到64 位的各种系统之上。

尤其值得一提的是,该系统自从2.51版本之后,就通过了美国FAA 认证,可以运行在诸如航天器等对安全要求极为苛刻的系统之上。

鉴于UC/OS-II 可以免费获得代码,对于嵌入式RTOS 而言,选择UC/OS 无疑是最经济的选择。

需要说明的是,UC/OS-II 作为一个实时操作系统只提供了多任务调度等基本功能,这在实际应用中显然是不够的。

除了移植好的操作系统内核部分,还必须有文件系统,全部硬件的驱动程序,图形API,控件函数,综合提高的消息函数以及几个系统必须的基本任务,象键盘,触摸屏,LCD 刷新等。

有了这些,UC/OS-II 才能实现复杂的功能。

特殊需求的地方还需要像USB通信协议,TCP/IP 协议等更复杂的软件模块。

博创提供的UC/OS-II 库文件中包含了上述大部分功能,基于库的开发变的非常简单,在基本的程序框架下应用我们提供的丰富API 函数即可。

实际开发中,用户的工程中无需包括UC/OS-II 的源代码,只需要包括库文件即可。

当然,用户也可以了解库中部分代码的源文件,可以根据自己的需求就行重新编译,也可以对自己的一系列源文件生成一个专门的库,方便自己后续工作。

UC/OS-II 的开发中,应用程序和操作系统是绑在一起编译的,所生成的system.bin 文件是唯一的可执行文件,其中包括了所需要的UC/OS-II 代码和被用到的驱动程序等函数代码,以及应用程序的代码。

system.bin 文件是存放在平台的16M FLASH 中的,在系统启动时由BIOS依靠文件系统从FLASH 中读入到SDRAM 中,然后把控制转移到该代码上,完成所谓的引导。

UCOS-II-信号量的理解

UCOS-II-信号量的理解
1. 信号量的理解
(1)uc/os-ii的信号量是由两个部分组成:一部分是16位的无符号整型信号量的计数值(0~65535);另一部分是等待该信号量的任务组成的等待任务表。(另外参考事件控制块ECB)
(2)信号量可以是2值的变量(称为二值信号量),也可以是计数式的。根据信号量的值,内核跟踪那些等待信号量的任务。
----------------------------------------------------------------
互斥型信号量
1.互斥型信号量(mutex)
互斥型信号量具备uc/os-ii信号量的所有机制,但还具有其他一些特性。
任务可利用互斥型信号量来实现对共享资源的独占处理。
如果如果任务Task_A调用OSSemPend(),信号量无效(为0),那么OSSemPend()调用OS_EventTaskWait()函数,把Task_A放入等待列表中。(等待到什么时候呢?要看OSSemPost()(或者等待超时情况),由它释放信号量并检查任务执行权,见下资料)
◆OSSemPost() 发出(释放)一个信号量 (注:由任务或中断操作)
Mutex是二值信号量,1表示资源是可以使用的。
2.关于优先级反转
下面概述优先级反转原理:
假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。此时任务C得以继续运行。

uCOS-ii 中常用变量说明

uCOS-ii 中常用变量说明

同样OSUnMapTbl[ ];也是为了加速优先级定义的一个数组。
13,对于信号量,消息邮箱,消息队列构成的事件数据结构,作为功能完善的事件处理,应该对系统的等待任务进行一定的管理。这个管理的功能包括两个方面。一是要对等待事件的所有任务进行记录并排序。二是应该允许任务有一定的等待时限。对于这些事件任务的记录和处理,UCOSII采用了与任务就绪表类似的方法,使用一个数组INT8U OSEventTbl[ ]作为记录等待事件任务的记录表,即等待任务表。同样为了加快对此表的反应速度,增加了INT8U OSEventGrp.这个事件表和任务就绪表格式一样。叫任务等待表。
OS_MAX_MEM_PARTS
OS_MAX_MEM_PARTS定义系统中最大的内存块数,内存块将由内存管理函数操作(定义在文件OS_MEM.C中)。如果要使用内存块,OS_MAX_MEM_PARTS最小应该设置为2,常量OS_MEM_EN也要同时置1。
OS_MAX_QS
OS_MAX_QS定义系统中最大的消息队列数。要使用消息队列 ...
OS_MAX_EVENTS
OS_MAX_EVENTS定义系统中最大的事件控制块的数量。系统中的每一个消息邮箱,消息队列,信号量都需要一个事件控制块。例如,系统中有10个消息邮箱,5个消息队列,3个信号量,消息邮箱,消息队列或是信号量,则OS_MAX_EVENTS最小应该设置为2。
本章将介绍μC/OS-II中的初始化配置项。由于μC/OS-II向用户提供源代码,初始化配置项由一系列#define constant语句构成,都在文件OS_CFG.H中。用户的工程文件组中都应该包含这个文件。本节介绍每个用#define constant定义的常量,介绍的顺序和它们在OS_CFG.H中出现的顺序是相同的。表12.1列出了常量控制的μC/OS-II函数。“类型”为函数所属的类型,“置1”表示当定义常量为1时可以打开相应的函数,“其他常量”为与这个函数有关的其他控制常量。注意编译工程文件时要包含OS_CFG.H,使定义的常量生效。表T12.1 μC/OS-II函数和相关的常量(#define constant定义)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(5)任务对信号量的释放问题。
任务执行发信号(post)操作来释放信号量。如果没有任务等待信号量,那么信号量的值仅是简单的加1(则信号量大于0,有效);如果有任务等待该信号量,那么就会有另一个任务进入就绪态,信号量的值就不加1。
之后,这个释放的信号量给那个等待中的任务,要看内核如何调度的。收到信号量的任务可能是如下两者之一:
◆等待任务中,优先级最高的;(uc/os-ii仅支持这种方式)。
◆最早开始等待信号量的任务(如果是按先进先出FIFO原则)。
2. 信号量的有效与无效问题
信号量有效:信号量的计算器非0(.OSEventCnt!=0)。信号量有效表示任务对资源可用。
信号量无效:信号量的计算器为0。信号量无效表示任务对目前资源不可用,需要等待其他另一个任务(或者中断服务子程序)发出该信号量(OSSemPost)。
(2)信号量可以是2值的变量(称为二值信号量),也可以是计数式的。根据信号量的值,内核跟踪那些等待信号量的任务。
(3)建立信号量的工作必须在任务级代码中或者多任务启动之前完成。
(4)任务要得到信号量的问题。
想得到信号量的任务,必须执行等待操作(pend)。如果信号量有效(非0),则信号量减1,任务得以继续运行。如果信号量无效,则等待信号量的任务就被列入等待信号量的任务表中。多少内核允许定义等待超时,当等待时间超过了设定值,该信号量还是无效,则等待该信号量的任务进入就绪态,准备运行,并返回出错代码(等待超时错误)。
3. 信号量的值(.OSEventCnt)大小表示什么?
二值信号量,表示任务可以独占共享资源。
计数式信号量,用于某资源可同时为N个任务所用。
4. 信号量是如何实现任务之间的通信的?
参见第1点的(4)(5)概述。
5. 信号量有关的三个重要函数分析
◆OSSemCreate() 创建一个信号量 (注:由任务或启动代码操作)
Mutex是二值信号量,1表示资源是可以使用的。
2.关于优先级反转
下面概述优先级反转原理:
假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。此时任务C得以继续运行。
创建工作必须在任务级代码中或者多任务启动之前完成。功能只要是先获取一个事件控制块ECB,写入一些参数。其中调用了OS_EeventWaitListInt()函数,对事件控制块的等待任务列表进行初始化。完成初始化工作后,返回一个该信号量的句柄(Handle)。
◆OSSemPend() 等待一个信号量 (注:只能由任务操作)
如果如果任务Task_A调用OSSemPend(),信号量无效(为0),那么OSSemPend()调用OS_EventTaskWait()函数,把Task_A放入等待列表中。(等待到什么时候呢?要看OSSemPost()(或者等待超时情况),由它释放信号量并检查任务执行权,见下资料)
◆OSSemPost() 发出(释放)一个信号量 (注:由任务或中断操作)
综述上面情况,任务C和任务A的优先级发生了反转。
而互斥型信号量就是具有解决优先级反转问题的特性。
3.uc/os-ii的互斥型信号量由三个部分组成:
◆一个标志,指示mutex是否可以使用(0或1)
◆一个优先级,准备一旦高优先级的任务需要这个mutex,赋予给占有mutex的任务。
◆一个等待该mutex的任务列表。
1. 信号量的理解
(1)uc/os-ii的信号量是由两个部分组成:一部分是16位的无符号整型信号量的计数值(0~65535);另一部分是等待该信号量的任务组成的等待任务表。(另外参考事件控制块ECB)
----------------------------------------------------------------
互斥型信号量
1.互斥型信号量(mutex)
互斥型信号量具备uc/os-ii信号量的所有机制,但还具有其他一些特性。
任务可利用互斥型信号量来实现对共享资源的独占处理。
本函数其中调用OS_EventTaskRdy()函数,把优先级最高的任务Task_A(在这假如是Task_A,另外假设当前调用OSSemPost()的任务是Task_B)从等待任务列表中去除,并使它进入就绪态。然后调用OSSched()进行任务调度。如果Task_A是当前就绪态中优先级最高的任务,则内核执行Task_A;否则,OSSched()直接返回,Task_B继续执行.
同理,任务B的事件到来后,会剥夺任务C的CPU使用权。任务B把事情搞定以后,把CPU使用权归还给任务B(呵呵,优先级低就是给人欺负啊,所以做人还真的要争口气!)。任务B又得以继续运行,任务B认真处理完毕资源S1后,终于可以释放S1的信号量。而处于等待该信号量的任务A马上得到信号量并开始处理共享资源S1。
本函数应用于任务试图获得共享资源的使用权、任务需要与其他任务或中断同步及任务需要等待特定事件发生mPend(),且信号量的值有效(非0),那么OSSemPend()递减信号量计数器(.OSEventCnt),并返回该值。换句话说,Task_A获取到共享资源的使用权了,之后就执行该资源。
相关文档
最新文档