更新时间:2021-07-08 GMT+08:00
编程实例
实例描述
本实例实现如下功能:
- 测试任务Example_TaskEntry创建一个信号量,锁任务调度,创建两个任务Example_SemTask1、Example_SemTask2,Example_SemTask2优先级高于Example_SemTask1,两个任务中申请同一信号量,解锁任务调度后两任务阻塞,测试任务Example_TaskEntry释放信号量。
- Example_SemTask2得到信号量,被调度,然后任务休眠20Tick,Example_SemTask2延迟,Example_SemTask1被唤醒。
- Example_SemTask1定时阻塞模式申请信号量,等待时间为10Tick,因信号量仍被Example_SemTask2持有,Example_SemTask1挂起,10Tick后仍未得到信号量,Example_SemTask1被唤醒,试图以永久阻塞模式申请信号量,Example_SemTask1挂起。
- 20Tick后Example_SemTask2唤醒, 释放信号量后,Example_SemTask1得到信号量被调度运行,最后释放信号量。
- Example_SemTask1执行完,40Tick后任务Example_TaskEntry被唤醒,执行删除信号量,删除两个任务。
编程示例
前提条件:在menuconfig菜单中完成信号量的配置。
代码实现如下:
#include "los_sem.h" #include "securec.h" /* 任务ID */ static UINT32 g_testTaskId01; static UINT32 g_testTaskId02; /* 测试任务优先级 */ #define TASK_PRIO_TEST 5 /* 信号量结构体id */ static UINT32 g_semId; VOID Example_SemTask1(VOID) { UINT32 ret; printf("Example_SemTask1 try get sem g_semId ,timeout 10 ticks.\n"); /* 定时阻塞模式申请信号量,定时时间为10ticks */ ret = LOS_SemPend(g_semId, 10); /* 申请到信号量 */ if (ret == LOS_OK) { LOS_SemPost(g_semId); return; } /* 定时时间到,未申请到信号量 */ if (ret == LOS_ERRNO_SEM_TIMEOUT) { printf("Example_SemTask1 timeout and try get sem g_semId wait forever.\n"); /*永久阻塞模式申请信号量*/ ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); printf("Example_SemTask1 wait_forever and get sem g_semId .\n"); if (ret == LOS_OK) { LOS_SemPost(g_semId); return; } } } VOID Example_SemTask2(VOID) { UINT32 ret; printf("Example_SemTask2 try get sem g_semId wait forever.\n"); /* 永久阻塞模式申请信号量 */ ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER); if (ret == LOS_OK) { printf("Example_SemTask2 get sem g_semId and then delay 20ticks .\n"); } /* 任务休眠20 ticks */ LOS_TaskDelay(20); printf("Example_SemTask2 post sem g_semId .\n"); /* 释放信号量 */ LOS_SemPost(g_semId); return; } UINT32 ExampleTaskEntry(VOID) { UINT32 ret; TSK_INIT_PARAM_S task1; TSK_INIT_PARAM_S task2; /* 创建信号量 */ LOS_SemCreate(0,&g_semId); /* 锁任务调度 */ LOS_TaskLock(); /* 创建任务1 */ (VOID)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask1; task1.pcName = "TestTsk1"; task1.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; task1.usTaskPrio = TASK_PRIO_TEST; ret = LOS_TaskCreate(&g_testTaskId01, &task1); if (ret != LOS_OK) { printf("task1 create failed .\n"); return LOS_NOK; } /* 创建任务2 */ (VOID)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S)); task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_SemTask2; task2.pcName = "TestTsk2"; task2.uwStackSize = OS_TSK_DEFAULT_STACK_SIZE; task2.usTaskPrio = (TASK_PRIO_TEST - 1); ret = LOS_TaskCreate(&g_testTaskId02, &task2); if (ret != LOS_OK) { printf("task2 create failed .\n"); return LOS_NOK; } /* 解锁任务调度 */ LOS_TaskUnlock(); ret = LOS_SemPost(g_semId); /* 任务休眠40 ticks */ LOS_TaskDelay(40); /* 删除信号量 */ LOS_SemDelete(g_semId); /* 删除任务1 */ ret = LOS_TaskDelete(g_testTaskId01); if (ret != LOS_OK) { printf("task1 delete failed .\n"); return LOS_NOK; } /* 删除任务2 */ ret = LOS_TaskDelete(g_testTaskId02); if (ret != LOS_OK) { printf("task2 delete failed .\n"); return LOS_NOK; } return LOS_OK; }
结果验证
编译运行得到的结果为:
Example_SemTask2 try get sem g_semId wait forever. Example_SemTask1 try get sem g_semId ,timeout 10 ticks. Example_SemTask2 get sem g_semId and then delay 20ticks . Example_SemTask1 timeout and try get sem g_semId wait forever. Example_SemTask2 post sem g_semId . Example_SemTask1 wait_forever and get sem g_semId .
完整实例代码
父主题: 信号量