信号量用于资源共享、任务同步、任务和ISR(中断服务函数)间的同步,在现实实验中比较多用于任务同步和任务和ISR(中断服务函数)间的同步。
//信号量常用函数
//信号量用于资源共享例子如下:
//申请一个信号量和共享资源块
u8 share_resource[30]; //共享资源区
OS_SEM MY_SEM_SHARE; //定义一个信号量,用于访问共享资源
//创建信号量
//创建一个信号量
OSSemCreate ((OS_SEM* )&MY_SEM_SHARE,
(CPU_CHAR* )"MY_SEM_SHARE",
(OS_SEM_CTR)1, //信号量为二进制信号量
(OS_ERR* )&err);
//使用信号量来访问共享资源,SemShare1_task()e和SemShare2_task()函数都访问共享资源share_resource[30],为防止其中一个任务在访问共享资源share_resource[30]时,另一个任务对共享资源share_resource[30]进行修改。
//阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后在进行操作。
//非阻塞操作的进程在不能进行设备操作时并不挂起,它或者被放弃,或者不停的查询,直到可以进行操作为止
//使用OSSemPost (&MY_SEM_SHARE,OS_OPT_POST_1,&err)时:信号量MY_SEM_SHARE.Ctr自加1
//OSSemPend(&MY_SEM_SHARE,0,OS_OPT_PEND_BLOCKING,0,&err)时:信号量MY_SEM_SHARE.Ctr自减1
//当信号量MY_SEM_SHARE.Ctr为0时,不能请求信号量
void SemShare1_task(void *p_arg)
{
OS_ERR err;
u8 task1_str[]="First task Running!";
while(1)
{
printf("Semshare:task1111\r\n");
OSSemPend(&MY_SEM_SHARE,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量,阻塞
memcpy(share_resource,task1_str,sizeof(task1_str)); //向共享资源区拷贝数据
delay_ms(300);
printf("%s\r\n",share_resource); //串口输出共享资源区数据
OSSemPost (&MY_SEM_SHARE,OS_OPT_POST_1,&err); //发送信号量
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
void SemShare2_task(void *p_arg)
{
OS_ERR err;
u8 task2_str[]="Sencond task Running!";
while(1)
{
printf("Semshare:task2222\r\n");
OSSemPend(&MY_SEM_SHARE,0,OS_OPT_PEND_BLOCKING,0,&err); //请求信号量,阻塞
memcpy(share_resource,task2_str,sizeof(task2_str)); //向共享资源区拷贝数据
delay_ms(300);
printf("%s\r\n",share_resource); //串口输出共享资源区数据
OSSemPost (&MY_SEM_SHARE,OS_OPT_POST_1,&err); //发送信号量
OSTimeDlyHMSM(0,0,1,0,OS_OPT_TIME_PERIODIC,&err); //延时1s
}
}
//信号量用于任务同步:
//定义一个信号量,用于任务同步
OS_SEM MY_SEM_SYNC; //定义一个信号量,用于任务同步
//创建一个信号量
//创建一个信号量,用于任务同步
OSSemCreate ((OS_SEM* )&MY_SEM_SYNC,
(CPU_CHAR* )"MY_SEM_SYNC",
(OS_SEM_CTR)0, //信号量数初始化为0;必须使用OSSemPost()函数来释放一个信号量
(OS_ERR* )&err);
//使用信号量进行任务间的同步:使用SemSync1_task()函数来释放信号量给SemSync2_task()函数,从而达到任务同步。每释放一次信号量,MY_SEM_SYNC.Ctr自加1,每请求一次信号量MY_SEM_SYNC.Ctr自减1,直到减为0时就不能再请求信号量。
//阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后在进行操作。
//非阻塞操作的进程在不能进行设备操作时并不挂起,它或者被放弃,或者不停的查询,直到可以进行操作为止
void SemSync1_task(void *p_arg)
{
OS_ERR err;
static u8 count = 0;
while(1)
{
if(count++ == 100)//判断语句可以根据项目的需求,判断什么时候任务同步
{
count = 0;
OSSemPost(&MY_SEM_SYNC,OS_OPT_POST_1,&err);//发送信号量
printf("SemSync111:SYNC_SEM.Ctr:%d\r\n",MY_SEM_SYNC.Ctr);
}
OSTimeDlyHMSM(0,0,0,10,OS_OPT_TIME_PERIODIC,&err); //延时10ms
}
}
void SemSync2_task(void *p_arg)
{
OS_ERR err;
while(1)
{
OSSemPend(&MY_SEM_SYNC,0,OS_OPT_PEND_BLOCKING,0,&err);//请求信号量,没有请求到信号量则阻塞
printf("SemSync222:SYNC_SEM.Ctr:%d\r\n",MY_SEM_SYNC.Ctr);
OSTimeDlyHMSM(0,0,2,0,OS_OPT_TIME_PERIODIC,&err);
}
}