信号量(这里仅说互斥)就两个操作,一个请求,一个释放。
一个任务请求信号量时:如果被其它任务占用,则该任务等待,同时导致任务切换;如果没有被其它任务占用,则获得,继续执行。
释放信号量时,如果其它高优先级任务正在请求并等待该信号量,则导致任务切换。
OSTimeDly之类,并不导致信号量的释放。只有获取信号量的那个任务调用释放功能时,信号量才会释放。
信号量
信号量的使用自己看了几天仍然没搞明白信号量,邮箱,和队列的区别。现在是学习信号量的使用,苦于没有现成的例子参考,只能一步步弄清楚它的,感觉外国人的思维还是和中国的有很大的出入,以至于学习一个国外的技术, 总是先翻译成自己习惯的思维去领会,变成自己的东西。
信号量程序dj:
#include
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
OS_STK TaskStk[3][MaxStkSize];//定义3个堆栈
void task0(void *dat);//定义任务0
void task1(void *dat);
long con1=0;
long con2=0;
OS_EVENT *sem;
u8 err;
main()
{
OSInit();
InitTimer0( );
sem=OSSemCreate(1);//建立信号量
OSTaskCreate(task0,(void*)0,&TaskStk[0][0],5);//建立任务 定义好它的优先级等参数
OSTaskCreate(task1,(void*)0,&TaskStk[1][0],6);
OSStart();
}
void task0(void *dat)//任务0
{
while(1)
{
con1++;
OSSemPost(sem);//发送信号量
OSTimeDly(2);
}
}
void task1(void *dat)//任务1
{
u16 value;
u16 vison;
while(1)
{
value=OSSemAccept(sem); //查看资源是否可以使用
OSSemPend(sem,0,&err); //等待接收信号 才往下执行任务
con2++;
}
OSTimeDly(2);//延时
}
}
心得:
信号量的建立必须是在任务级中建立,信号量类型为OS_EVENT ,信号量值可以为1,0,0~65535的值,不同的值代表不同的意义。
OSSemAccept(信号量)起查询信号量作用,返回信号量的值。
OSSemPend(sem,0,&err);将暂停当前任务,等待信号量的到来。如果 接收到一个信号量(如果信号量大于0) ,该信号量会自动减1,在例子中,信号量开始定义为1,在任务1接收后,信号量会变为0;例子中的OSSemPend(sem,timeout,&err),timeout代表等待timeout个信号量后还没得到信号量,恢复运行状态,如果timeout=0,表示无限等待信号量。