ocos 信号量
信号量分为 :声明信号量、互斥信号量
转:
ucos-ii学习笔记——信号量的原理
ucos-ii学习笔记——信号量的原理及使用
#include "INCLUDES.h"
#define TASK_STK_SIZE 512
char *s1="MyTask";
char *s2="YouTask";
INT8U err; //定义一个错误信息
INT8U y=0;
OS_EVENT *Fun_Semp; //声明信号量 是事件控制块ECB类型的
//注意,前面有一个例子2 定义了互斥信号量,定义如下
//BOOLEAN ac_key; //信号量,互斥信号量 实质上就是一个标志位,是一个全局变量,来标志共享资源的访问情况
//这样,当已经有任务访问共享资源时,其他的任务就不能访问,知道该资源未被访问,其他的任务才可以进行访问
//注意这两个信号量的区别和使用情况
OS_STK StartTaskStk[TASK_STK_SIZE]; //定义任务堆栈区
OS_STK MyTaskStk[TASK_STK_SIZE];
OS_STK YouTaskStk[TASK_STK_SIZE];
void Fun(INT8U x,INT8U y);
void StartTask(void *data);
void MyTask(void *data);
void YouTask(void *data);
void main (void)
{
Fun_Semp=OSSemCreate(1); //在主函数中创建信号量 返回值为创建的信号量指针,参数是信号量的计数器的值
//用该参数对信号量计数器OSEventCnt进行初始化
//1即代表只创建一个信号量,代表信号量用于对共享资源的访问(例如,把它当做二值信号量使用),详见P166
OSInit();
PC_DOSSaveReturn();
PC_VectSet(uCOS, OSCtxSw);
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
INT16S key;
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], 1); //创建任务函数
OSTaskCreate(YouTask,(void *)0, &YouTaskStk[TASK_STK_SIZE - 1], 2); //创建任务函数
for (;;)
{
//如果恩下ESC键,则退出UC/OS-II
if (PC_GetKey(&key) == TRUE)
{
if (key == 0x1B)
{
PC_DOSReturn();
}
}
OSTimeDlyHMSM(0,0,3,0);
}
}
//MyTask的函数代码
void MyTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
pdata = pdata;
for (;;)
{
OSSemPend(Fun_Semp,0,&err); //请求信号量 参数Fun_Semp是信号量指针 0那一项是等待时限timeout,0表示无限等待
//err表示错误信息
PC_DispStr(0,++y,s1,DISP_BGND_BLACK+DISP_FGND_WHITE); //显示MyTask字符串
Fun(7,y); //调用Fun函数
OSSemPost(Fun_Semp); //发送信号量 释放信号量,函数的参数Fun_Semp代表信号量的指针
OSTimeDlyHMSM(0,0,1,0);
}
}
void YouTask(void *pdata)
{
#if OS_CRITICAL_METHOD == 3 //Allocate storage for CPU status register
OS_CPU_SR cpu_sr;
#endif
pdata=pdata;
for (;;)
{
OSSemPend(Fun_Semp,0,&err); //请求信号量
PC_DispStr(0,++y,s2,DISP_BGND_BLACK+DISP_FGND_WHITE);
Fun(7,y); //调用FUN函数
OSSemPost(Fun_Semp); //释放信号量
OSTimeDlyHMSM(0,0,2,0); //等待2s
}
}
//公共的函数Fun的代码
void Fun(INT8U x,INT8U y)
{
PC_DispStr(x,y," Calling FUN()",DISP_BGND_BLACK+DISP_FGND_WHITE); //显示字符串,表示调用了Fun函数
}
//创建信号量时,用的参数为1,即Fun_Semp=OSSemCreate(1); ,只创建了一个信号量,这种情况一般是信号量用于对
//共享资源的访问(例如,可以把它当做二值信号量使用)
//在上面的程序中,当MyTask运行时,先请求获得了信号量,对共享资源Fun函数进行访问,由于只创建了一个信号量,
//所以在MyTask的访问期间,即使任务YouTask也进行申请信号量,此时OSEventCnt是值已经为0了,所以会把任务
//YouTask列入任务等代表OSEventTbl[]中,使任务处于等待状态。
//只有等MyTask对Fun函数访问完成了,调用OSSemPost(Fun_Semp);释放了信号量,该释放信号量的函数会先检查任务等待
//表中是否还有等待信号量的任务,如果有,则使任务进入就绪态后,调用调度器OS_Sched()引发一次任务调度,去运行等待
//任务列表中优先级最高的任务。如果没有,则就把信号量计数器OSSemCnt加1.
//所以任务YouTask要想访问Fun()函数,必须等到任务MyTask对Fun访问完毕,释放了信号量之后,才能访问,反之亦然
//所以由上面可以看出,只创建一个信号量,即OSSemCreate(1);,作用就相当于使用一个二值信号量,标志共享资源是否正在
//被访问
//看懂了上面的分析,也就可以解释实验现象了,由于YouTask等待2s,MyTask等待1s,所以有可能在MyTask访问Fan函数期间,YouTask
//也来访问(也有可能是反过来),但是由于信号量已经被MyTask占用了,所YouTask只好等待,MyTask使用完了,释放了信号量,YouTask才能正常使用Fun函数
//这样也就解决了多任务对共享资源的使用的问题,使任务之间得到了同步
//要仔细分析信号量工作的原理,把上面的内容看懂了,基本上也就可以使用信号量了
ocos 信号量的更多相关文章
- ucos实时操作系统学习笔记——任务间通信(信号量)
ucos实时操作系统的任务间通信有好多种,本人主要学习了sem, mutex, queue, messagebox这四种.系统内核代码中,这几种任务间通信机制的实现机制相似,接下来记录一下本人对核心代 ...
- Linux 信号量详解一
信号量主要用于进程间(不是线程)的互斥,通过sem_p()函数加锁使用资源,sem_v函数解锁释放资源,在加锁期间,CPU从硬件级别关闭中断,防止pv操作被打断. semget函数 int semge ...
- PHP进程通信基础——信号量+共享内存通信
PHP进程通信基础--信号量+共享内存通信 由于进程之间谁先执行并不确定,这取决于内核的进程调度算法,其中比较复杂.由此有可能多进程在相同的时间内同时访问共享内存,从而造成不可预料的错误.信号量这个名 ...
- C#多线程--信号量(Semaphore)
百度百科:Semaphore,是负责协调各个线程, 以保证它们能够正确.合理的使用公共资源.也是操作系统中用于控制进程同步互斥的量. Semaphore常用的方法有两个WaitOne()和Releas ...
- Linux学习笔记(15)-信号量
在多线程或者多进程编程中,有一个非常需要关注的东西,那就是同步以及互斥问题. 同步是指多个进程之间的协作,而互斥是指多个进程之间,为了争夺有限的资源,而进行的竞争. 理论很高端,但经过自己几天的学习, ...
- 多线程之信号量(By C++)
信号量在多线程中,主要是用于线程的同步或者限制线程运行的数量. 所谓同步,当流程1运行在线程1中,流程2运行在线程2中,流程2必须在流程1结束之后才能开始执行.你会怎么做,所有就需要给出一个流程1结束 ...
- 信号量sem
一.什么是信号量 为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域.临界区域是指执行数据更 ...
- 【.NET深呼吸】线程信号量(Semaphore)
Semaphore类可以控制某个资源允许访问的线程数,Semaphore有命名式的,也有不命名的:如果不考虑跨进程工作,一般在代码中使用不命名方式即可. 信号量有点类似于等待句柄,某个线程如果调用了W ...
- java多线程--信号量Semaphore的使用
Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...
随机推荐
- webpy,希望能多了解一些关于WSGI,PYTHON的WEB开发框架的事,也希望能进一步了解PYTHON
如果能真正看懂源代码,那就强了. 几年了,不应该总是小搞小打的. [Python]Webpy 源码学习(一) http://diaocow.iteye.com/blog/1922760 学习线路: 那 ...
- C++调用DLL有两种方法——静态调用和动态调用
C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报 分类: cpp(30) [ ...
- ActionResult 的返回类型
大多数操作方法会返回从 ActionResult 中派生的类的实例. ActionResult 类是所有操作结果的基础. 不过,也存在不同的操作结果类型,具体取决于操作方法执行的任务. 例如,最常见的 ...
- [LeetCode] 116. Populating Next Right Pointers in Each Node 解决思路
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *nex ...
- Object-C 类定义 -- 笔记
OC类分为两个文件,一个是.h文件,一个是.m文件 .h文件 存放类,函数的申明 .文件 存放类的具体实现 类申明使用关键字 @interface @end来申明 类实现使用关键字@implement ...
- 【iOS基础】iOS 网络请求
一.一个HTTP请求的基本要素1.请求URL:客户端通过哪个路径找到服务器 2.请求参数:客户端发送给服务器的数据* 比如登录时需要发送的用户名和密码 3.返回结果:服务器返回给客户端的数据* 一般是 ...
- IOS-连接
http://blog.sina.com.cn/s/articlelist_2659739627_0_2.html
- 【转】Linux中安装Resin
安装步骤: Ø 安装resin前先要保证安装了JDK,可以用命令查看是否安装了JDK: [root@wxr webapps]# java -versions java version " ...
- IIS7 常用模块介绍说明
1.1.0 IIS常用的功能模块介绍: 1) 静态内容:可发布静态 Web 文件格式,比如 HTML 页面和图像文件. 2) 默认文档:允许您配置当用户未在 URL ...
- 你的sscanf用对了吗
用sscanf解析输入字符串 我们平常编写的很多应用程序都会处理各种各样的输入,这些输入或来自本地文件,或来自网络,或来自用户的输入.今天,让我们来看看sscanf这个和字符串相关的函数可能给你带来的 ...