新手理解RTOS嵌入式系统

本文介绍了FreeRTOS在嵌入式系统中的应用,详细阐述了任务的划分与调度、时间管理和内存管理机制,包括任务的优先级、时间分片、滴答中断、内存分配方式以及低功耗模式等内容。
摘要由CSDN通过智能技术生成

新手理解RTOS嵌入式系统

一句话定义FreeRTOS:是实现任务的工具。这意味着使用rtos的程序员,需要把一个具体的“业务”分解成“多个任务”,然后使用rtos实现这“多个任务”就可以了。

对于RTOS来讲,它是如何实现“任务”的?

  • 每个任务都有一小片自己的栈空间,也就是一个自己的“小房子”,可以粗略地将这个“小房子”等同于任务(例如,你工作了一辈子,终于把房贷还完了,那是不是可以粗略地把这个“房子”看成你的一生)。空间性

对于使用RTOS的工程师来讲,如何处理“多个任务”之间的关系?

  • 多个任务之间的“通风报信”,通信:队列,消息邮箱
  • 多个任务之间的“琴瑟和鸣”,同步:信号量,事件组
  • 多个任务对同一资源的使用:信号量,互斥量

对于RTOS来讲,如何处理“多个任务”之间的关系?

  • 任务调度机制,解决“CPU运行时间”的分配问题。时间性

RTOS中,真正的“时间性”和“空间性”架构

  • 内存管理机制
  • 时间管理机制。时间管理是任务调度的基础,或者前身,是比任务调度机制更加原初的机制。
  • 相较于空间性,时间性更加的复杂,所以对时间的管理机制更加的多。关于时间性与空间性:空间承载了时间的运行,时间反过来将空间作为“工具”来使用。

内存管理

1. 静态内存分配

在静态内存分配中,内存在编译时就被分配好,并且在整个程序运行期间都不会改变。这种分配方式适用于任务和队列的数量在编译时就已知,且不会动态创建或删除的情况。

  • 任务的静态分配:可以在任务定义中指定堆栈大小和任务控制块(TCB)的内存位置。
  • 队列的静态分配:可以在创建队列时指定队列的内存位置和大小。

静态内存分配的优点是无需运行时内存管理开销,执行速度快。但缺点是缺乏灵活性,一旦定义,内存大小和数量就无法改变。

2. 动态内存分配

动态内存分配允许在程序运行时根据需要分配和释放内存。FreeRTOS提供了几种动态内存管理的方法:

  • 使用c标准库:可以在FreeRTOS中使用C标准库的内存管理函数,如malloc()free()。但是,这种方法可能会引入较大的运行时开销,并且可能不适合实时系统的要求。
  • 使用FreeRTOS的动态内存管理器:FreeRTOS提供了自己的动态内存管理器,可以通过pvPortMalloc()vPortFree()函数来分配和释放内存。这个管理器专为FreeRTOS设计,通常比标准库函数更高效、更适用于实时系统。
  • 使用固定大小的内存池:通过xHeapCreate()函数创建一个固定大小的内存池,然后使用pvPortMalloc()vPortFree()在这个内存池中分配和释放内存。这种方式可以减少内存碎片,提高内存分配的效率。

3. 内存碎片问题

在动态内存管理中,内存碎片是一个常见问题。随着时间的推移,频繁的内存分配和释放可能导致内存碎片化,从而影响内存的利用率。FreeRTOS提供了几种减少内存碎片的方法:

  • 合并相邻的空闲块:FreeRTOS的内存管理器会尝试合并相邻的空闲内存块,以减少碎片。
  • 使用内存池:通过创建固定大小的内存池,可以减少碎片的产生,因为内存池中的内存块大小是固定的。

时间管理

1. 滴答(Tick)中断

FreeRTOS使用滴答中断作为时间管理的基础。滴答中断通常由硬件定时器产生,配置为固定的频率(例如1ms或10ms)。每次滴答中断发生时,操作系统会执行一些基本的维护任务,如更新系统的时间基准、检查超时的任务、处理软件定时器等。

2. 系统时间基准

FreeRTOS维护一个系统时间基准,通常称为xTaskGetTickCount()。该函数返回自系统启动以来的滴答数。这个时间基准可以用于任务间的同步、超时检测以及记录经过的时间等。

