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-II

实验一、任务创建与删除1、uC/OS-II介绍对于操作系统的学习,创建任务和删除任务是最为基础的工作,uC/OS-II以源代码的形式发布,是开源软件, 但并不意味着它是免费软件。
可以将其用于教学和私下研究;但是如果将其用于商业用途,那么必须通过Micrium获得商用许可。
uC/OS-II属于抢占式内核,最多可以支持64个任务,分别对应优先级0~63,每个任务只能对应唯一的优先级,其中0为最高优先级。
63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。
uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。
系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整型变量做累加运算;另一个是系统任务,它的优先级为次低,该任务负责统计当前cpu的利用率。
μC/OS-II可管理多达63个应用任务,并可以提供如下服务,本章将针对以下服务分别以例程的方式来介绍1)信号量2)互斥信号量3)事件标识4)消息邮箱5)消息队列6)任务管理7)固定大小内存块管理8)时间管理2、任务创建与删除想让uC/OS-II管理用户的任务,用户必须要先建立任务,在开始多任务调度(即调用OSStart())前,用户必须建立至少一个任务。
uC/OS-II提供了两个函数来创建任务:OSTask Create()或OSTaskCreateExt()。
可以使用其中任意一个即可,其函数原型如下:INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U pri o)INT8U OSTaskCreateExt (void(*task)(void *pd),void *pdata,SD_STK *ptos,INT8U prio, INT16U id,OS_STK *pbos,INT32U stk_size, void *pext,INT16U opt)task:任务代码指针pdata:任务的参数指针ptos:任务的堆栈的栈顶指针prio:任务优先级id:任务特殊的标识符(uC/OS-II中还未使用)pbos:任务的堆栈栈底的指针(用于堆栈检验)stk_size:堆栈成员数目的容量(宽度为4字节)pext:指向用户附加的数据域的指针opt:是否允许堆栈检验,是否将堆栈清零,任务是否要进行浮点操作等等删除任务,是说任务将返回并处于休眠状态,任务的代码不再被uC/OS-II调用,而不是删除任务代码。
UCOS-II和UCOS-III的性能对比(中文)

否
是
是
是
否
是
uC/OS-III 中文资料
任务级的时基定时 否
器处理
提供的服务
~20
MISRA-C:1998
否
MISRA-C:2004
否
DO178B
否
EUROCAE ED-12B
FDA 认证
否
SIL3/SIL4 IEC
否
IEC-61508
否
否
是
~90
~70
是(除了 10 个规 N/A
则)
否
是(除了 7 个规则)
是
申请中
是
申请中
是
ห้องสมุดไป่ตู้
北航ARM9实验报告:实验3uCOS-II实验

北航ARM9实验报告:实验3uCOS-II实验北航 ARM9 实验报告:实验 3uCOSII 实验一、实验目的本次实验的主要目的是深入了解和掌握 uCOSII 实时操作系统在ARM9 平台上的移植和应用。
通过实际操作,熟悉 uCOSII 的任务管理、内存管理、中断处理等核心机制,提高对实时操作系统的理解和应用能力,为后续的嵌入式系统开发打下坚实的基础。
二、实验环境1、硬件环境:ARM9 开发板、PC 机。
2、软件环境:Keil MDK 集成开发环境、uCOSII 源代码。
三、实验原理uCOSII 是一个可裁剪、可剥夺型的多任务实时内核,具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点。
其基本原理包括任务管理、任务调度、时间管理、内存管理和中断管理等。
任务管理:uCOSII 中的任务是一个独立的执行流,每个任务都有自己的堆栈空间和任务控制块(TCB)。
任务可以处于就绪、运行、等待、挂起等状态。
任务调度:采用基于优先级的抢占式调度算法,始终让优先级最高的就绪任务运行。
时间管理:通过系统时钟节拍来实现任务的延时和定时功能。
内存管理:提供了简单的内存分区管理和内存块管理机制。
中断管理:支持中断嵌套,在中断服务程序中可以进行任务切换。
四、实验步骤1、建立工程在 Keil MDK 中创建一个新的工程,选择对应的 ARM9 芯片型号,并配置相关的编译选项。
2、导入 uCOSII 源代码将 uCOSII 的源代码导入到工程中,并对相关的文件进行配置,如设置任务堆栈大小、系统时钟节拍频率等。
3、编写任务函数根据实验要求,编写多个任务函数,每个任务实现不同的功能。
4、创建任务在主函数中使用 uCOSII 提供的 API 函数创建任务,并设置任务的优先级。
5、启动操作系统调用 uCOSII 的启动函数,使操作系统开始运行,进行任务调度。
6、调试与测试通过单步调试、查看变量值和输出信息等方式,对系统的运行情况进行调试和测试,确保任务的执行符合预期。
ucosii 互斥信号量 创建条件

