实验八 uCOS-II的互斥信号量

合集下载

uC_OS-II实验指导书2015 - 8

uC_OS-II实验指导书2015 - 8
default: printf("时间:%d,任务TTaskMessageSen发消息失败,错误号:%d\n",OSTimeGet(),err);
} OSQQuery(myQ,&myQData); printf("时间:%d,当前队列中消息数量:%d\n",OSTimeGet(),myQData.OSNMsgs); } }
实验 8 µC/OS-II 任务间通信设计
1 实验目的
掌握嵌入式实时操作系统µC/OS-II 中信号量、消息邮箱、消息队列机制的基本原理和使用方法。
2 实验内容
数据类型定义如下: typedef unsigned char BOOLEAN; typedef unsigned charpedef unsigned short INT16U; typedef signed short INT16S; typedef unsigned long INT32U; typedef signed long INT32S; typedef unsigned short OS_STK; 任务控制块的结构定义如下: typedef struct os_tcb {
if (myMBox==(OS_EVENT *)0) /*检查邮箱是否存在*/ {
2
printf("时间:%d,任务TaskMessageRec判定邮箱不存在!\n",OSTimeGet()); OSTaskDel(OS_PRIO_SELF); /*不成功则删除本任务*/ return; }
while(1) {
prcount=(INT32U * )OSMboxPend(myMBox,0,perr); /*请求消息,如果消息不存在就阻塞*/ if (*perr==OS_ERR_NONE) printf("时间:%d,任务TaskMessageRec接收消息为%d\n",OSTimeGet(),*prcount); else printf("时间:%d,任务TaskMessageRec等待异常结束,错误号:%d\n",*perr);

UCOSII操作系统实验教程

UCOSII操作系统实验教程

下次实验的准备工作
• 阅读《嵌入式实时操作系统μC/OS原理与 实践》P67-72任务的挂起和恢复
实验9
任务的挂起和恢复
• 1.编译运行代码,输入选项3继续运行程序 • 2.运行查看结果
• 3.查看代码,说明为什么得到这样的运行 结果 • 4.对任务代码进行修改,得到不同的结果 • 5.改变任务的优先级,查看运行结果,说 明输出的不同之处,说明原因
补充,各个例子的运行结果展示 3
下次实验的准备工作
• 阅读《嵌入式实时操作系统μC/OS原理与 实践》P102-129 • 事件管理的重要数据结构,事件管理程 序,信号量管理
实验10 信号量管理实验
• 1.例子程序说明见《嵌入式实时操作系统 μC/OS原理与实践》 P129,运行结果见 P133图4.9 • 打开原始工程运行代码,输入选项4继续 运行程序 • 2.运行查看结果 • 3.说明使用信号量实现的功能,为什么能 实现这样的功能,都使用了哪些数据结构。
补充,各个例子的运行结果展示 1
准备工作
• 阅读《嵌入式实时操作系统μC/OS原理与 实践》P24-40 2.1任务管理的重要数据结 构,为以后的实验做准备
实验2
调试模式跑第一个任务
• 本实验的目的在于学会使用VC的调试模式 运行和调试操作系统。 • 步骤 • 1.在上次实验的基础上不改动代码,打开工 程 • 2.在usercode.c中的 • printf(“welcome to embeded system\n”);处 设置断点。
• 阅读《嵌入式实时操作系统μC/OS原理与 实践》P41-43任务控制块的初始化,P5154任务的创建
实验3
任务的创建
• 掌握任务创建的过程 • 步骤 • 1. 去掉前面的断点,找到main.c中 OSTaskCreate(FirstTask, 0, &TaskStk[5][TASK_STK_SIZE-1], 5);函数,设置 断点,并按F5调试运行,运行代码的时候输入 1,在运行到断点时,按F11追进函数内部,再按 F10单步运行,与书上51页进行比较。 • 2。画出该函数运行完成后的就绪表和就绪组,任 务控制块空闲链表和任务链表。

ucosii 互斥信号量 创建条件

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。

uC_OS-II实验指导书

uC_OS-II实验指导书

µC_OS-II实验指导书电子科技大学嵌入式软件工程中心北京科银京成技术有限公司目录第一部分实验系统简介及入门 (5)1 实验系统的目的 (5)2 实验系统的构成 (5)3 操作系统简介 (5)3.1 µC/OS-II概述 (5)3.2 µC/OS-II的特点 (6)3.3 µC/OS-II主要源代码文件介绍 (7)4 LambdaTOOL集成开发环境简介 (7)5 µC/OS-II实验内容简介 (8)5.1 任务管理实验 (8)5.2 优先级反转实验 (8)5.3 优先级继承实验 (9)5.4 哲学家就餐实验 (9)5.5 内存管理实验 (9)5.6 时钟中断实验 (9)5.7 消息队列实验 (9)6 预备实验:嵌入式开发环境的建立 (9)6.1 目的 (9)6.2 实验步骤及说明 (10)第二部分µC/OS-II实验 (24)实验1 任务的基本管理 (24)1 实验目的 (24)2 实验原理及程序结构 (24)2.1 实验设计 (24)2.2 操作系统配置 (25)2.3 源程序说明 (27)3 运行及观察应用输出信息 (29)4 本实验中所用到的µC/OS-II相关函数 (31)4.1 OSTaskCreate() (31)4.2 OSTaskSuspend() (31)4.3 OSTaskResume() (32)实验2 优先级反转 (33)1 实验目的 (33)2 原理及程序结构 (33)2.1 实验设计 (33)2.2 操作系统配置 (35)2.3 源程序说明 (36)3 运行及观察应用输出信息 (39)4 本实验中所用到的µC/OS-II相关函数 (39)4.1 OSSemCreate() (39)4.2 OSSemPend() (40)4.3 OSemPost() (40)4.4 OSTimeDly() (41)实验3 优先级继承 (42)1 实验目的 (42)2 原理及程序结构 (42)2.1 实验设计 (42)2.2 操作系统配置 (45)3 运行及观察应用输出信息 (46)4 本实验中所用到的µC/OS-II相关函数 (47)4.1 OSMutexCreate() (47)4.2 OSMutexPend() (47)4.3 OSMutexPost() (48)5 应用调试过程 (49)实验4 信号量:哲学家就餐问题的实现 (51)1 实验目的 (51)2 原理及程序结构 (51)2.1 实验设计 (51)2.2 操作系统配置 (52)3运行及观察应用输出信息 (53)4 本实验中所用到的µC/OS-II相关函数 (55)实验5 µC/OS-II的内存管理 (56)1 实验目的 (56)2 原理及程序结构 (56)2.1实验设计 (56)2.2 操作系统配置 (62)3 本实验中所用到的µC/OS-II相关函数 (63)3.1 OSMemCreate() (63)3.2 OSMemGet() (64)3.3 OSMemPut() (64)3.4 OSMemQuery() (65)实验6 时钟中断 (66)1 实验目的 (66)2 原理及程序结构 (66)2.1 实验设计 (66)2.2 操作系统配置 (68)3 运行及观察应用输出信息 (70)4 本实验中所用到的µC/OS-II相关函数 (71)实验7 消息队列 (72)1 实验目的 (72)2 原理及程序结构 (72)2.1 实验设计 (72)2.2 源程序说明 (72)2.3 操作系统配置 (77)3 运行及观察应用输出信息 (78)4 本实验中所用到的µC/OS-II相关函数 (82)4.1 OSQCreate() (82)4.2 OSQPend() (82)4.3 OSQPostFront() (83)4.4 OSQPost() (83)4.5 OSQFlush () (84)4.6 OSQQuery() (84)4.7 OSQDel() (85)4.8 OSTimeDlyHMSM() (85)第一部分实验系统简介及入门1 实验系统的目的通过此实验系统,读者可以了解嵌入式实时操作系统µC_OS-II的内核机制和运行原理。

uCOS-II信号量集

uCOS-II信号量集

等待任务链表
事件标志组、事件标志节点及任务控 制块之间的关系
给等待任务链表添加节点的函数为OS_FlagBlock( ),这个函数 的原型为: static void OS_FlagBlock ( OS_FLAG_GRP *pgrp, //信号量集指针 OS_FLAG_NODE *pnode, //待添加的等待任务节点指针 OS_FLAGS flags, //指定等待信号的数据 INT8U wait_type, //信号与等待任务之间的逻辑 INT16U timeout //等待时限 ); 这个函数将在请求信号量集函数OSFlagPend ( )中被调用。
任务可以通过调用函数OSFlagPend( )请求一个信号量 集,OSFlagPend( )函数的原型为:
OS_FLAGS OSFlagPend ( OS_FLAG_GRP *pgrp, //所请求的信号量集指针 OS_FLAGS flags, //滤波器 INT8U wait_type, //逻辑运算类型 INT16U timeout, //等待时限 INT8U *err //错误信息 );
发送(置位)事件标志组中的事件标志OSFlagPost()
case OS_FLAG_WAIT_SET_ANY://”或”方式等待 flags_rdy = pgrp->OSFlagFlags & pnode->OSFlagNodeFlags; if (flags_rdy != (OS_FLAGS)0) {//有满足条件的事件标志 if (OS_FlagTaskRdy(pnode, flags_rdy) == TRUE) sched = TRUE; //如果任务就绪,设置调度标志 } break; } pnode = (OS_FLAG_NODE *)pnode->OSFlagNodeNext;//下一个等待 事件标志的节点 } if (sched == TRUE) OS_Sched();//如果设置了调度标志,则实施调度 *err = OS_NO_ERR; return (pgrp->OSFlagFlags); }

UCOS-互斥信号量(学习笔记)

UCOS-互斥信号量(学习笔记)

UCOS-互斥信号量(学习笔记)互斥信号量主要是为了解决信号量出现的优先级反转的情况:任务的运⾏取决于优先级和获得信号量2个条件,并且获得信号量⼜优先于设定的优先级。

剥夺性内核对信号量进⾏独占访问,就有可能出现先获得信号量的低优先级任务在独占信号量过程中被⾼优先级任务剥夺CPU 控制权⽽挂起,不能及时释放信号量,⽽⾼优先级任务⼜需要该信号量从⽽出现优先级反转。

解决的办法:引⼊互斥信号量,在任务获得共享信号量过程中提升置最⾼优先级不被打断(通过将信号量计数器分成⾼8位作为提升优先级,低8位作为占⽤标志0XFF表明未占⽤),从⽽使低优先级任务及时释放共享信号量。

其它与信号量相同。

⼀创建互斥信号量: OS_EVENT *OSMutexCreat(INT8U prio,INT8U &err)//从任务链表中取得⼀个任务控制块赋值类型为OS_Event_TYPE_MUXTEX,然后给任务计数器的⾼8位赋值优先级,第⼋位赋值0XFF表明未被占⽤。

⼆申请互斥信号量:void OSMutexPend(OS_EVENT *P, INT16U timeout,INT8U &err)//访问任务计数器若为0xff则获得运⾏权,否则进⼊等待列表,timeout⽤于指定等待时间。

OSMutexAccept(OS_EVENT *P,INT8U &err)//⽆等待的请求⼀个信号量。

三发送(释放)互斥信号量:INT8U OSMutexPost(OS_EVENT *P)四获得互斥型信号量的当前状态:INT8U OSMutexQuery(OS_EVENT *P,OS_MUTEX_DATA *pdata)//需事先定义⼀个存储互斥型信号量状态的变量。

五删除互斥型信号量:OS_EVENT *OSMutexDel(OS_EVENT *P, INT8U opt,INT8U &err)//opt为删除的选择项:⽴即删除、等待⽆任务等待时再删除。

uCOS-II互斥信号量

uCOS-II互斥信号量

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

本手册描述了&#61549;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-II

第五篇:uCOS-II

第五篇:uCOS-II 信号量及其操作1.信号量使⽤信号量之前⾸先要对信号量有⼀个本质的认识(1)信号量的含义:信号量是⼀类事件,使⽤信号量的最初⽬的是为了给共享资源设⽴⼀个标志,该标志表⽰共享资源的占⽤情况,这样,当⼀个任务在访问共享资源之前,就可以对这个标志进⾏查询,从⽽在了解资源被占⽤的情况之后,再来决定⾃⼰的⾏为。

(2)UCOS-II的信号量⾥⾯有⼀个OSEventCnt,正确的认识这个,是使⽤信号量的关键。

OSSemCreate(0):这种情况下可以⽤任务的同步。

OSSemCreate(1):这种情况类似于互斥信号量,有⼀个名字就是⼆值信号量,可⽤于⼀个资源的使⽤OSSemCreate(>1):这种情况表⽰有>1个资源可以使⽤。

(3)OSEventCnt的初始数据代表可⽤的资源数,1就是⼀个可⽤资源,n就是n可⽤资源。

(4)OSTimeTick 函数⾥⾯有⼀个需要注意的地⽅。

a如果事件中设置了0SxxxPend的延时的话,会进到下⾯函数的这个地⽅。

b如果设置的是⼀直等到的话,将通过OSXXXPost释放。

在延迟的时间⾥⾯没有就绪的话,任务OSTCBStatPend被设置成超时,并清除相应的标志位。

if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;ptcb->OSTCBStatPend = OS_STAT_PEND_TO;}在延迟的时间⾥⾯任务收到信息,任务OSTCBStatPend被设置成OKelse{ptcb->OSTCBStatPend = OS_STAT_PEND_OK;}如果任务没有被挂起的话,任务将加⼊到就绪列表。

if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {OSRdyGrp |= ptcb->OSTCBBitY;OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;}(5)下⾯分两种情况进⾏详细的讨论A. OSSemCreate(0)这种情况下⽤于信号的同步OSSemPen(xx, 0, xx)设置为0的话,任务将被⼀直挂起直到收到OSSemPost信号。

uCOS-II中关于信号量的使用总结

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个事件均发生后,这个任务才能运行。

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互斥信号量的用法(实用版)目录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.互斥信号量应在任务开始执行前创建,并在任务结束时释放,避免资源泄漏。

ucosii互斥信号量的用法

ucosii互斥信号量的用法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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则负责释放互斥锁,以便其他任务可以访问共享资源。

S.D.Lu的uCOSII入门学习笔记互斥信号量

S.D.Lu的uCOSII入门学习笔记互斥信号量

S.D.Lu的uC/OS II 入门学习笔记(6):互斥信号量在该系列笔记前面篇章中,我刻意跳过了互斥信号量的介绍,是有原因的。

该系列笔记面向的是初学者,信号量通信是学习者初次接触任务同步的相关内容,后面还有消息邮箱和消息队列。

因为互斥信号量的内容还会涉及到优先级反转的内容,对初学者来说相对复杂。

所以,先学习完消息邮箱和消息队列的基本应用之后,再回过头学习互斥信号量的内容会比较好。

本篇实验将在第(3)篇的基础上进行,仍然是运行两个任务,每个任务控制一个LED的亮灭。

问题的提出在可剥夺型内核中,当任务以独占式使用共享资源时,会出现低优先级任务先于高优先级任务被运行的现象,这就是任务优先级反转。

一般来说,在实时系统中不允许出现这种现象,因为它破坏了任务执行的预期顺序,可能要导致严重后果。

关于这个现象的详细描述,请仔细阅读任哲《嵌入式实时操作系统μCOS-II原理及应用》(第2版)第五章5.4.1节。

其中例子基本描述是这样的,有A、B、C三个任务,它们的优先级别A>B>C,而且A和C共享一个独占式资源S。

当C占用该资源时,如果此时A 申请访问资源S,那么A由于等待资源S而得不到运行。

这样,任务B就可能超越任务A 优先得到运行。

任务C占用资源的时间越长,A就会被阻塞越久。

解决问题的办法之一是,使获得信号量任务的优先级别在使用共享资源期间暂时提升到所有任务最高优先级的高一个级别上,以使该任务不被其他任务所打断,从而能尽快地使用完共享资源并释放信号量,然后再回复该任务原来的优先级别。

引入互斥型信号量,就是为了解决上述问题的。

在上一篇例3-2的基础上进行修改。

例6-1将app.c中的内容改为如下:编译下载,运行程序,结果和例3-2相同,LED2闪烁2次后LED1闪烁1次,如此循环,而且两路LED不会同时被点亮(刚开始上电的时候有可能同时被点亮,取决于初始化函数)。

需要注意的是,本例中用到了互斥信号量及相关函数等,所以在os_cfg.h配置文件中必须将OS_MUTEX_EN置1,如下图:几个相关的函数原型如下:本例非常简单,而且并没有体现互斥信号量的作用。

实验八 uCOS-II的互斥信号量

实验八 uCOS-II的互斥信号量

实验八uCOS的互斥信号量一:实验目的:1.理解互斥型信号量。

2.学会使用互斥型信号量实现对共享资源的独占式处理。

3.解决任务在使用独占式资源出现的优先级反转问题。

二:实验内容:完成教材5-7实验,使用互斥型信号量实现对共享资源的独占式处理。

实验中要求要创建互斥型信号量,请求互斥型信号量,发送互斥型信号量,删除互斥型信号量。

三:程序代码:#include "includes.h"#define TASK_STK_SIZE 512OS_STK StartTaskStk[TASK_STK_SIZE];OS_STK MyTaskStk[TASK_STK_SIZE];OS_STK YouTaskStk[TASK_STK_SIZE];OS_STK HerTaskStk[TASK_STK_SIZE];INT16S key;char *s1="MyTask running--yangkun";char *s2="YouTask running--yangkun";char *s3="HerTask running--yangkun";char *s4="MyTask pend_Semp";char *s5="HerTask pend_Semp";INT8U err;INT8U y=0;INT32U Times=0;OS_EVENT *Semp;void StartTask(void *pdata);void MyTask(void *pdata);void YouTask(void *pdata);void HerTask(void *pdata);void main (void){OSInit();PC_DOSSaveReturn();PC_VectSet(uCOS, OSCtxSw);Semp=OSMutexCreate(1,&err);OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE - 1], 0);OSStart();}void StartTask (void *pdata){#if OS_CRITICAL_METHOD == 3OS_CPU_SR cpu_sr;#endifpdata = pdata;OS_ENTER_CRITICAL();PC_VectSet(0x08, OSTickISR);PC_SetTickRate(OS_TICKS_PER_SEC);OS_EXIT_CRITICAL();OSStatInit();OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE - 1], 3);OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE - 1], 4);OSTaskCreate(HerTask,(void*)0,&HerTaskStk[TASK_STK_SIZE - 1], 5);for (;;){if (PC_GetKey(&key) == TRUE) {if (key == 0x1B) {PC_DOSReturn();}}OSTimeDlyHMSM(0, 0, 3, 0);}}void MyTask(void *pdata){#if OS_CRITICAL_METHOD==3OS_CPU_SR cpu_sr;#endifpdata=pdata;for(;;){OSTimeDlyHMSM(0,0,0,200);{PC_DispStr(10,++y,s4,DISP_BGND_BLACK+DISP_FGND_WHITE);OSMutexPend(Semp,0,&err);PC_DispStr(10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);}OSTimeDlyHMSM(0,0,0,200);}}void YouTask(void *pdata){#if OS_CRITICAL_METHOD==3OS_CPU_SR cpu_sr;#endifpdata=pdata;for(;;){PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);OSTimeDlyHMSM(0,0,0,300);}}void HerTask(void *pdata){#if OS_CRITICAL_METHOD==3OS_CPU_SR cpu_sr;#endifpdata=pdata;for(;;){PC_DispStr(10,++y,s5,DISP_BGND_BLACK+DISP_FGND_WHITE);OSMutexPend(Semp,0,&err);PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_WHITE);for(Times;Times<20000000;Times++){OS_Sched();}PC_DispStr(20,++y,"***************",DISP_BGND_BLACK+DISP_FGND_WHITE);OSMutexPost(Semp);OSTimeDlyHMSM(0,0,1,0);}}四:实验结果:。

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个任务。

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

uCOS-II操作系统简介及实验

uCOS-II操作系统简介及实验
进入临界段: 进入临界段:OS_ENTER_CRITICAL() 退出临界段:OS_EXIT_CRITICAL()。 退出临界段: 。

这两个宏的定义取决于所用的微处理器, 这两个宏的定义取决于所用的微处理器,每种微 处理器都有自己的OS_CPU.H文件。 文件。 处理器都有自己的 文件
uC/OS-II操作系统 uC/OS-II操作系统
uC/OS-II操作系统 uC/OS-II操作系统
1.2 uC/OS-II特点 特点
• 1、uC/OS-II内核具有很强的可移植性。 内核具有很强的可移植性。 、 内核具有很强的可移植性 • 2、具有可抢占的实时多任务调度功能。 、具有可抢占的实时多任务调度功能。 • 3、提供了许多系统服务,如信号量、消 、提供了许多系统服务,如信号量、 •
任务状态
• • • • • •
休眠态 - OSTaskCreate()或OSTaskCreateExt() 或 就绪态 等待态,就绪态 就绪态,运行态 等待态 就绪态 运行态 - OSTaskDel() - 休眠态 就绪态 - OSStart() - 运行态 运行态 - OSTimeDly()或OSTimeDlyHMSM() , 或 OSSemPend(),OSMboxPend(),或OSQPend() , , 等待态 等待态 - OSTimeTick() -就绪态 就绪态 空闲任务 - OSTaskIdle()
uC/OS-II操作系统 uC/OS-II操作系统
任务调度
• μC/OS-Ⅱ总是运行进入就绪态任务中优 μC/OS先级最高的那一个。 先级最高的那一个。确定哪个任务优先 级最高, 级最高,下面该哪个任务运行了的工作 是由调度器(Scheduler)完成的。 是由调度器(Scheduler)完成的。

UCOS—II常用资料整理

UCOS—II常用资料整理

UC/OS—II的常用资料整理作者:~风中的叶~ QQ:654705188一、变量类型1.OS_STK:typedef unsigned int堆栈的类型定义1.1OS_STK_DATA:堆栈数据的类型定义2.OS_CPU_SR:typedef unsigned int保存CPU状态的变量类型3. OS_EVENT:消息事件的类型定义,包括信号量、互斥型信号量、消息邮箱、消息队列typedef struct {INT8U OSEventType;INT8U OSEventGrp;INT16U OSEventCnt;void *OSEventPtr;INT8U OSEventTbl[OS_EVENT_TBL_SIZE];} OS_EVENT;3.1 OS_SEM_DATA:消息信号量数据的类型定义3.2 OS_MUTEX_DATA:消息互斥型信号量数据的类型定义3.3 OS_MBOX_DATA:消息邮箱数据的类型定义4.OS_FLAG_GRP:标志组的类型定义typedef struct {INT8U OSFlagType;V oid *OSFlagWaitList;OS_FLAGS OSFlagFlags;} OS_FLAG_GRP;4.1OS_FLAGS:typedef INT16U事件标志(位)类型定义4.2 OS_FLAG_NODE:事件标志节点类型定义5. OS_Q:消息队列的类型定义typedef struct os_q {struct os_q *OSQPtr;void **OSQStart;void **OSQEnd;void **OSQIn;void **OSQOut;INT16U OSQSize;INT16U OSQEntries;} OS_Q;5.1 OS_Q_DATA:消息队列数据的类型定义6. OS_MEM:内存管理的类型定义typedef struct {void *OSMemAddr;void *OSMemFreeList;INT32U OSMemBlkSize;INT32U OSMemNBlks;INT32U OSMemNFree;} OS_MEM;6.1 OS_MEM_DATA:内存管理数据的类型定义7.OS_TCB:任务控制块的类型定义二、常用变量1.OSCtxSwCtr:OS_EXT INT32U任务切换次数的记录变量2.OSCPUUsage:OS_EXT INT8S CPU的使用率3. OSIdleCtr:OS_EXT INT32空闲任务计数器4. OSIdleCtrRun:空闲任务的计数器每秒的计数值5.OSIntNesting:OS_EXT INT8S中断嵌套的层数(0~255)6.OSLockNesting:OS_EXT INT8S调用OSSchedLock嵌套层数7. OSPrioCur:OS_EXT INT8S正在运行的任务的优先级8. OSTaskCtr:OS_EXT INT8S已经建立了的任务数全局变量:三、常用函数一、OS_CORE.C(1)void OSInit (void) //系统初始化(2)void OSIntEnter (void) //发生了一次中断(中断嵌套的逐层进入)(3)void OSIntExit (void) //退出了一次中断(中断嵌套的逐层退出)(4)void OSSchedLock (void) // 给调度器上锁(5)void OSSchedUnlock (void) // 给调度器解锁,成对使用(6)void OSStart (void) // 启动多任务过程,在启动之前必须调用OSInit(),并已建立一个任务。

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得以继续运行。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验八uCOS的互斥信号量
一:实验目的:
1.理解互斥型信号量。

2.学会使用互斥型信号量实现对共享资源的独占式处理。

3.解决任务在使用独占式资源出现的优先级反转问题。

二:实验内容:
完成教材5-7实验,使用互斥型信号量实现对共享资源的独占式处理。

实验中要求要创建互斥型信号量,请求互斥型信号量,发送互斥型信号量,删除互斥型信号量。

三:程序代码:
#include "includes.h"
#define TASK_STK_SIZE 512
OS_STK StartTaskStk[TASK_STK_SIZE];
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
OS_STK HerTaskStk[TASK_STK_SIZE];
INT16S key;
char *s1="MyTask running--yangkun";
char *s2="YouTask running--yangkun";
char *s3="HerTask running--yangkun";
char *s4="MyTask pend_Semp";
char *s5="HerTask pend_Semp";
INT8U err;
INT8U y=0;
INT32U Times=0;
OS_EVENT *Semp;
void StartTask(void *pdata);
void MyTask(void *pdata);
void YouTask(void *pdata);
void HerTask(void *pdata);
void main (void)
{
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
Semp=OSMutexCreate(1,&err);
OSTaskCreate(StartTask,(void*)0,&StartTaskStk[TASK_STK_SIZE - 1], 0);
OSStart();
}
void StartTask (void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
OS_ENTER_CRITICAL();
PC_VectSet(0x08, OSTickISR);
PC_SetTickRate(OS_TICKS_PER_SEC);
OS_EXIT_CRITICAL();
OSStatInit();
OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE - 1], 3);
OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE - 1], 4);
OSTaskCreate(HerTask,(void*)0,&HerTaskStk[TASK_STK_SIZE - 1], 5);
for (;;)
{
if (PC_GetKey(&key) == TRUE) {
if (key == 0x1B) {
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0, 0, 3, 0);
}
}
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for(;;)
{
OSTimeDlyHMSM(0,0,0,200);
{
PC_DispStr(10,++y,s4,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSMutexPend(Semp,0,&err);
PC_DispStr(10,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE);
}
OSTimeDlyHMSM(0,0,0,200);
}
}
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for(;;)
{
PC_DispStr(10,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSTimeDlyHMSM(0,0,0,300);
}
}
void HerTask(void *pdata)
{
#if OS_CRITICAL_METHOD==3
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for(;;)
{
PC_DispStr(10,++y,s5,DISP_BGND_BLACK+DISP_FGND_WHITE);
OSMutexPend(Semp,0,&err);
PC_DispStr(10,++y,s3,DISP_BGND_BLACK+DISP_FGND_WHITE);
for(Times;Times<20000000;Times++)
{
OS_Sched();
}
PC_DispStr(20,++y,"***************",DISP_BGND_BLACK+DISP_FGND_WHITE);
OSMutexPost(Semp);
OSTimeDlyHMSM(0,0,1,0);
}
}
四:实验结果:。

相关文档
最新文档