3. 任务超时处理

在创建任务时,可以为任务设置一个超时时间。如果任务因为等待事件(如信号量、互斥锁等)而挂起,它会在超时时间到达后被自动唤醒。这个机制确保了任务在特定时间内得不到所需资源时能够继续执行或进行错误处理。

4. 软件定时器

FreeRTOS提供了软件定时器功能,允许创建定时器来执行周期性或一次性的任务。软件定时器可以是:

  • 一次性定时器:在设置的时间到达后执行一次回调函数。
  • 周期性定时器:每隔设定的时间间隔执行一次回调函数。

软件定时器通过xTimerCreate()函数创建,并通过xTimerStart()函数启动。定时器的回调函数会在设定的时间到达时被调用。

5. 延时函数

FreeRTOS提供了vTaskDelay()函数,允许任务主动挂起一段时间。这个延时是精确的,并且不会消耗CPU资源。在延时期间,如果任务的超时时间到达,它会立即被唤醒。

6. 时间管理函数

FreeRTOS提供了一系列的时间管理函数,如:

  • xTaskGetTickCount():获取系统启动以来的滴答数。
  • xTaskGetTickCountFromISR():从中断服务例程中获取滴答数。
  • vTaskDelayUntil():使任务延迟直到达到某个滴答值。
  • xTimerIsTimerActive():检查定时器是否正在运行。
  • xTimerStop():停止定时器。
  • xTimerReset():重置定时器,使其立即到期。

7. 低功耗模式

FreeRTOS支持低功耗模式,通过configUSE_TICKLESS_IDLE配置项启用。在这种模式下,当没有任务运行且没有等待的事件时,系统会进入低功耗状态。在这种状态下,CPU的时钟频率可以降低,从而减少能耗。


任务调度

FreeRTOS的任务调度机制通过优先级、时间分片和任务状态管理来实现

1.调度策略

FreeRTOS采用抢占式调度策略,这意味着高优先级的任务可以中断当前正在执行的低优先级任务。一旦高优先级任务准备就绪,调度器会立即抢占CPU,使得高优先级任务开始执行。这种策略确保了紧急或重要的任务能够得到及时处理。

2.任务优先级

每个任务都有一个优先级,优先级是任务属性的一部分,可以在任务创建时通过uxTaskPriority参数设置。FreeRTOS中的优先级是数值越大表示优先级越高。例如,如果任务A的优先级高于任务B,当任务B正在执行时,任务A变为可运行状态,调度器会立即切换到任务A。

3.任务状态

任务在FreeRTOS中有几种状态,包括:

  1. 就绪(Ready):任务已经准备好执行,等待CPU分配时间。
  2. 运行(Running):任务当前正在CPU上执行。
  3. 挂起(Suspended):任务因为某种原因被挂起,不会占用CPU时间,但仍然保留在就绪列表中。
  4. 延迟(Blocked):任务因为等待事件(如信号量、互斥锁等)而被阻塞,直到事件得到满足。

4.时间分片

FreeRTOS使用时间分片(Time Slice)或称为时间片轮转(Round-robin)策略来调度相同优先级的任务。每个任务被分配一个固定的时间片,当任务的时间片用尽时,调度器会切换到下一个同优先级的任务。这样可以保证同优先级的任务能够公平地共享CPU时间。

5.任务切换

任务切换是由调度器自动进行的。当一个高优先级任务准备就绪或者当前任务的时间片用尽时,调度器会执行任务切换。任务切换涉及到保存当前任务的状态(如寄存器值)和加载下一个任务的状态。

6.调度器使能与禁止

在某些情况下,可能需要临时禁止调度器,例如在中断服务例程中修改共享资源时。可以使用taskENTER_CRITICAL()taskEXIT_CRITICAL()宏来禁止和使能调度器。在禁止调度器的代码块中,任务切换不会发生,以保证代码的原子性。

7.调度器的强制唤醒

在某些情况下,可能需要强制唤醒等待的高优先级任务。可以使用xTaskResumeAll()函数来唤醒所有挂起的任务,或者使用xTaskResumeFromISR()函数从中断服务例程中唤醒任务。

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏夜2029

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值