ucosii 互斥信号量创建条件摘要:1.ucosii 简介2.互斥信号量的概念3.互斥信号量的创建条件4.互斥信号量在ucosii 中的应用正文:【1.ucosii 简介】ucosii是一款基于μC/OS-II实时操作系统的嵌入式软件开发平台。
μC/OS-II是一个源代码公开的实时操作系统内核,其主要特点是可移植性强、占用资源少、实时性能优越,适用于各种嵌入式系统。
ucosii在μC/OS-II的基础上,提供了丰富的组件和工具,便于开发者快速构建嵌入式系统。
【2.互斥信号量的概念】互斥信号量(Mutex)是一种同步原语,用于实现多任务之间的互斥访问。
互斥信号量有一个计数器,用于表示当前有多少任务正在访问共享资源。
当一个任务要访问共享资源时,需要先请求互斥信号量。
如果计数器为零,表示当前没有其他任务访问共享资源,请求信号量后计数器加一,任务可以访问共享资源;如果计数器大于零,表示其他任务正在访问共享资源,请求信号量后计数器加一,任务需要等待其他任务访问完成后才能访问共享资源。
任务访问完共享资源后,释放互斥信号量,计数器减一,表示可以有其他任务访问共享资源。
【3.互斥信号量的创建条件】在ucosii 中,创建互斥信号量需要满足以下条件:1.互斥信号量对象需要分配在用户空间,不能分配在内核空间。
2.互斥信号量对象的初始化需要保证计数器为零,表示没有任务访问共享资源。
3.互斥信号量对象需要关联一个等待队列,用于存放等待访问共享资源的任务。
【4.互斥信号量在ucosii 中的应用】在ucosii 中,互斥信号量可以用于保护共享资源,避免多任务同时访问导致的数据不一致问题。
以下是一个简单的互斥信号量使用示例:```c#include "ucosii.h"#include "ucosii_os.h"// 定义共享资源int32_t g_data;// 创建互斥信号量MUTEX_T g_mutex;// 初始化互斥信号量void init_mutex() {mutex_init(&g_mutex, 0);}// 访问共享资源void access_data() {int32_t i;for (i = 0; i < 10; i++) {// 获取互斥信号量mutex_lock(&g_mutex);// 访问共享资源g_data = i;// 释放互斥信号量mutex_unlock(&g_mutex);}}// 任务入口void app_main() {init_mutex();// 启动多个任务访问共享资源while (1) {task_create(1, access_data, NULL);}}```在这个示例中,我们定义了一个共享资源g_data,并创建了一个互斥信号量g_mutex。
嵌入式μcosii内核实验四哲学家就餐问题的实现

操作系统配置
#define OS_LOWEST_PRIO
7
/*任务优先级不能够不小于7*/
#define OS_SEM_EN
1
/*是否允许使用信号量功能*/
#define OS_MAX_EVENTS
5
/*最多能够有5个事件*/
#define OS_TICKS_PER_SEC 200 /*设置每秒之内旳时钟节拍数目*/
本试验中所用到旳µC/OS-II有关函数
□ OSTaskCreateExt () : 创建一种任务 □ OSSemCreate() :建立并初始化一种信号量 □ OSSemPend() :申请信号量 □ OSSemPost() :释放信号量 □ OSTimeDly():将一种任务延时若干个时钟节拍
操作系统配置
#define OS_TASK_CREATE_EN
1
/*允许使用OSTaskCreate()*/
#define OS_TASK_STAT_EN
0
/* 禁止统计任务*/
#define OS_MAX_TASKS
6
/*最多能够创建6个任务*/
ห้องสมุดไป่ตู้
#define OS_TASK_CREATE_EXT_EN 1 /*是否允许使用OSTaskCreateExt()*/
源程序阐明
TaskStart负责:
□安装时钟中断服务例程
–ucos_x86_idt_set_handler(0x20,(void *)OSTickISR,0x8e00);
□初始化操作系统时钟
–ucos_timer_init();
□创建信号量
–fork[i] = OSSemCreate(1);
互斥信号量和二值信号量

