1.行为同步的概念
一个任务的运行过程中需要其他任务的配合,才能得到预定的效果,任务之间的这种动作称为“行为同步”。
2.具体情况
2.1 任务之间的单向同步
可以通过信号量实现,
示意代码如下:
OS_EVENT *Sem1,*Sem2; //创建信号量
INT8U err; //定义返回信息的变量
void task1(void * pdata)
{
INT8U err;
pdata=pdata;
while(1)
{
OSSemPend(Sem2,0,&err);//等待信号量2
........
OStimeDly(10);
}
}
void task2(void * pdata)
{
INT8U err;
pdata=pdata;
while(1)
{
OSSemPend(Sem1,0,&err);//等待信号量1
........
OStimeDly(10);
}
}
void task3(void * pdata)
{
INT8U err;
pdata=pdata;
while(1)
{
OSSemPost(Sem1,0,&err);//发送信号量1
OSSemPost(Sem2,0,&err);//发送信号量2
........
}
}
2.2任务与任务之间的双向同步
示例代码:
OS_EVENT *SeMbox;//定义发送消息邮箱指针
OS_EVENT *AckMbox;//定义应答消息邮箱指针
void task1(void * pdata)//task1 为按键任务,用户触发
{
INT8U err;
pdata=pdata;
while(1)
{
........//任务代码
OSMboxPost(SeMbox,(void *)1);//发送消息
........//任务代码
OSMboxPend(AckMbox,0,&err);//等待消息
OStimeDly(10);
}
}
void task2(void * pdata)
{
INT8U err;
pdata=pdata;
while(1)
{
OSMboxPend(SeMbox,0,&err);//等待消息
........//任务代码
OSMboxPost(AckMbox,(void *)1);//发送消息
........//任务代码
OStimeDly(10);
}
}
2.3多个任务相互同步
这种情况使用事件标志组结合用于计数的全局变量实现,防止中断造成行为同步的失效:
示意代码如下:
INT8U cnt;
void taskA(void * pdata)//task1 为按键任务,用户触发
{
INT8U err;
pdata=pdata;
while(1)
{
OSFlagPost(FLAGW,//发送签到任务
0x01,//bit0 置位
OS_FLAG_SET,//1有效
&err);
OSFlagPend(FLAGW,
0x07,//等待最低三位
OS_FLAG_WAIT_SET_ALL,//全为1
0,
&err
)
........//同步点之后的任务代码
OStimeDly(10);
}
}
void taskB(void * pdata)//task1 为按键任务,用户触发
{
INT8U err;
pdata=pdata;
while(1)
{
OSFlagPost(FLAGW,//发送签到任务
0x02,//bit1 置位
OS_FLAG_SET,//1有效
&err);
OSFlagPend(FLAGW,
0x07,//等待最低三位
OS_FLAG_WAIT_SET_ALL,//全为1
0,
&err
)
........//同步点之后的任务代码
OStimeDly(10);
}
}
void taskA(void * pdata)//task1 为按键任务,用户触发
{
INT8U err;
pdata=pdata;
while(1)
{
OSFlagPost(FLAGW,//发送签到任务
0x04,//bit2 置位
OS_FLAG_SET,//1有效
&err);
OSFlagPend(FLAGW,
0x07,//等待最低三位
OS_FLAG_WAIT_SET_ALL,//全为1
0,
&err
)
........//同步点之后的任务代码
OStimeDly(10);
}
}
参考文献
[1] 周慈航. 《基于嵌入式实时操作系统的程序设计技术》[M].北京航空航天大学出版社,2011.