【原创】ucos信号量的操作及原理

信号量的操作及原理

 
1.OSSemCreate创建信号量semaphore
    在使用信号量之前,要先用OSSemCreate创建一个信号量,并通过返回的合法事件结构体指针使用信号量。
  1. OS_EVENT *OSSemCreate(INT16U cnt)
  2. {
  3. #if OS_CRITICAL_METHOD == 3 /* 原理请查看http://blog.csdn.net/liuhui_8989/article/details/8783323 */
  4. OS_CPU_SR cpu_sr;
  5. #endif
  6. OS_EVENT *pevent;
  7. if(OSIntNesting>0){/* 不能在中断内创建信号量 */
  8. return((OS_EVENT *)0);/* 直接返回0 */
  9. }
  10. OS_ENTER_CRITICAL();
  11. pevent =OSEventFreeList;/* 获取空闲的事件控制块 */
  12. if(OSEventFreeList!=(OS_EVENT *)0){/* 将OSEventFreeList指向下一个事件控制块 */
  13. OSEventFreeList=(OS_EVENT *)OSEventFreeList->OSEventPtr;
  14. }
  15. OS_EXIT_CRITICAL();
  16. if(pevent !=(OS_EVENT *)0){/* Get an event control block */
  17. pevent->OSEventType= OS_EVENT_TYPE_SEM;
  18. pevent->OSEventCnt= cnt;/* 设置计数器的初值 */
  19. pevent->OSEventPtr=(void*)0;/* Unlink from ECB free list */
  20. OS_EventWaitListInit(pevent);/* 初始化事件控制块中任务等待表为0 */
  21. }
  22. return(pevent);
  23. }
    简而言之,如果没有了空闲的事件控制块或者是在中断内创建信号里,则返回无效的事件控制块0;否则返回类型为信号量,任务等待表OSEventGrp和OSEventTbl[]为0,且已设置了计数器初值的事件控制块指针。这样便成功地创建了一个信号量。这里要注意,使用OSSemCreate函数返回的指针前,要检验是否为有效的指针。
    cnt的值至少为0。
    创建了信号量之后,便可以对信号量进行如下操作了,申请、释放、删除、查询信号量。
2. 信号量的申请和释放
  1. 申请:voidOSSemPend(OS_EVENT *pevent, INT16U timeout, INT8U *err)
  2. 释放:INT8U OSSemPost(OS_EVENT *pevent)
    OSSemPend函数有三个参数,
    第一个是一个指向事件控制块的指针,该值为OSSemCreate返回值。
    第二个是一个等待时间值(至少为0),如果信号量目前被占用,则无法立即申请到信号量,调用该函数的任务将被挂起,如果等待时间值为0,则一直被挂起直到信号量被释放为止(OSSemPost能够在释放信号量的同时,恢复等待信号量的任务),如果等待时间值大于0,则在超时时间过后,由OSTineTick恢复为就绪状态的任务。
    第三个为一个指向错误代码的指针,该值作为函数返回值使用。
    OS_NO_ERR                       函数调用成功,获得了信号量。
    OS_TIMEOUT                     在规定的时间内没有申请到信号量
    OS_ERR_EVENT_TYPE       事件类型错误,不是信号量
    OS_ERR_PEND_ISR            不能在中断内申请信号量
    OS_ERR_PEVENT_NULL    pevent指针无效
 
