介绍计数信号量所用到的函数
1.创建计数信号量
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount,
UBaseType_t uxInitialCount);
功 能:
创建一个计数信号量。
参 数:
uxMaxCount: 计数信号量的最大值, 当达到这个值的时候,信号量不能再被释放。
uxInitialCount: 创建计数信号量的初始值。
返 回 值:
如果创建成功则返回一个计数信号量句柄,用于访问创建的计数信号量。
如果创建不成功则返回 NULL。
2. 计数信号量的获取
xSemaphoreTake( xSemaphore, xBlockTime )
参数:
xSemaphore:二值信号量句柄
xBlockTime: portMAX_DELAY 既没有申请到资源阻塞,
申请到立马返回
返回值:成功返回pdPASS
3. 计数信号量的释放
xSemaphoreGive(SemaphoreHandle_t xSemaphore )
参数:
xSemaphore :二值信号量句柄
返回值:成功返回pdPASS
4. 代码
#include "main.h"
#define QUEUE_LEN_MAX 6
#define QUEUE_SIZE 4
void APP_TaskCreate(void *p);
void Recive_Task(void *p);
void Send_Task(void *p);
void All_Config(void);
TaskHandle_t APP_CreateHandle = NULL;
TaskHandle_t Send_CreateHandle = NULL;
TaskHandle_t Recive_CreateHandle = NULL;
SemaphoreHandle_t p_Semap = NULL;
int main(void)
{
BaseType_t Task_Ret = pdPASS;
All_Config();
Task_Ret = xTaskCreate(APP_TaskCreate,
"App_TaskCreate",
32,
NULL,
2,
&APP_CreateHandle);
if(Task_Ret == pdPASS)
{
printf("任务创建成功\r\n");
vTaskStartScheduler();//开启任务调度
}
}
/****************************
函数名称:APP_TaskCreate
函数作用:任务创建
函数参数:无
函数返回值:无
****************************/
void APP_TaskCreate(void *p)
{
taskENTER_CRITICAL(); //开启临界段
BaseType_t Task_Ret = pdPASS;
//创建计数信号量
p_Semap = xSemaphoreCreateCounting(10,10);
if(p_Semap == NULL)
printf("创建计数信号量失败\r\n");
else
printf("创建计数信号量成功\r\n");
Task_Ret = xTaskCreate(Send_Task, //函数名称
"Send_TaskCreate", //任务名称
512, //任务堆栈大小
NULL, //传递给任务的参数
3, //优先级
&Send_CreateHandle //任务句柄
);
if(Task_Ret == pdPASS)
printf("send任务创建成功\r\n");
else
printf("send任务创建失败\r\n");
Task_Ret = xTaskCreate(Recive_Task, //函数名称
"Recive_TaskCreate", //任务名称
512, //任务堆栈大小
NULL, //传递给任务的参数
2, //优先级
&Recive_CreateHandle //任务句柄
);
if(Task_Ret == pdPASS)
printf("Recive任务创建成功\r\n");
else
printf("Recive任务创建失败\r\n");
//删除本任务
vTaskDelete(APP_CreateHandle);
printf("APP任务删除\r\n");
taskEXIT_CRITICAL(); //关闭临界段
}
/****************************
函数名称:Recive_Task
函数作用:释放信号量(+1)
函数参数:无
函数返回值:无
****************************/
void Recive_Task(void *p)
{
BaseType_t Task_Ret = pdTRUE;
while(1)
{
if(KEY_GetVal() == 1)
{
Task_Ret = xSemaphoreGive(p_Semap);//释放二值信号量
if ( Task_Ret == pdTRUE )
printf("释放一个车位!\r\n");
else
printf("已释放全部车位!\r\n");
}
vTaskDelay(20);//释放CPU
}
}
/****************************
函数名称:Send_Task
函数作用:得到信号量(-1)
函数参数:无
函数返回值:无
****************************/
void Send_Task(void *p)
{
BaseType_t Task_Ret = pdPASS;
uint8_t data = 0X00;
while(1)
{
if((USART1->SR &(0X01<<5)))
{
data=USART1->DR;
if(data == 'A')
{
data=0;
Task_Ret = xSemaphoreTake(p_Semap,/* 二值信号量句柄 */
0); /* 等待时间 */
if (Task_Ret == pdTRUE)
printf("获得一个车位!\r\n");
else
printf("车位已满!\r\n");
}
}
vTaskDelay(20);//释放CPU
}
}
void All_Config(void)
{
NVIC_SetPriorityGrouping(5);
BEEP_Config();
LED_Config();
KEY_Config();
USART_Config(9600);
printf("USART1 OK\r\n");
}