实验七 uCOS的信号量
UCOS配置注释
#define OS_MAX_QS 1 //最大的消息队列数。要使用消息队列,常量OS_Q_EN也要同时置1。如果要使用消息队列,OS_MAX_ QS最小应该设置为2*/
// ---------------- 互斥型信号量管理--------------- */
#define OS_MUTEX_EN 1 // 允许(1)或者禁止(0) MUTEX */
#define OS_MUTEX_ACCEPT_EN 1 // 允许生成函数代码OSMutexAccept() */
#define OS_TASK_QUERY_EN 1 // 允许生成函数代码OSTaskQuery() */
// ------------------时间管理--- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN 1 //允许生成函数代码OSTimeDlyHMSM() */
#define OS_TIME_DLY_RESUME_EN 1 //允许生成函数代码OSTimeDlyResume() */
#define OS_MBOX_DEL_EN 1 // 允许生成函数代码OSMboxDel() */
#define OS_MBOX_POST_EN 1 // 允许生成函数代码OSMboxPost() */
#define OS_TASK_DEL_EN 1 // 允许生成函数代码OSTaskDel() */
#define OS_TASK_SUSPEND_EN 1 // 允许生成函数代码OSTaskSuspend() and OSTaskResume() */
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信号量
浅析UCOS信号量信号量有3种用途:1) 表达事件的发生次数或者已发生事件的数量。
2) 表达资源可用性,例如有一台打印机,信号量值为1表示打印机空闲,为0表示打印机被占用。
这是资源可用量的一个特例,也可以说,信号量值为1表示有1台打印机空闲,为0表示无打印机空闲。
3) 表达资源可用量,例如有10个串口,信号量值用于表达空闲串口数量。
UCOS代码没有显式地区分信号量的用途并作分别处理,因为这些用途的代码处理是完全相同的。
假设信号量用于表达事件发生的次数,OSSemCreate创建一个事件,初始化事件计数器初值为0。
当一个任务等待事件发生时,若事件未发生,事件计数器为0,任务保持等待状态。
假设信号量用于表达资源可用性(或数量),OSSemCreate创建一个事件,初始化资源计数器初值为10。
当一个任务等待资源可用时,若无可用资源,资源计数器为0,任务保持等待状态。
事件计数器和资源计数器在程序中是同一个变量,可见,当这个变量为0时,无论用于信号量用于事件计数器还是资源计数器,都会使(等待事件的和申请资源的)任务保持等待状态。
假设信号量用于表达事件发生的次数,某个任务或中断触发了事件,事件计数器递增为非0,表示事件已发生,UCOS会调度等待事件发生的任务获得执行。
假设信号量用于表达资源可用性(或数量),当一个任务用完并释放资源时资源计数器递增为非0,表示有资源可用,UCOS会调度等待资源可用的任务获得执行。
事件计数器和资源计数器在程序中是同一个变量,可见,当这个变量非0时,无论信号量用于事件计数器还是资源计数器,都会使(等待事件的和申请资源的)任务获得执行。
OSSemPend,等待事件发生,或者等待资源可用,都是等待事件计数器(资源计数器)变为非0。
OSSemPost,触发事件发生,或者通知资源可用,都是将事件计数器(资源计数器)递增为非0。
在调用OSSemPend时,若事件已发生,或者资源已可用,事件计数器(资源计数器)已是非0,就要调度等待事件的或者等待资源的任务获得执行,并递减事件计数器(资源计数器)。
ucOS简要教程
第一篇 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 上。
严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。
ucos信号量用法
ucos信号量用法uC/OS中的信号量是一种用于同步和互斥的机制,常用于任务之间的通信和资源的共享。
下面是在uC/OS中使用信号量的一般步骤:1. 创建信号量:使用`OS_SEM_CREATE`宏或`OS_SEM_CREATE_EX`函数创建一个信号量。
这些函数会返回一个信号量控制块(Semaphore Control Block,简称SCB)的指针。
```cOS_SEM_CREATE_EX(p_sem, p_name, initial_value)```2. 等待(等待信号量):在任务中使用`OS_SEM_PEND`宏或`OS_SEM_PEND_EX`函数等待信号量。
如果信号量的值大于0,则任务会继续执行;否则任务会被阻塞,直到有信号量可用。
```cOS_SEM_PEND_EX(p_sem, timeout, ret_err)```3. 产生(发信号量):使用`OS_SEM_POST`宏或`OS_SEM_POST_EX`函数来发信号量。
这会增加信号量的值,并唤醒正在等待该信号量的任务。
```cOS_SEM_POST_EX(p_sem, opt, ret_err)```4. 删除信号量:使用`OS_SEM_DEL`宏或`OS_SEM_DEL_EX`函数删除信号量。
这会释放信号量的相关资源。
```cOS_SEM_DEL_EX(p_sem, opt, ret_err)```在uC/OS中,还可以设置信号量的属性,例如信号量的名称、触发模式、超时时间等。
具体用法可以参考uC/OS的用户手册或API文档。
ucos信号量用法
ucos信号量用法一、引言在嵌入式系统的开发中,ucos作为一个开源的实时操作系统,被广泛应用于各种嵌入式设备中。
信号量是ucos中一种重要的同步机制,用于解决多任务环境下资源竞争的问题。
本文将介绍ucos中信号量的用法和注意事项。
二、信号量的概念信号量是一种用于多任务同步和资源管理的机制。
在ucos中,信号量是一种计数型变量,用于实现任务的互斥访问和同步操作。
信号量可以有两个操作:等待(wait)和释放(signal)。
三、信号量的创建和初始化在ucos中,信号量的创建和初始化是通过调用相应的API函数实现的。
首先需要定义一个信号量的变量,然后通过调用API函数对其进行初始化。
例如,可以使用以下代码创建一个信号量并初始化为1:SEM_HANDLE sem;sem = OSSemCreate(1);在上述代码中,SEM_HANDLE是信号量的句柄类型,OSSemCreate()是ucos提供的一个用于创建和初始化信号量的函数。
四、信号量的等待操作信号量的等待操作是任务在使用共享资源之前进行的操作。
如果资源已被占用,则任务需要等待,直到资源可用。
在ucos中,可以通过调用OSSemPend()函数来完成等待操作。
以下是一个示例代码,展示了任务如何进行信号量等待操作:void Task1(void *arg){while(1){// 等待信号量OSSemPend(sem, 0, &err);// 使用共享资源// 释放信号量OSSemPost(sem);}}在上述代码中,任务会在OSSemPend()函数处等待信号量。
参数sem表示待等待的信号量句柄,0表示最大等待时间,&err用于记录等待的结果。
五、信号量的释放操作信号量的释放操作是任务在使用完共享资源后进行的操作。
通过调用OSSemPost()函数来释放信号量,使其他任务可以继续访问该资源。
以下是一个示例代码,展示了任务如何进行信号量释放操作:void Task2(void *arg){while(1){// 使用共享资源// 释放信号量OSSemPost(sem);}}在上述代码中,任务会在OSSemPost()函数处释放信号量,以便其他任务可以继续访问该资源。
uCOS-II任务间通讯和同步实验15页
二 实验内容
实验内容
使用信号量实现任务间同步 使用邮箱实现任务之间的通讯
4
三 预备知识
预备知识
了解操作系统任务调度的机制 了解操作系统任务间通讯的机制 学习uC/OS-II操作系统下多任务应用程序的编写方法
5
四 实验设备
实验设备
JX44B0教学实验箱 ADT1000仿真器和ADT IDE集成开发环境 串口连接线
JX44B0实验系统教案 uC/OS-II任务间通讯和同步实验
武汉创维特信息技术有限公司
11.01.2020
提纲
1
实验目的
2 实验内容
3 预备知识
4 实验设备
5 基础知识 6 实验过程 7 实验报告要求
2
一 实验目的
实验目的
掌握uC/OS-II操作系统下使用信号量解决任务之间的同步 问题
掌握uC/OS-II操作系统下任务间通讯的-II中使用消息队列实现任务之间的通讯
消息队列是uC/OS-II中另一种通讯机制,它可以使一个任 务或者中断服务子程序向另一个任务发送以指针方式定义 的变量。因具体的应用有所不同,每个指针指向的数据结 构变量也有所不同。
uC/OS-II提供了7个对消息队列进行操作的函数:创建消 息队列函数OSQCreate(),等待消息队列函数OSQPend(), 先进先出(FIFO)发送消息函数OSQPost(),后进先出(LIFO) 发送消息函数OSQPostFront(),无等待获取消息函数 OSQAccept(),清空消息队列函数OSQFlush()和查询消息 队列函数OSQQuery()。
12
六 实验过程
实验过程
13
六 实验报告要求
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信号量用于简单的按键扫描
uC/OS信号量用于简单的按键扫描首先,当然要给按键扫描创建一个任务:OSTaskCreate(TaskKeyScan, (void * )0,(OS_STK*)&TASK_KEY_STK[KEY_STK_SIZE-1], 23);其次,创建一个信号量,赋值为0表示一个或者多个事件的发生,在这里表示按键按下这个事件:SemEvent = OSSemCreate(0);然后,就是按键任务的代码,如下:void TaskKeyScan(void * pdata){INT8U KeyAState;/*读取按键值*/INT8U key_press = 0;pdata = pdata;for(;;){OSTimeDlyHMSM(0,0,0,20);/*每隔20ms扫描一次按键*/KeyAState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);/*按键按下返回1*/if (KeyAState == 1){OSTimeDlyHMSM(0,0,0,20);/*20ms去抖动*/KeyAState = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);if (KeyAState == 1){key_press = 1;/*按键确认标识置位*/}}if (KeyAState == 0 && key_release == 1)/*本次按键有效*/{OSSemPost(SemEvent);/*发送信号量*/key_press = 0;/*清除按键确认标识*/printf( "Post\n" );}}}最后,在另外的任务中响应按键,执行按键操作(使LED 灯翻转):void TaskLed(void * pdata){pdata = pdata;for(;;){OSSemPend(SemEvent,10,&err);/*挂起任务,等待信号量到来。
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对于信号量,互斥信号量,事件标志组的个人理解ucos看了也有一周多了,索性源码都能开得懂,并且能去理解。
昨天一开始看事件标志组的时候确实不知道怎么回事,后来百度一下,明白了事件标志组的作用以后,再去看书上的讲解和原码就清晰多了,很容易就明白了他的基本运行机理。
这也给了我一点启示,学一个东西,看一个东西之前,你最少要知道他干嘛用的,如果连干嘛用的都知道书看的再熟也是枉然。
ucos中提供了好几个用于同步事件以及共享资源访问的机制,目前我看明白的有信号量,互斥信号量,事件标志组。
下面谈谈自己对他们的理解:1.互斥信号量:互斥互斥,意思就是我用了你就不能用,你用了我就不能用。
永远都只有一个人独占这个东西~!举个例子:比如说打印机。
我任务1现在让他打印《静夜思》,那么在我还没打印完之前,别的任务就不能命令打印机去打印别的东西。
否则如果任务2让他打印《春晓》,那最后打印出来的会是什么~????反正肯定不是任务1想要的,肯定也不是任务2想要的。
上面讲的比较通俗。
打印机就是共享资源,谁都可以访问他~!但是同一时间,肯定要保证只有1个任务再操作打印机。
那样才能得到大家想要的结果。
也就是要独占共享资源的访问权~!ucos2中通过互斥信号量来解决这个问题。
简单说就是任务1开始访问打印机的时候,先去查询这个互斥信号量是否有效,有效,说明没人在访问打印机,这时任务1就把这个互斥信号量置无效,然后开始操作打印机。
这样,每个任务再操作打印机前都要去查询这个互斥信号量时候有效。
无效就等,等到有效才可以访问,或者等到不耐烦了(术语叫等待超时)就不等了~!任务一直到用完了打印机后才把信号量置有效,这时其他任务才有可能去访问,操作打印机。
这里又有一个问题:再任务1操作打印机器件,可能有多个任务申请打印机的所有权。
那么再任务1结束后,我应该给谁用呢~~??也许我们马上就反应过来了~废话~!!当然是排队了~~谁先到的谁用啊~~~。
ucosii互斥信号量的用法
ucosii互斥信号量的用法(实用版)目录1.互斥信号量的概念和作用2.uCOS II 中的信号量和互斥信号量3.互斥信号量在 uCOS II 中的应用实例4.使用互斥信号量的注意事项正文一、互斥信号量的概念和作用互斥信号量是一种用于实现多任务之间同步和互斥的信号量,主要应用于解决多任务对共享资源访问时的线程冲突问题。
互斥信号量可以保证在某一时刻,只有一个任务能够访问共享资源,其他任务需要等待信号量变为可用状态后才能访问。
二、uCOS II 中的信号量和互斥信号量在 uCOS II 操作系统中,信号量是一种重要的同步原语,用于实现任务之间的同步和通信。
信号量分为计数型信号量和互斥型信号量两种。
计数型信号量可以实现任务之间的有序执行,它是一个整数值,可以通过 P 操作(即等待信号量)和 V 操作(即发送信号量)来实现任务的同步。
当计数型信号量的值为 0 时,表示任务需要等待其他任务释放资源;当信号量的值大于 0 时,表示任务可以继续执行。
互斥型信号量主要用于解决多任务对共享资源的互斥访问问题。
互斥型信号量只有一个值,通过 P 操作(即等待信号量)和 V 操作(即发送信号量)来实现任务的同步。
与计数型信号量不同,互斥型信号量在任何时候都只能被一个任务访问,其他任务需要等待信号量变为可用状态后才能访问。
三、互斥信号量在 uCOS II 中的应用实例在 uCOS II 中,互斥信号量通常用于以下场景:1.保护共享资源:当多个任务需要访问共享资源时,可以通过互斥信号量来保证同一时刻只有一个任务能够访问资源。
2.实现任务之间的互斥:在多任务系统中,有些任务不能同时执行,可以通过互斥信号量来实现任务之间的互斥。
3.实现任务之间的有序执行:在特定场景下,需要保证多个任务按照一定的顺序执行,可以通过互斥信号量来实现任务之间的有序执行。
四、使用互斥信号量的注意事项在使用互斥信号量时,需要注意以下几点:1.互斥信号量应在任务开始执行前创建,并在任务结束时释放,避免资源泄漏。
ucos信号量用法
ucos信号量用法在很多嵌入式系统中,ucos操作系统被广泛应用。
在ucos中,信号量是一种常用的同步机制,用于控制对共享资源的访问。
本文将介绍ucos信号量的用法、应用场景以及注意事项,帮助读者更好地理解和使用信号量。
1.ucos信号量简介ucos信号量是一种计数信号量,它用于在多个任务之间实现互斥访问共享资源。
信号量的值表示可用资源的数量。
当一个任务需要访问共享资源时,信号量的值会减1;当任务释放资源后,信号量的值会加1。
当信号量的值为0时,表示没有可用资源,此时其他任务需要等待。
2.ucos信号量使用方法在ucos中,信号量的使用方法如下:(1)初始化信号量:在使用信号量之前,需要对其进行初始化。
可以使用OS_SemCreate函数创建一个信号量,并设置初始值。
(2)申请信号量:当任务需要访问共享资源时,使用OS_SemWait函数申请信号量。
如果信号量值为0,任务将进入等待状态,直到其他任务释放资源。
(3)释放信号量:当任务完成资源访问后,使用OS_SemSignal函数释放信号量。
这样可以通知其他任务有可用资源可供使用。
3.ucos信号量应用场景信号量主要用于以下场景:(1)多任务互斥访问共享资源:当多个任务需要访问同一共享资源时,可以使用信号量实现互斥访问,避免数据冲突和程序崩溃。
(2)设备驱动程序:在设备驱动程序中,可以使用信号量控制设备的访问权限,确保设备在多个任务间安全地共享。
(3)生产者消费者问题:在生产者消费者问题中,信号量可以用于实现生产者和消费者之间的同步,确保生产的商品不被消费过多或过少。
4.ucos信号量注意事项(1)在使用信号量时,需要注意资源的分配和释放要成对出现,避免悬空信号量。
(2)当信号量用于多任务互斥访问时,要注意任务的优先级设置,避免高优先级任务长时间阻塞低优先级任务。
(3)避免在一个任务中多次申请和释放同一个信号量,导致系统资源浪费。
总之,ucos信号量在嵌入式系统中发挥着重要作用。
UCOSIII信号量,互斥信号量
UCOSIII信号量,互斥信号量UCOSIII信号量:资源共享角度阐述信号量:二值信号量(共享资源)计数信号量(用于资源可以被几个任务所用,例如缓存池)互斥信号量(用于解决优先级反转)任务内带信号量(只能用于任务同步,一种计数信号量)1:二值信号量,计数信号量//定义信号量OS_SEM MY_SEM;//创建信号量OSSemCreate ((OS_SEM*)&MY_SEM,(CPU_CHAR* )"MY_SEM",(OS_SEM_CTR)1,(OS_ERR* )&err);//OS_SEM_CTR:此处为1表示二值信号量,用于共享资源计数型信号量,则为计数值此处为0表示计数信号量,用于任务同步//请求信号量OS_SEM_CTR OSSemPend (OS_SEM *p_sem,OS_TICK timeout,OS_OPT opt,CPU_TS *p_ts,OS_ERR *p_err)//发送(释放)信号量OS_SEM_CTR OSSemPost (OS_SEM *p_sem,OS_OPT opt,OS_ERR *p_err)//对于二值信号量:OSSemPend(),OS_SEM_CTR减一,OS_SEM_CTR变为0,表示该信号量被占有OSSemPost (),OS_SEM_CTR加一,OS_SEM_CTR变为1,表示该信号量可用//对于计数信号量:每执行OSSemPend(),OS_SEM_CTR 减一,OS_SEM_CTR减到0,任务阻塞每执行 OSSemPost (),OS_SEM_CTR加一2:互斥信号量(二值信号量)//定义一个互斥信号量OS_MUTEX TEST_MUTEX;//创建一个互斥信号量void OSMutexCreate (OS_MUTEX *p_mutex,CPU_CHAR *p_name,OS_ERR *p_err)void OSMutexPend (OS_MUTEX *p_mutex,OS_TICK timeout,OS_OPT opt,CPU_TS *p_ts,OS_ERR *p_err)void OSMutexPost (OS_MUTEX *p_mutex,OS_OPT opt,OS_ERR *p_err)互斥信号量用于结局二值信号量优先级反转的问题。
c语言信号量使用示例
c语言信号量使用示例C语言信号量使用示例引言:在计算机编程领域中,多任务处理是一项非常重要的技术。
多任务处理可以让不同的任务在同一时间进行,并可以共享计算机资源。
然而,多任务处理中存在一个可能的问题,即竞态条件(Race Condition)。
竞态条件指的是多个进程或线程在同时访问共享资源时发生的冲突。
为了解决这一问题,信号量(Semaphore)应运而生。
信号量是一种用于进程间同步和互斥的工具。
本文将使用C语言的信号量来演示信号量的用法。
什么是信号量?信号量是一种特殊的变量,用于在多进程或多线程之间共享信息,并控制对共享资源的访问。
信号量可以被用来表示一个资源的数量。
当一个进程或线程需要使用该资源时,它需要检查信号量的值。
如果信号量的值大于0,表示资源可用,并会减少信号量的值,同时允许访问资源。
当信号量的值等于0时,表示资源已被占用,进程或线程需要等待直到资源可用。
使用信号量的步骤:下面是使用信号量的一般步骤。
1. 引入必要的头文件:在使用信号量之前,需要包含相应的头文件。
在C语言中,使用信号量需要引入`<semaphore.h>`头文件。
2. 创建信号量:使用`sem_t`类型的变量来表示一个信号量。
可以使用`sem_init()`函数来创建一个新的信号量,该函数接受三个参数,第一个参数是指向信号量变量的指针,第二个参数指定信号量的作用范围(在进程间共享还是线程间共享),第三个参数是信号量的初始值。
3. 获取信号量:在进程或线程需要使用共享资源之前,需要通过调用`sem_wait()`函数来获取信号量。
该函数会使信号量的值减1,如果信号量的值小于0,则会阻塞进程或线程直到资源可用。
4. 访问共享资源:一旦获得了信号量,进程或线程就可以访问共享资源。
5. 释放信号量:在进程或线程访问完共享资源之后,应调用`sem_post()`函数来释放信号量。
该函数会使信号量的值加1,并递增等待此信号量的进程或线程。
基于STM32串口空闲中断与DMA,配合ucos信号量接收未知大小数据
//去除第一个字符发送不了的情况
USART_ClearFlag(USART2,USART_FLAG_TC);
//使能空闲总线中断
USART_ITConfig(USART2,USART_IT_IDLE,ENABLE);
{
//关闭DMA通道,防止数据被破坏
DMA_Cmd(DMA1_Channel6,DISABLE);
//这两条指令用于清除空闲中断标志
USART2->SR;
USART2->DR;
//获取接收到的数据量
Recv_Size = DMA_GetCurrDataCounter(DMA1_Channel6);
/*************************************
使用uCOS的信号量处理串口DMA接收数据
*************************************/
#define BUFFER_SIZE (512)
//接收到数据信号量
OS_EVENT *Recv_Sem;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel6,&DMA_InitStructure);
//串口初始化
USART_DeInit(USART2);
USART_ART_BaudRate = 115200;
Deal_State = 1;
//开始处理数据
}
//清空接收到的数据
memset(Deal_Buffer,0,Recv_Size);
UCOS-II-信号量的理解
(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中的互斥信号量
详解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开始执行。
os的基本知识,信号量,临界资源
os的基本知识,信号量,临界资源1、信号量与互斥锁这两个东西是相似的,不同的是信号量主要做同步,⽽互斥锁做互斥访问;那么其值也就不同,信号量有很多可取的值,⽽互斥锁则是⼆值;操作也不同,信号量在做同步的时候,⼀个线程post,另⼀个pend。
⽽互斥锁则是在⼀个线程中加锁和解锁。
以上是不同之处,下边是结合ucos来讲。
信号量和互斥型信号量(ucos中对互斥锁的称呼)的数据类型ECB(时间控制块)是⼀样的。
其操作也⼀样。
在pend和post时,都可能会发⽣任务切换(没有获得信号量则该线程等待、发出信号量后⾼优先级任务解除挂起)。
这也就决定了,在中断例程中,不应使⽤pend函数,⽽应使⽤accpet,这个accept是不会等待信号量的,也就不存在任务切换的问题。
在中断中可以使⽤post函数。
互斥访问的处理不是必须要⽤信号量(互斥锁),因为这些功能的调⽤需要消耗时间,关中断也可以解决,但是会造成中断响应的延迟,看情况吧。
2、死锁Deadlock,⼜叫做抱死(deadly embrace)。
指两个线程⽆限制得等待对⽅控制的资源。
应对这种问题可以设置等待超时。
还可以:得到全部资源,再做下⼀步⼯作;⽤同样的顺序申请多个资源;释放资源时,使⽤相反的顺序。
3、临界资源临界资源(critical resource)⼜称为共享资源,指多个线程共享的资源(硬件、变量等)。
通常要保证线程互斥地访问临界资源。
访问临界资源的那段代码称为临界代码,保证进⼊临界代码段的互斥,也就实现了资源的互斥访问。
信号量(互斥锁)可以实现,ucos使⽤宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()通过关中断和开中断的⽅法实现了进⼊和离开临界区。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OSStatInit();
OSTaskCreate(YouTask,
(void *)0,
&YouTaskStk[TASK_STK_SIZE-1],
2);
for(;;)
{
if(ac_key)
{
ac_key=FALSE;//
s="MyTask";
PC_DispStr(5,++y1,
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
INT8Uerr;
pdata = pdata;
OS_ENTER_CRITICAL();
PC_VectSet(0x08,OSTickISR);
PC_SetTickRate(OS_TICKS_PERI中的信号量的使用,实现共享资源的使用。
二:实验内容:
完成课本5-2的实验,观察结果,了解互斥信号量的使用。
uCOSII使用信号量、邮箱和消息队列这些中间环节来实现任务之间的通信。
信号量是一类事件。使用信号量的最初目的是为了给共享资源设立一个标志,该标志表示该共享资源被占用情况。
s,
DISP_BGND_BLACK+DISP_FGND_WHITE);
OSTimeSet(0);
while(OSTime<500)
{
PC_DispStr(55,y2,
s,
DISP_BGND_BLACK+DISP_FGND_WHITE);
}
ac_key=TRUE;
}
OSTimeDly(10);
}
}
实验分析:程序在运行时,首先运行任务MyTask,输出字符串:MyTask。然后MyTask等待20个节拍,运行YouTask,输出字符串:YouTask。MyTask等待时间到了,但是由于信号量无效,所以尽管优先级高,但是也是继续运行YouTask,输出字符串:YouTask。直到信号量有效时,运行MyTask。如此循环执行,直到按键ESC,退出uCOS-II.
char*s;
void MyTask(void *data);
void YouTask(void *data);
/*********************主函数***************************/
void main(void)
{
OSInit();
ac_key=1;
PC_DOSSaveReturn();
四:实验结果:
void YouTask(void * pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
INT8Uerr;
pdata = pdata;
for(;;)
{
if(ac_key)
{
ac_key=FALSE;
s="YouTask";
PC_DispStr(28,++y2,
三:程序代码:
#include "includes.h"
#defineTASK_STK_SIZE512
OS_STKMyTaskStk[TASK_STK_SIZE];
OS_STKYouTaskStk[TASK_STK_SIZE];
INT16Skey;
INT8Uy1=0,y2=0;
BOOLEANac_key;
PC_VectSet(uCOS,OSCtxSw);
OSTaskCreate(MyTask,
(void*)0,
&MyTaskStk[TASK_STK_SIZE-1],
0);
OSStart();
}
/********************任务MyTask************************/
s,
DISP_BGND_BLACK+DISP_FGND_WHITE);
ac_key=TRUE;
}
//如果按下ESC键,则退出uCOS-II
if(PC_GetKey(&key)==TRUE)
{
if(key==0x1B)
{
PC_DOSReturn();
}
}
OSTimeDly(20);
}
}
/***************************************************************************/