freertos阻塞函数
时间: 2024-07-28 17:01:16 浏览: 122
FreeRTOS(Real-Time Operating System for Embedded Systems)是一个轻量级嵌入式实时操作系统,它特别适合小型微控制器。Freertos提供了一系列的API函数,其中就包括一些用于同步任务的阻塞函数,比如:
1. vTaskDelay():这是一个基本的睡眠函数,它会使当前的任务暂停运行指定的时间(以 Tick 指数计数单位),直到再次唤醒。
2. xQueueReceive() 和 xQueueSend():这两个函数用于操作队列(queue),如果队列为空,xQueueReceive()会阻塞等待消息的到来;反之,如果队列满,xQueueSend()会挂起发送者。
3. xSemaphoreTake() 和 xSemaphoreGive():它们分别用于获取信号量(semaphore)和释放信号量,当信号量值为0并且有其他任务正在等待获取该信号量时,xSemaphoreTake()会阻塞。
4. xEventGroupWaitBits():这个函数用于在一个事件组(event group)上等待多个事件之一发生,如果所有事件都没有满足条件,该函数会进入阻塞状态。
这些阻塞函数允许任务在需要的时候暂时停止执行,以便于管理系统的资源,如处理器时间、内存和其他共享资源,提高了系统的响应性和效率。
相关问题
FreeRTOS阻塞状态
在FreeRTOS中,阻塞状态是指任务调用延时函数后,任务会被剥夺CPU的使用权,进入阻塞状态,直到延时时间结束后,任务重新获取CPU的使用权才能继续运行。在任务阻塞期间,CPU可以执行其他任务,如果其他任务也处于延时状态,那么CPU将运行空闲任务。空闲任务是系统在启动调度器时创建的优先级最低的任务,它主要负责系统内存的清理工作。\[1\]\[2\]\[3\]
#### 引用[.reference_title]
- *1* [【FreeRTOS】03 任务的运行、就绪、阻塞、挂起](https://blog.csdn.net/little_grapes/article/details/124657272)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item]
- *2* *3* [FreeRTOS 笔记之⑥:空闲任务与阻塞延时的实现](https://blog.csdn.net/XieWinter/article/details/103052953)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item]
[ .reference_list ]
freertos阻塞链表
### FreeRTOS 中阻塞链表的使用
#### 创建和初始化阻塞链表
为了创建并初始化一个用于任务间通信的阻塞链表,在FreeRTOS中可以利用`xQueueCreate()`函数来完成这一操作。该函数允许指定队列长度以及每个数据项大小,从而定义了一个固定尺寸的消息缓冲区[^1]。
```c
// 定义消息结构体
typedef struct {
uint8_t ucMessageID;
char cData[ 20 ];
} xMessage;
// 创建具有特定数量槽位及每条消息字节数量的队列句柄
xQueueHandle xCreatedQueue;
void vAFunction( void )
{
// 假设我们希望创建能够容纳10个上述类型变量的空间作为队列元素,
// 并且这些元素占用内存空间等于单个xMessage实例所占。
xCreatedQueue = xQueueCreate( 10, sizeof( xMessage ) );
if( xCreatedQueue == NULL )
{
// 如果返回NULL,则表示由于缺乏堆内存而未能成功建立所需资源。
}
}
```
#### 向阻塞链表发送数据
当向已存在的队列写入新项目时,可选用两种模式之一:立即尝试发送(`xQueueSend`)或是带超时机制等待直到有空闲位置可用(`xQueueSendToBack`)。后者对于处理高优先级中断服务程序(ISR)特别有用,因为它不会使当前上下文挂起而是直接失败退出。
```c
BaseType_t xStatus;
// 尝试立即将一条消息加入到之前声明过的队列里
xStatus = xQueueSend( xCreatedQueue , &xItemToSend , ( TickType_t ) 0 );
if(xStatus != pdPASS){
// 发送未成功的错误处理逻辑...
}
// 或者采用另一种方式带有最大容忍时间参数的方式推送至队尾
const TickType_t xTicksToWait = 10 / portTICK_PERIOD_MS;
xStatus = xQueueSendToBack( xCreatedQueue , &xAnotherItemToSend , xTicksToWait );
if(xStatus != pdPASS){
// 考虑在此处实现重发策略或其他补偿措施
}
```
#### 接收来自阻塞链表的数据
接收端同样有两种不同的行为可以选择——即时获取(`xQueueReceive`)或是在规定时间内轮询直至接收到有效载荷(`uxQueueMessagesWaiting`)。前者适用于常规的任务同步场景;后者则适合于那些需要频繁查询是否有待读取的新信息的情况。
```c
xMessage receivedMsg;
// 设置最长等待时间为10ms
const TickType_t xBlockTime = 10 / portTICK_PERIOD_MS;
while(true)
{
// 阻塞性地从队列中取出下一个可用的消息副本
if(pdTRUE == xQueueReceive( xCreatedQueue , &receivedMsg , xBlockTime ))
{
// 成功获得了一条完整的记录后执行相应业务流程...
}else{
// 处理因超时等原因造成无果的情形
}
// ...其他代码片段...
// 查询当前队列剩余未被消费的数量
UBaseType_t count = uxQueueMessagesWaiting( xCreatedQueue );
if(count > 0){
// 存在积压的信息提示或者其他动作
}
}
```
阅读全文
相关推荐
















