freeRtos学习笔记
freeRtos任务通知
任务通知的优缺点
- freeRtos任务控制块中包含两个32位的变量,用于任务通知,在一些情况下,任务通知可以替代信号量和事件组,并且比信号量和事件组效率更高。
- 如果不使用任务通知,则可以关闭configUSE_TASK_NOTIFICATIONS宏 在创建任务时,每个任务就可以少8个字节的RAM。
- 任务通知存放在任务控制块中,因此在本任务中接收本任务控制块中的任务通知。
- 只有等待通知的任务才能被堵塞,发送通知的任务不会因为发送失败进入堵塞状态。
发送任务通知信号量函数
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify ); /* 任务句柄 */
void vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, /* 任务句柄 */
BaseType_t *pxHigherPriorityTaskWoken ); /* 高优先级任务是否被唤醒的状态保存 */
发送信号量函数 任务通知信号量加一
- 第一个参数 任务句柄
- 第二个参数 对应任务由于获取不到信号量而进入堵塞态,在中断中发送了该任务的任务通知信号量,则该任务由堵塞态转变为就绪态,如果该任务优先级比当前运行的任务优先级高,则pxHigherPriorityTaskWoken会变为pdTRUE 在中断结束部分可以调用taskYELD()进行任务调度
- 返回值 只会发会pdTRUE
- 注意 任务通知存放在任务控制块内,所以只需要创建对应任务,并打开任务通知使能宏即可
获取任务通知信号量函数
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, /* 选择是否清零用于任务通知的 ulNotifiedValue */
TickType_t xTicksToWait ); /* 等待信号量可用的最大等待时间 */
获取任务通知信号量函数
- 第一个参数 如果为pdFALSE 则该函数返回前会将任务通知信号量减一,如果为pdTRUE 函数返回前会将任务通知信号量清零
- 第二个参数 如果没有任务信号量,最大等待时间,单位为系统节拍
- 返回值 返回任务当前通知值,即在其减一或者清零前的值
修改任务通知变量函数
BaseType_t xTaskNotify(TaskHandle_t xTaskNotify, /* 任务句柄 */
uint32_t ulValue, /* 更新任务控制块中的通知变量值 */
eNotifyAction eAction); /* 任务通知更新模式 */
BaseType_t xTaskNotifyFromISR(TaskHandle_t xTaskNotify, /* 任务句柄 */
uint32_t ulValue, /* 更新任务控制块中的通知变量值 */
eNotifyAction eAction, /* 任务通知更新模式 */
BaseType_t *pxHightPriorityTaskWoken) /* 高优先级任务是否被唤醒的状态保存 */
修改任务通知变量函数
- 第一个参数 任务句柄
- 第二个参数 要更新的值
- 第三个参数 更新模式
支持参数 | 参数描述 |
---|---|
eNoAction | 接收此消息的任务, 其任务控制块中的变量 ulNotifiedValue 没有变化,即函数 xTaskNotify 第 2 个参数 ulValue 没有用上。 |
eSetBits | 接收此消息的任务, 其任务控制块中的变量 ulNotifiedValue 与函数 xTaskNotify 第 2 个参数 ulValue 实现或操作,比如ulValue=0x01, 那么变量的 ulNotifiedValue 的 bit0 = 1,ulValue=0x08, 那么变量的 ulNotifiedValue 的 bit3= 1, 通过这种方式就实现了任务事件标志组。 |
eIncrement | 接收此消息的任务, 其任务控制块中的变量 ulNotifiedValue 实现加一操作,此时函数 xTaskNotify 实现的功能等效于函数xTaskNotifyGive, 函数 xTaskNotify 的第二个参数 ulValue 没有用上。 这种方式用于信号量。 |
eSetValueWithOverwrite | 接收此消息的任务, 其任务控制块中的变量 ulNotifiedValue 被设置为函数 xTaskNotify 第 2 个参数 ulValue 的数值,即使等待此消息的任务还没有收到上一次的数值,数值也会被覆盖。 这种方式相当于消息队列覆盖方式函数xQueueOverwrite()。 |
eSetValueWithoutOverwrite | 如果接收此消息的任务, 其任务控制块中的变量 ulNotifiedValue 已经被更新,但由于接收此消息的任务还处于阻塞态等待此消息,那么变量 ulNotifiedValue 不可以被更新为函数 xTaskNotify 第 2 个参数 ulValue 的数值,和 eSetValueWithOverwrite 相反(eSetValueWithOverwrite 会丢弃覆盖旧数据,eSetValueWithoutOverwrite 不丢弃旧数据,丢弃此次设置的新数据), 此时函数xTaskNotify 会返回 pdFALSE。如果接收此消息的任务, 其任务控制块中的变量ulNotifiedValue 还没有被更新, 那么变量 ulNotifiedValue 会被设置为 xTaskNotify 第 2 个参数 ulValue 的数值。这种方式用于消息邮箱,相当于消息队列长度为 1 时调用函数xQueueSend()。 |
- 第四个参数 对应任务由于获取不到信号量而进入堵塞态,在中断中发送了该任务的任务通知信号量,则该任务由堵塞态转变为就绪态,如果该任务优先级比当前运行的任务优先级高,则pxHigherPriorityTaskWoken会变为pdTRUE 在中断结束部分可以调用taskYELD()进行任务调度
- 返回值 第三个参数为eSetValueWithoutOverwrite时有可能返回pdFALSE 其他的均返回pdPASS
等待任务通知函数
BaseType_t xTaskNotifyWait(uint32_t ulBitsToClearOnEntry,
uint32_t ulBitsToClearOnExit,
uint32_t *pulNotificationValue,
TickType_t xTicksToWait);
等待任务通知函数
- 第一个参数 函数执行前,任务通知变量那些位被清除
- 第二个参数 函数退出前,任务通知变量那些位被清除
- 第三个参数 保存任务控制块中任务通知变量值
- 第四个参数 没有消息时,最大等待时间
- 返回值 如果没有超时返回pdTRUE 超时则返回pdFALSE
本文参考 freertos官方文档 https://freertos.org/a00110.html
《安富莱 STM32-V6 开发板 FreeRTOS 教程》