互斥信号量和二值信号量互斥信号量和二值信号量是计算机科学中常用的同步机制。
它们的作用是确保在多线程或多进程环境中,对共享资源的访问顺序和正确性。
本文将分别介绍互斥信号量和二值信号量的概念、原理和应用。
互斥信号量是一种特殊类型的信号量,它的值只能是0或1。
当互斥信号量的值为1时,表示共享资源未被占用,可以被访问;当互斥信号量的值为0时,表示共享资源已被占用,其他线程或进程需要等待。
互斥信号量的原理是通过对共享资源的访问进行加锁和解锁操作来实现同步。
当一个线程或进程要访问共享资源时,首先需要尝试将互斥信号量的值减1,如果成功,则表示资源未被占用,可以访问;如果失败,则表示资源已被占用,需要等待其他线程或进程释放资源。
互斥信号量的应用非常广泛。
在操作系统中,互斥信号量常被用于实现进程间的互斥访问和同步操作。
在多线程编程中,互斥信号量可以避免多个线程同时访问共享资源导致的数据竞争和不一致性。
例如,在一个多线程的银行账户系统中,多个线程同时对同一个账户进行存款或取款操作,就需要使用互斥信号量来确保只有一个线程能够访问账户并更新余额。
二值信号量与互斥信号量类似,也是一种特殊类型的信号量,它的值只能是0或1。
不同之处在于,二值信号量的值为0时,表示共享资源不可用;值为1时,表示共享资源可用。
二值信号量的原理和互斥信号量相似,通过加锁和解锁操作来实现对共享资源的同步访问。
当一个线程或进程需要访问共享资源时,首先需要尝试将二值信号量的值减1,如果成功,则表示资源可用,可以访问;如果失败,则表示资源不可用,需要等待其他线程或进程释放资源。
二值信号量的应用也非常广泛。
在操作系统中,二值信号量常被用于实现生产者-消费者模型。
生产者线程负责生产数据并将其放入一个共享缓冲区,消费者线程负责从缓冲区中取出数据进行消费。
为了避免生产者和消费者同时访问缓冲区导致的数据竞争和不一致性,可以使用一个二值信号量来控制对缓冲区的访问。
当缓冲区为空时,消费者需要等待生产者将数据放入缓冲区;当缓冲区已满时,生产者需要等待消费者将数据取出。
uCOS-II中关于信号量的使用总结

