重点理解退出的机制:先删除信号量,再退任务
if (uwRet == true)
printf("task 2 access a semp OK!\r\n");
else //创造出现失误的条件
printf("task 2 access a semp ERROR!\r\n");
if(sum++>=5)
{
//删除信号量,信号索引ID
osal_semp_del(sync_semp);
}
if(sum>=10)
{
printf("exit task....sum:%d\r\n",sum);
sum=0;
//退出任务
osal_task_exit();
}
printf("task 2 access a semp sum:%d!\r\n",sum);
所有代码如下:
#include <osal.h>
#define USER_TASK1_PRI 12
#define USER_TASK2_PRI 11
osal_semp_t sync_semp;
/*
1、信号量(Semaphore)是一种实现任务间通信的机制,实现任务之间同步或临界资源的互斥访问。常用于协助一组相互竞争的任务来访问临界资源。
2、在多任务系统中,各任务之间需要同步或互斥实现临界资源的保护,信号量功能可以为用户提供这方面的支持。
3、通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数。其值的含义分两种情况:
1)0,表示没有积累下来的Post操作,且有可能有在此信号量上阻塞的任务。
2)正值,表示有一个或多个Post下来的释放操作。
4、以同步为目的的信号量和以互斥为目的的信号量在使用有如下不同:
1)用作互斥时,信号量创建后记数是满的,
在需要使用临界资源时,先取信号量,使其变空这样其他任务需要使用临界资源时就会因为无法取到信号量而阻塞,从而保证了临界资源的安全。
2)用作同步时,信号量在创建后被置为空,任务1取信号量而阻塞,任务2在某种条件发生后释放信号量,
于是任务1得以进入READY或RUNNING态,从而达到了两个任务间的同步。
运作原理:信号量初始化、创建、申请、释放、删除
*****信号量开发的典型流程:创建信号量(SemCreate),释放信号量(SemPost),申请信号量(SemPend),删除信号量(SemDelete)*****
*/
//主函数:创建信号量
//任务1:释放信号量
//任务2:申请信号量
static int user_task1_entry() //任务1
{
//用返回值检验是否信号量释放成功
uint32_t uwRet = NULL;
while (1)
{
printf("task 1 will post a temp ......... \r\n");
//任务1释放一个信号量
uwRet = osal_semp_post(sync_semp); //把信号量地址发出去
/*
osal_semp_pend(osal_semp_t semp)
semp -- 信号量索引ID地址
返回值: false - 创建失败
返回值: true - 创建成功
*/
if (uwRet == true)
{
printf("task 1 post a temp OK ! \r\n");
osal_task_sleep(2 * 1000);
}
else
printf("task 1 post a temp ERROR ! \r\n");
}
}
static int user_task2_entry() //任务2
{
uint32_t uwRet = NULL;
int sum = 0;
while (1)
{
printf("task2 is waiting for a semp....\r\n");
//申请得到信号量,完成任务一任务二的同步
uwRet = osal_semp_pend(sync_semp, cn_osal_timeout_forever);
/*
osal_semp_pend(osal_semp_t,int timeout)
semp -- 信号量索引ID地址
timeout -- 超时时间(32位值)
返回值: false - 创建失败
返回值: true - 创建成功
*/
if (uwRet == true)
printf("task 2 access a semp OK!\r\n");
else //创造出现失误的条件
printf("task 2 access a semp ERROR!\r\n");
if(sum++>=5)
{
//删除信号量,信号索引ID
osal_semp_del(sync_semp);
}
if(sum>=10)
{
printf("exit task....sum:%d\r\n",sum);
sum=0;
//退出任务
osal_task_exit();
}
printf("task 2 access a semp sum:%d!\r\n",sum);
}
}
int standard_app_demo_main() //已经在系统的main函数中自动调用了
{
/*
//osal_semp_create(osal_semp_t *semp,int limit,int initvalue)
semp--信号量索引ID的地址
limit -- 信号量计数值的最大值
initvalue -- 信号量计数值的初始值
返回值: false - 创建失败
返回值: true - 创建成功
*/
//创建信号量
osal_semp_create(&sync_semp, 1, 0);
printf("sysn_semp semp create success. \r\n");
osal_task_create("user_task1", user_task1_entry, NULL, 0X400, NULL, USER_TASK1_PRI);
osal_task_create("user_task2", user_task2_entry, NULL, 0X400, NULL, USER_TASK2_PRI);
return 0;
}