STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

一、FreeRTOS简介

FreeRTOS 是一个可裁剪、可剥夺型的多任务内核,而且没有任务数限制。FreeRTOS 提供了实时操作系统所需的所有功能,包括资源管理、同步、任务通信等。

FreeRTOS 是用 C 和汇编来写的,其中绝大部分都是用 C 语言编写的,只有极少数的与处理器密切相关的部分代码才是用汇编写的,FreeRTOS 结构简洁,可读性很强!最主要的是非常适合初次接触嵌入式实时操作系统学生、嵌入式系统开发人员和爱好者学习。

最新版本 V9.0.0(2016年),尽管现在 FreeRTOS 的版本已经更新到 V10.4.1 了,但是我们还是选择 V9.0.0,因为内核很稳定,并且网上资料很多,因为 V10.0.0 版本之后是亚马逊收购了FreeRTOS之后才出来的版本,主要添加了一些云端组件,一般采用 V9.0.0 版本足以。

  • FreeRTOS官网:http://www.freertos.org/
  • 代码托管网站:https://sourceforge.net/projects/freertos/files/FreeRTOS/

二、新建工程

1. 打开 STM32CubeMX 软件,点击“新建工程”

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

3. 配置时钟
RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

4. 配置调试模式
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器
SYS 设置,选择 Debug 为 Serial Wire

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

在基于STM32 HAL的项目中,一般需要维护的 “时基” 主要有2个:

  1. HAL的时基,SYS Timebase Source
  2. OS的时基(仅在使用OS的情况下才考虑)

而这些 “时基” 该去如何维护,主要分为两种情况考虑:

  • 裸机运行
    可以通过 (滴答定时器)或 ()定时器 的方式来维护 ,也就是HAL库中的 ,这是HAL库中维护的一个全局变量。在裸机运行的情况下,我们一般选择默认的 (滴答定时器) 方式即可,也就是直接放在 中断服务函数中来维护。

  • 带OS运行
    前面提到的 是STM32的HAL库中的新增部分,主要用于实现 以及作为各种 timeout 的时钟基准。

    在使用了OS(操作系统)之后,OS的运行也需要一个时钟基准(简称“时基”),来对任务和时间等进行管理。而OS的这个 时基 一般也都是通过 (滴答定时器) 来维护的,这时就需要考虑 “HAL的时基” 和 “OS的时基” 是否要共用 (滴答定时器) 了。

    如果共用SysTick,当我们在CubeMX中选择启用FreeRTOS之后,在生成代码时,CubeMX一定会报如下提示:

    STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

    STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
    • Queue Name: 队列名称
    • Queue Size: 队列能够存储的最大单元数目,即队列深度
    • Queue Size: 队列中数据单元的长度,以字节为单位
    • Allocation: 分配方式: 动态内存创建
    • Buffer Name: 缓冲区名称
    • Buffer Size: 缓冲区大小
    • Conrol Block Name: 控制块名称

    4.3 创建任务Task

    我们创建两个任务,一个消息接收任务,一个消息发送任务。

    STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
    • Task Name: 任务名称
    • Priority: 优先级,在 FreeRTOS 中,数值越大优先级越高,0 代表最低优先级
    • Stack Size (Words): 堆栈大小,单位为字,在32位处理器(STM32),一个字等于4字节,如果传入512那么任务大小为512*4字节
    • Entry Function: 入口函数
    • Code Generation Option: 代码生成选项
    • Parameter: 任务入口函数形参,不用的时候配置为0或NULL即可
    • Allocation: 分配方式: 动态内存创建
    • Buffer Name: 缓冲区名称
    • Conrol Block Name: 控制块名称

    4.4 创建二值信号量Binary Semaphore

    在 进行配置。

    STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
    在右边图中找到按键对应引脚,选择 。
    这里的 是指挂载在中断线几上,如 GPIO_EXTI0 就是挂载在中断线0上。
    STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
    配置
    中断优先级分组规则 默认为4个比特位,一般情况下不改。
    勾选刚刚配置的外部中断线0和13,并配置抢占优先级 和响应优先级 。在 FreeRTOS 中,优先级最低为 。

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
选择应用的 IDE 开发环境 MDK-ARM V5
STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
点击 GENERATE CODE 生成代码
STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
  • 在执行中断服务例程的过程中,如果有更高优先级别的中断源触发中断,由于当前处于中断处理上下文环境中,根据不同的处理器构架可能有不同的处理方式,比如新的中断等待挂起直到当前中断处理离开后再行响应;或新的高优先级中断打断当前中断处理过程,而去直接响应这个更高优先级的新中断源。后面这种情况,称之为中断嵌套。在硬实时环境中,前一种情况是不允许发生的,不能使响应中断的时间尽量的短。而在软件处理(软实时环境)上,FreeRTOS 允许中断嵌套,即在一个中断服务例程期间,处理器可以响应另外一个优先级更高的中断。

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)

FreeRTOS 在 Cortex-M 系列处理器上也遵循与裸机中断一致的方法,当用户需要使用自定义的中断服务例程时,只需要定义相同名称的函数覆盖弱化符号即可。所以,FreeRTOS 在 Cortex-M 系列处理器的中断控制其实与裸机没什么差别。

8.4 FreeRTOS开关中断

FreeRTOS开关中断函数为portENABLE_INTERRUPTS()和portDISABLE_INTERRUPTS(),这两个函数其实是宏定义,在portmacro.h中有定义,如下:

函数vPortBASEPRI()传递了一个0,这就对应了上面说到的,开启中断是将0写入BASEPRI寄存器。

8.5 临界区

STM32CubeMX学习笔记(36)——FreeRTOS实时操作系统使用(中断管理)
CMSIS-RTOS没有临界区,但FreeRTOS与临界段代码保护有关的函数有4个:、
和、、,这四个函数其实是宏定义,在task.h文件中有定义。这四个函数的区别是前两个是任务级的临界段代码保护,后两个是中断级的临界段代码保护。所以必要时要是加上。

8.5.1 任务级临界段代码保护

taskENTER_CRITICAL()和taskEXIT_CRITICAL()是任务级的临界代码保护,一个是进入临界段,一个是退出临界段,这两个函数是成对使用的,这函数的定义如下:

而portENTER_CRITICAL()和portEXIT_CRITICAL()也是宏定义,在文件 portmacro.h中有定义。
任务级临界代码保护使用方法如下:

当进入临界区时,中断被屏蔽,临界区代码无法被打断,只有当所有的临界段代码都退出以后才会使能中断!
注:当进入临界区时,优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断得不到及响应,所以临界区代码一定要精简。

8.5.2 中断级临界段代码保护

函数taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()中断级别临界段代码保护,是用在中断服务程序中的,而且这个中断的优先级一定要低于configMAX_SYSCALL_INTERRUPT_PRIORITY。这两个函数在文件task.h中有如下定义:

中断级临界代码保护使用方法如下:

来源:Leung_ManWah

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年3月4日
下一篇 2022年3月4日

相关推荐