下面讲解一下函数内部原理:
无标题.png
    如果信号量的计数器值大于0,则将其减1,表示又有一个任务占用,并直接返回。
    如果信号量的计数器值为0,表示信号量已被其他任务占用,此时任务控制块中的状态标志是等待信号状态以及就绪的,因为使用的是按位或操作,保留了原有的就绪状态标志。
    之后调用了OS_EventTaskWait(pevent); 此时作了3件事:
    (1)OSTCBCur->OSTCBEventPtr = pevent;将事件控制块指针保存于任务控制块中
    (2)去除任务在任务就绪表的就绪状态,注意没有包括任务控制块中的状态标志
    (3)设置事件控制块中的任务等待表
    至此任务被挂起!通过OS_Sched运行其他任务去了。
    接下来的结果取决于,信号量是否在规定的等待时间内被释放。
    在当前任务被挂起,而运行其他任务的同时,每个时钟节拍都会运行OSTimeTick中断函数,此函数会遍历所有任务,如果任务控制块中的状态标志为就绪的,且Dly等待值不为0,则将Dly减1,如果减1后刚好为0,则在任务就绪表中恢复该任务的就绪状态!
    如果该就绪状态的任务恢复运行,此时任务控制块的状态标志仍为OS_STAT_SEM,运行OS_EventTO,做的事刚好和OS_EventTaskWait相反。
    (1)OSTCBCur->OSTCBEventPtr = 0;
    (2)设置任务控制块中的状态标志为就绪状态(去除OS_STAT_SEM状态
    (3)去除事件控制块中的任务等待表
    此时返回OS_TIMEOUT。
    但是如果在等待时间未过去,其他任务释放了信号量,OSSemPost能够在释放信号量的同时,恢复等待信号量的任务。等待信号量的任务恢复运行,此时任务控制块的状态标志不包含OS_STAT_SEM了,所以函数直接跳过第二个if语句,返回OS_NO_ERR。
释放信号量过程:
    函数OSSemPost在对信号量的计数器操作之前,首先检查任务等待表中是否还有其他等待该信号的任务,如果没有,就把计数器加1,如果有,则调用OS_EventTaskRdy将任务等待表中最高优先级的任务设为就绪状态,并调用OSSched调度任务。
 
3. 应用
3.1申请函数和释放函数在同一任务中成对出现
main:
pevent = OSSemCreate(1);
task1:
OSSemPend(pevent, 0, err);
....
OSSemPost(pevent);
task2:
OSSemPend(pevent, 0, err);
....
OSSemPost(pevent);
当一个任务没有释放信号量,另一个任务在申请信号量时只能挂起直到信号量释放。
3.2 应用程序中有一个函数Fun(),如果想使任务M必须经过Y任务允许才能调用函数一次,可以使用信号量
main:
pevent = OSSemCreate(0);
task1:
OSSemPend(pevent, 0, err);
Fun();
task2:
OSSemPost(pevent);
本文链接:http://www.cnblogs.com/cposture/p/4299055.html

转载于:https://www.cnblogs.com/cposture/p/4299055.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JMeter之JMS接口测试

JMeter中的JMS Point-to Point、JMS Publisher和JMS Subscriber分别用于发送JMS的PTP消息和PUB/SUB消息,可以选择使用JMeter来测试JMS。 MOM(消息中间件)作为消息数据交换的平台,也是影响应用执行效率的潜在环节。在Java程序中&am…

AutoRest - 具有 C# 和 Razor 模板的 Swagger 规范代码生成器。

简介AutoRest工具生成用于访问 RESTful Web 服务的客户端库。AutoRest是使用OpenAPI 规范格式描述 REST API 的规范。AutoRest 是一个提供代码生成框架的工具,用于将 OpenAPI 2.0 和 3.0 规范转换为客户端库,用于这些规范所描述的服务。它是在 OpenAPI I…

java内存四大区,jvm基础-内存区域

1.运行时数据区java虚拟机在执行java程序的过程中会爸它所管理的内存分为若干个不同的数据区域jvm内存主要分为堆、程序计数器、方法区、虚拟机栈喝本地方法栈,直接内存等。java方法的运行和虚拟机栈虚拟机栈是线程运行java方法所需要的数据,指令&#x…

【ArcGIS遇上Python】ArcGIS Python实现批量化矢量和栅格数据重命名

在ArcGIS中,要为矢量数据或栅格数据重命名,需要到ArcCatalog中进行,但是只能一个个重命名。ArcGIS中也提供了矢量、栅格数据的重命名工具:【重命名】,如下图所示: 双击运行该工具,可以看到,更改数据集的名称。这包括各种数据类型,其中包括要素数据集、栅格、表 和 sha…

电脑测速软件_网速慢,怎么办,教你测速,教你解决方案

网速慢、网页慢、视频卡、游戏卡,如何判断自己的宽带速率是否有问题,本期我们来讨论下,如何正确测试网速,信道干扰、2.4G与5G信号、IPTV测速。一、电脑测速受到无线环境影响,无线性能瓶颈等多方面原因,电脑…

Xamarin效果第十六篇之GIS添加Mark

在前面几篇文章中简单玩耍了一下在线和离线加载高德地图图层;今天再次完善一下添加Mark图层和展示详细信息弹窗;来看看最终效果:添加Mark无非就是用了PictureMarkerSymbol:PictureMarkerSymbol picMarkSymbol await GetPictureMarker(); MapPoint mapPoint new MapPoint(foot…

Android规范发展

一、Android 编码规范 1.java 代码中不出现中文。最多凝视中能够出现中文 2.局部变量命名、静态成员变量命名 仅仅能包括字母,单词首字母出第一个外,都为大写,其它字母都为小写 3.常量命名 仅仅能包括字母和_,字母所有大写&#x…

js input 自动换行_矿用自动灭火装置水基型自动灭火装置原理国内分析研讨_搜狐汽车...

山 东潍坊九通消防科技(九通长胜)是国内最早针对矿用车辆发动机舱自动灭火的要求研发设计的超细干粉、水基型自动灭火装置是当下国内解决矿用车辆(地表车辆、井下车辆)灭火的非常好的技术,目前在掘进机、凿岩台车、皮卡、吉普车、轻卡、巨无霸、电传动汽车、露天矿山…

关于WannaCry勒索病毒 你需要知道的8个问题

近日来,WannaCry勒索病毒席卷全球,超过150个国家至少30万名用户中招,造成损失达80亿美元(约合人民币550亿元)。 目前,多名网络安全专家指出,目前病毒事态只是由于多种原因而稍显缓和,但许多网络用户特别是中…

C# ReaderWriterLockSlim类

为了使锁定机制允许锁定多个读取器(而不是一个写入器)访问某个资源,可以使用 ReaderWriterLockSlim 类。这个类提供了一个锁定功能,如果没有写入器锁定资源,就允许多个读取器访问资源,但只能有一个写入器锁定该资源。ReaderWriter…

LOG4NET用法

log 4net组件下载:log4net.dll web.config配置如下&#xff1a; <?xml version"1.0" encoding"utf-8" ?> <configuration><configSections><section name"log4net" type"log4net.Config.Log4NetConfigurationSectio…

怎么计算信息完整度_德阳冻货运镖怎么计算费用

德阳冻货运镖怎么计算费用物流”一词我们并不陌生&#xff0c;它把小到零食玩具、大到家用电器&#xff0c;一一送到我们手中&#xff0c;但传统的物流运输模式只能满足部分物品的运输要求。随着人们的生活品质不断提高、消费不断升级。德阳冻货运镖怎么计算费用息平台的支撑&a…

AI+时代,谈谈产品经理对图像识别技术的阈值控制

产品满足用户的需求有一个阈值&#xff0c;产品值低于阈值用户会觉得了无生趣&#xff0c;即产品一般般&#xff0c;也即产品经理做了功能经理。产品值等于阈值产品功能基本满足了用户的需求&#xff0c;而只有产品经理驾驭了需求&#xff0c;把产品做成作品&#xff0c;产品值…

【亲身经验】如何在 6 个月内成为“微软 MVP”

前言很荣幸&#xff0c;在愚人节这天&#x1f601;&#xff0c;收到了获得“微软 MVP”奖项的通知&#xff1a;由于该奖项评选标准只涉及 2021 年所做的贡献&#xff0c;而我的贡献主要是公众号文章。因此以我从 2021/06 开始运营个人公众号算起&#xff0c;可以说&#xff0c;…

3500个常用汉字表_小学常用560个汉字笔画笔顺表,打印下来,小学六年慢慢练...

温馨提示公众号改版后很多孩子及家长朋友找不到我们了为了方便大家更快地找到我们获取更多学习工具和资料您可以按照下面的方式 星标或置顶我们☟ ☟ ☟小学阶段&#xff0c;字写得好很重要&#xff0c;笔顺写对了也很重要。写对笔顺有利于把字写得美观&#xff0c;考试时碰到笔…

SVN安装和使用总结

SVN简介&#xff1a; 为什么要使用SVN&#xff1f; 程序员在编写程序的过程中&#xff0c;每个程序员都会生成很多不同的版本&#xff0c;这就需要程序员有效的管理代码&#xff0c;在需要的时候可以迅速&#xff0c;准确取出相应的版本。 Subversion是什么&#xff1f; 它是一…

从部署 httpd 入手,理清 k8s 配置中的 containerPort、port、nodePort、targetPort

注&#xff1a;文中各种内网、公网 IP 仅为示例&#xff0c;不保证所有 IP 都可以访问&#xff0c;且你的环境中 IP 可能不同。背景在上一篇文章 自己搭建一个k8s环境 中&#xff0c;我们一顿操作猛如虎&#xff0c;搭建出了由 1 个 master 和 1 个 worker 节点组成的 k8s 集群…

360文件粉碎机_中山三乡资料文件销毁粉碎销毁资料文件公司一览表

中山三乡资料文件销毁粉碎销毁资料文件公司一览表安排搬运工作人员及运输车辆上门收取销毁物品&#xff0c;将需销毁的物品装上运输车辆&#xff0c;并进行拍照、车箱粘贴封条等工作。第五步&#xff1a;客户可安排工作人员&#xff0c;跟我公司销毁运输车辆一同前往我公司销毁…

Sonnedix收购意大利11.2MW光伏电站产品组合

2016年9月5日, 太阳能独立发电商Sonnedix宣布已经在意大利获得Trading Emissions 的11.2MW太阳能光伏电站产品组合&#xff0c;此交易预计将在2016年第四季度关闭。 该产品组合包括三个地面安装光伏电站: 阿布鲁佐的Basciano和Cupello、以及西西里岛的Librandello。 Sonnedix在…