教程https://www.bilibili.com/video/BV1nvqSBAELQSTM32F103 Cube MX FreeRTOS 面向对象项目框架可维护性高复用性高内聚低耦合软件框架非常重要。FreeRTOS任务调度时间片轮转调度抢占式调度对相同优先级的任务FreeRTOs采用时间片轮转调度为每个任务分配1个单位时间片顺序执行。对不同优先级的任务FreeRToS采用抢占式调度高优先级任务优先执行并且高优先级会打断低优先级任务。任务分为就绪态、运行态、阻塞态和挂起态调度器通过任务状态和优先级进行调度其本质是PendsV 中断如何撑爆FreeRTOS的堆栈总堆Total Heap和任务栈Task Stack总堆FreeRTOS 在程序编译时会分配一块连续的内存作为总堆。其本质是一个数组。可以使用pvPortMalloc()、vPortFree()函数从中申请和释放内存。FreeRTOS 使用heap_1.c~heap_5.c来管理堆的分配。任务栈每个任务独立拥有用于存放任务内的信息。当被打断或调用子函数时需要保存现场就把当前的任务信息压入栈中下次恢复时再从栈中取出。压栈和出栈由系统自动操作不需要手动管理。动态分配方式下FreeRTOS 会从总堆中申请一块内存作为任务栈静态分配方式下用户可以指定一块内存作为任务栈。FreeRTOS任务创建参数如何查询当前任务堆栈使用情况如何撑爆任务栈1 定义大数组任务切换时需要保存现场当前信息压入任务栈2 嵌套调用函数调用函数时也需要保存现场当前信息压入任务栈优化按需分配任务栈监控水位留足余量减少任务内的临时变量减少函数嵌套嵌套都是有开销的总堆空间不够会发生什么消息队列思考任务之间如何传递消息消息队列Queue消息队列是 FreeRTOS 提供的一种通信机制可以方便地实现任务与任务、中断与任务之间的通信。发送方只需要将信息发送到消息队列中系统自动转交给接收方。优势① 拷贝传递非引用传递保证信息完整不会出现数据只写一半的情况② 支持异步通知发送不需要等待接收代码解耦③ 支持一对多、多对一、多对多通信④ 系统级支持可以实现阻塞任务操作劣势① 依赖系统调用时间和空间开销大portmax_delay指的是队列满的时候一直等待直到有了空位再写进去。先进先出实验总结任务之间、中断与任务间可以使用全局变量和队列进行信息传递消息队列可以方便地阻塞任务但是时间和空间开销比全局变量大消息队列在任务内和中断内要使用不同的函数为节省消息队列开销可以在保证数据完整性的情况下传递指针队列大小要依据实际情况选择太小会丢数据太大会浪费内存。信号量和优先级翻转问题非互斥信号量分类1 二值信号量本质是只有队列长度为 1项大小为 0空元素的消息队列故队列只有【空 (0)】和【满 (1)】两种状态【空】表示事件还未发生【满】表示事件已经发生。信号量【满 (1)】时执行获取Take操作成功后信号量值为 0【空 (0)】执行释放Give操作无效。信号量【空 (0)】时执行释放Give操作成功后信号量值为 1【满 (1)】执行获取Take操作会阻塞。2 计数信号量本质是队列长度为计数最大值uxMaxCount的队列内部最多有 uxMaxCount 个长度为 0 的元素空元素。每次获取Take信号量则信号量值减 1最小值为 0。每次释放Give信号量则信号量值加 1最大值为 uxMaxCount。3 适用场景二值信号量适用于同步如信号采集。计数信号量适用于资源管理如图书馆剩余座位。4 实验使用二值信号量实现定时器中断控制板载 LED 闪烁。使用计数信号量实现每按一个按键亮一个灯每松开一个按键灭一个灯。优先级翻转1 互斥锁本质是一种支持优先级继承的二值信号量。优先级继承机制当高优先级任务尝试获取互斥信号量时若该信号量已被低优先级任务占用FreeRTOS 会将占用互斥信号量的任务优先级提升至当前高优先级任务的优先级。机制效果优先级继承无法完全消除优先级翻转现象但能降低已发生的优先级反转带来的影响提升系统响应速度。使用限制互斥信号量不可在中断中使用因为中断无任务优先级也不会被信号量阻塞。2 递归互斥锁本质是一种特殊的互斥锁同样支持优先级继承且同样不可在中断中使用。核心特性允许同一个任务多次获取该锁对应的任务获取锁的次数必须与释放锁的次数完全一致否则会导致资源无法释放。信号量核心总结 本质特性信号量的本质是消息队列但其中的元素均为空元素不占用实际存储空间。核心用途同步协调任务的执行时机解决 “什么时候执行” 的问题互斥保护共享资源的访问权限解决 “谁能执行” 的问题优先级翻转问题非互斥类信号量如二值信号量、计数信号量可能引发优先级翻转现象互斥信号量无法完全避免优先级翻转但可通过优先级继承机制降低该现象带来的负面影响提升系统响应速度
FreeRTOS工程项目实践
教程https://www.bilibili.com/video/BV1nvqSBAELQSTM32F103 Cube MX FreeRTOS 面向对象项目框架可维护性高复用性高内聚低耦合软件框架非常重要。FreeRTOS任务调度时间片轮转调度抢占式调度对相同优先级的任务FreeRTOs采用时间片轮转调度为每个任务分配1个单位时间片顺序执行。对不同优先级的任务FreeRToS采用抢占式调度高优先级任务优先执行并且高优先级会打断低优先级任务。任务分为就绪态、运行态、阻塞态和挂起态调度器通过任务状态和优先级进行调度其本质是PendsV 中断如何撑爆FreeRTOS的堆栈总堆Total Heap和任务栈Task Stack总堆FreeRTOS 在程序编译时会分配一块连续的内存作为总堆。其本质是一个数组。可以使用pvPortMalloc()、vPortFree()函数从中申请和释放内存。FreeRTOS 使用heap_1.c~heap_5.c来管理堆的分配。任务栈每个任务独立拥有用于存放任务内的信息。当被打断或调用子函数时需要保存现场就把当前的任务信息压入栈中下次恢复时再从栈中取出。压栈和出栈由系统自动操作不需要手动管理。动态分配方式下FreeRTOS 会从总堆中申请一块内存作为任务栈静态分配方式下用户可以指定一块内存作为任务栈。FreeRTOS任务创建参数如何查询当前任务堆栈使用情况如何撑爆任务栈1 定义大数组任务切换时需要保存现场当前信息压入任务栈2 嵌套调用函数调用函数时也需要保存现场当前信息压入任务栈优化按需分配任务栈监控水位留足余量减少任务内的临时变量减少函数嵌套嵌套都是有开销的总堆空间不够会发生什么消息队列思考任务之间如何传递消息消息队列Queue消息队列是 FreeRTOS 提供的一种通信机制可以方便地实现任务与任务、中断与任务之间的通信。发送方只需要将信息发送到消息队列中系统自动转交给接收方。优势① 拷贝传递非引用传递保证信息完整不会出现数据只写一半的情况② 支持异步通知发送不需要等待接收代码解耦③ 支持一对多、多对一、多对多通信④ 系统级支持可以实现阻塞任务操作劣势① 依赖系统调用时间和空间开销大portmax_delay指的是队列满的时候一直等待直到有了空位再写进去。先进先出实验总结任务之间、中断与任务间可以使用全局变量和队列进行信息传递消息队列可以方便地阻塞任务但是时间和空间开销比全局变量大消息队列在任务内和中断内要使用不同的函数为节省消息队列开销可以在保证数据完整性的情况下传递指针队列大小要依据实际情况选择太小会丢数据太大会浪费内存。信号量和优先级翻转问题非互斥信号量分类1 二值信号量本质是只有队列长度为 1项大小为 0空元素的消息队列故队列只有【空 (0)】和【满 (1)】两种状态【空】表示事件还未发生【满】表示事件已经发生。信号量【满 (1)】时执行获取Take操作成功后信号量值为 0【空 (0)】执行释放Give操作无效。信号量【空 (0)】时执行释放Give操作成功后信号量值为 1【满 (1)】执行获取Take操作会阻塞。2 计数信号量本质是队列长度为计数最大值uxMaxCount的队列内部最多有 uxMaxCount 个长度为 0 的元素空元素。每次获取Take信号量则信号量值减 1最小值为 0。每次释放Give信号量则信号量值加 1最大值为 uxMaxCount。3 适用场景二值信号量适用于同步如信号采集。计数信号量适用于资源管理如图书馆剩余座位。4 实验使用二值信号量实现定时器中断控制板载 LED 闪烁。使用计数信号量实现每按一个按键亮一个灯每松开一个按键灭一个灯。优先级翻转1 互斥锁本质是一种支持优先级继承的二值信号量。优先级继承机制当高优先级任务尝试获取互斥信号量时若该信号量已被低优先级任务占用FreeRTOS 会将占用互斥信号量的任务优先级提升至当前高优先级任务的优先级。机制效果优先级继承无法完全消除优先级翻转现象但能降低已发生的优先级反转带来的影响提升系统响应速度。使用限制互斥信号量不可在中断中使用因为中断无任务优先级也不会被信号量阻塞。2 递归互斥锁本质是一种特殊的互斥锁同样支持优先级继承且同样不可在中断中使用。核心特性允许同一个任务多次获取该锁对应的任务获取锁的次数必须与释放锁的次数完全一致否则会导致资源无法释放。信号量核心总结 本质特性信号量的本质是消息队列但其中的元素均为空元素不占用实际存储空间。核心用途同步协调任务的执行时机解决 “什么时候执行” 的问题互斥保护共享资源的访问权限解决 “谁能执行” 的问题优先级翻转问题非互斥类信号量如二值信号量、计数信号量可能引发优先级翻转现象互斥信号量无法完全避免优先级翻转但可通过优先级继承机制降低该现象带来的负面影响提升系统响应速度