文章目录
前言
队列就像一个传送带,可以传送不同数据。信号量不能传输数据,只能表示资源的数量,信号量只有一个计数值。在前面同步互斥中,我们有两个实验。
同步实验: 我们创建了两个任务,
任务1循环遍历一个比较大的数字,遍历完成后设置标志位置1。任务2等待任务1标志位置1后串口发送数据,但是在任务2等待过程中也参与CPU的调度,从而导致任务1计算时间增加。
我们的问题就是既然任务2在等待,那如何配置才能让任务2不抢占CPU资源。
互斥实验: 两个任务交替使用一个函数发送串口数据。
上一章我们用队列解决同步互斥,但由于队列数据保存也需要空间。本章我们使用信号量来解决。使用信号量时不需要传递数据和复制数据,更节省空间、效率更高
一、计数型信号量使用
创建句柄
static SemaphoreHandle_t xSemCalc;
xSemCalc = xSemaphoreCreateCounting(10, 0);
释放信号和获取信号
void Task1Function(void * param)
{
volatile int i = 0;
while (1)
{
for (i = 0; i < 10000000; i++)
sum++;
//printf("1");
xSemaphoreGive(xSemCalc);
vTaskDelete(NULL);
}
}
void Task2Function(void * param)
{
while (1)
{
//if (flagCalcEnd)
flagCalcEnd = 0;
printf("flagCalcEnd = %d\r\n", flagCalcEnd);
xSemaphoreTake(xSemCalc, portMAX_DELAY);
flagCalcEnd = 1;
printf("sum = %d\r\n", sum);
}
}
二、二进制信号量实现互斥
创建句柄
static SemaphoreHandle_t xSemUART;
xSemUART = xSemaphoreCreateBinary();
xSemaphoreGive(xSemUART);//初始值设为1表示可以使用
释放信号和获取信号
void TaskGenericFunction(void * param)
{
while (1)
{
xSemaphoreTake(xSemUART, portMAX_DELAY);
printf("%s\r\n", (char *)param);
xSemaphoreGive(xSemUART);
vTaskDelay(1);
}
}