uCOS-II中关于信号量的使用总结
在ucos-II中,为了实现任务之间的同步,用到的同步机制有:信号量,邮箱和消息队列。
其中这里我主要说下对信号量的使用经验。
信号量在创建时,调用OSSemCreate(INT16U cnt)函数。
cnt为信号量的初始值。
对cnt赋予不同的值,所起到的作用不同。
如果Semp = OSSemCreate(0), 该信号量表示等待一个事件或者多个事件的发生。
例如:我们现在想实现这样一个功能:当有按键按下时,PWM蜂鸣器响起;无按键时,蜂鸣器不响。
这是我们就可以分别建立两个任务,Task1和Task2,在Task1中处理按键的按下与否,一旦按下,则调用OSSemPost(Semp)发送这里信号量。
在Task2中调用OSSemPend(Semp,0,&err)请求此信号量,如果信号量可用,则调用蜂鸣器程序蜂鸣,否则无限等待,任务自动进行切换。
如果我们想对一个公共资源进行互斥访问,例如:如果我们想让两个任务Task1和Task2都可以调用Fun()函数,但不能同时调用,最好定义Semp = OSSemCreate(1),同理在各自的任务中都需要调用OSSemPend(Semp,0,&err)请求此信号量,如果可用,则调用Fun(),然后再调用OSSemPost(Semp)释放该信号量。
这里就实现了一个资源的互斥访问。
同理,如果一个任务要等待n个事件发生后才能执行,则应定义为Semp = OSSemCreate(n)。
然后在这n 个任务分别运行时调用OSSemPost(Semp),直到这n个事件均发生后,这个任务才能运行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
μCOS-II互斥信号量
Application Note
AN-1002
Jean J. Labrosse
brosse@
概述:
使用互斥信号(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)创建了一个互斥信号。
需要注意的是,OSMutexCreate()函数使用PIP最为参数。
然后创建三个任务L1(3),启动μC/OS-II L1(4).
假设任务运行了一段时间,在某个时间点,任务#3最先访问了共同的资源,并得到了互斥信号,任务#3运行了一段时间后被任务#1抢占。
任务#1需要使用这个资源,并通过调用OSMutexPend()企图获得互斥信号,这种情况下,OSMutexPend()会发现一个高优先级的任务需要这个资源,就会把任务#3的优先级提高到9,同时强迫进行上下文切换退回到任务#3执行。
任务#3可以继续执行然后释放占用的共同资源。
任务#3通过调用OSMutexPost()释放占用的mutex信号,OSMutexPost()会发现mutex被一个优先级提升的低优先级的任务占有,就会把任务#3的优先级返回到20。
把资源释放给任务#1使用,执行上下文切换到任务#1
Listing 1, 互斥信号使用示例
-----------------------------------------------------------------
OS_EVENT *ResourceMutex;
OS_STK TaskPrio10Stk[1000];
OS_STK TaskPrio15Stk[1000];
OS_STK TaskPrio20Stk[1000];
void main (void)
{
INT8U err;
OSInit(); /* (1) */
/* ---------- 应用程序初始化---------- */
OSMutexCreate(9, &err); /* (2) */
OSTaskCreate(TaskPrio10, (void *)0, &TaskPrio10Stk[999], 10); /* (3) */ OSTaskCreate(TaskPrio15, (void *)0, &TaskPrio15Stk[999], 15); OSTaskCreate(TaskPrio20, (void *)0, &TaskPrio20Stk[999], 20);
/* ---------- Application Initialization ---------- */
OSStart(); /* (4) */
}
void TaskPrio10 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* --------- 应用程序代码---------- */
OSMutexPend(ResourceMutex, 0, &err);
/* ------- 访问贡献资源------ */
OSMutexPost(ResourceMutex);
/* --------- 应用程序代码---------- */
}
}
void TaskPrio15 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* ---------应用程序代码---------- */
OSMutexPend(ResourceMutex, 0, &err);
/* ------- 访问共享资源------ */
OSMutexPost(ResourceMutex);
/* --------- 应用程序代码---------- */
}
}
void TaskPrio20 (void *pdata)
{
INT8U err;
pdata = pdata;
while (1) {
/* ---------应用程序代码---------- */
OSMutexPend(ResourceMutex, 0, &err);
/* -------访问共享资源------ */
OSMutexPost(ResourceMutex);
/* ---------应用程序代码---------- */
}
}
μC/OS-II'互斥信号包含三个元素,一个flag表示当前mutex是否能够获得(0或1);一个priority表示使用这个mutex的任务,以防一个高优先级的任务需要访问mutex;还包括一个等待这个mutex的任务列表。
为了启动μC/OS-II’s mutex服务,应该在OS_CFG.H中设置OS_MUTEX_EN=1。
在使用一个互斥信号之前应该首先创建它,创建一个mutex信号通过调用OSMutexCreate()完成,mutex的初始值总是设置为1,表示资源可以获得。
μC/OS-II提供了六种访问互斥信号量的操作OSMutexCreate(), OSMutexDel(), OSMutexPend(), OSMutexPost(), OSMutexAccept() and OSMutexQuery(). Figure 1 展示了任务和互斥信号量的关系。
一个互斥信号量只能被任务访问。
在途中使用钥匙符号表示互斥信号。
钥匙符号表明互斥信号用来访问共享资源。