chenbingjy 发表于 2024-11-12 13:14

如何使能二进制信号量

<p>请问高手,freertos如何使能二进制信号量?谢谢</p>

fxyc87 发表于 2024-11-13 09:36

<p>我只是大自然的搬运工</p>

<hr />
<p>1. **二进制信号量简介**<br />
&nbsp; &nbsp;- 在FreeRTOS中,二进制信号量是一种用于任务同步和互斥的机制。它只有两种状态:满(被获取)和空(可用)。二进制信号量可以用于保护共享资源,也可以用于任务之间的同步。<br />
2. **使能二进制信号量的步骤**<br />
&nbsp; &nbsp;- **创建二进制信号量**<br />
&nbsp; &nbsp; &nbsp;- 使用`xSemaphoreCreateBinary()`函数来创建一个二进制信号量。这个函数返回一个`SemaphoreHandle_t`类型的句柄。例如:<br />
```c<br />
SemaphoreHandle_t binarySemaphore;<br />
binarySemaphore = xSemaphoreCreateBinary();<br />
if(binarySemaphore == NULL)<br />
{<br />
&nbsp; &nbsp; // 创建失败的处理,可能是内存不足等原因<br />
&nbsp; &nbsp; // 可以在这里添加错误处理代码,如打印错误信息等<br />
}<br />
```<br />
&nbsp; &nbsp;- **给出(释放)信号量**<br />
&nbsp; &nbsp; &nbsp;- 二进制信号量创建后,默认是没有被获取的(空状态)。可以使用`xSemaphoreGive()`函数来释放信号量,使其变为满状态。例如,在一个任务中释放信号量:<br />
```c<br />
void vTaskFunction(void *pvParameters)<br />
{<br />
&nbsp; &nbsp; // 其他任务代码<br />
&nbsp; &nbsp; // 释放信号量<br />
&nbsp; &nbsp; if(xSemaphoreGive(binarySemaphore)== pdTRUE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 信号量释放成功的处理<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 信号量释放失败的处理,可能是信号量无效等原因<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; // 任务的其他代码<br />
}<br />
```<br />
&nbsp; &nbsp;- **获取信号量**<br />
&nbsp; &nbsp; &nbsp;- 另一个任务或者中断服务函数(在满足条件的情况下)可以使用`xSemaphoreTake()`函数来获取信号量。当信号量处于满状态时,`xSemaphoreTake()`函数会将信号量变为空状态,并允许任务继续执行。例如:<br />
```c<br />
void anotherTaskFunction(void *pvParameters)<br />
{<br />
&nbsp; &nbsp; if(xSemaphoreTake(binarySemaphore, portMAX_DELAY)== pdTRUE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 成功获取信号量,执行受信号量保护的代码段<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 例如访问共享资源等<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 完成后可以再次释放信号量,以便其他任务获取<br />
&nbsp; &nbsp; &nbsp; &nbsp;xSemaphoreGive(binarySemaphore);<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; else<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 获取信号量失败的处理,可能是信号量为空且等待超时等原因<br />
&nbsp; &nbsp; }<br />
}<br />
```<br />
&nbsp; &nbsp;- **注意事项**<br />
&nbsp; &nbsp; &nbsp;- 当在中断服务函数中使用信号量时,应该使用`xSemaphoreGiveFromISR()`函数来释放信号量,而不是`xSemaphoreGive()`。因为在中断服务函数中不能调用会导致阻塞的函数。`xSemaphoreGiveFromISR()`函数的使用稍微复杂一些,它需要一个额外的参数来指示是否需要进行任务切换。例如:<br />
```c<br />
void vISRFunction(void)<br />
{<br />
&nbsp; &nbsp; BaseType_t xHigherPriorityTaskWoken = pdFALSE;<br />
&nbsp; &nbsp; xSemaphoreGiveFromISR(binarySemaphore, &amp;xHigherPriorityTaskWoken);<br />
&nbsp; &nbsp; if(xHigherPriorityTaskWoken == pdTRUE)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp;// 请求任务切换,使等待信号量的高优先级任务能够尽快运行<br />
&nbsp; &nbsp; &nbsp; &nbsp;portYIELD_FROM_ISR();<br />
&nbsp; &nbsp; }<br />
}<br />
```<br />
&nbsp; &nbsp; &nbsp;- 在使用二进制信号量进行任务同步或互斥时,要确保正确地初始化、释放和获取信号量,以避免出现死锁或资源竞争等问题。并且要根据具体的应用场景合理地设置信号量获取的等待时间,如使用`portMAX_DELAY`表示一直等待,直到信号量可用,或者使用其他较短的时间值来实现有限时间的等待。</p>

freebsder 发表于 2024-11-19 14:13

<p>直接用吧,这个不复杂啊。只不过要在不同线程处理请求和释放。</p>
页: [1]
查看完整版本: 如何使能二进制信号量