在阅读本文之前,有两个定义在FreeRTOSConfig.h中的宏,你必须先明白它们是什么意思,《FreeRTOS内核配置说明》一文中,讲解了这两个宏:

  • configKERNEL_INTERRUPT_PRIORITY
  • configMAX_SYSCALL_INTERRUPT_PRIORITY

FreeRTOS与Cortex-M内核可谓是绝配,以至于让移植和使用FreeRTOS都变得更简单起来。根据FreeRTOS官方反馈,在Cortex-M内核上使用FreeRTOS大多数的问题点是由不正确的优先级设置引起的。这个问题也是在意料之中的,因为尽管Cortex-M内核的中断模式是非常强大的,但对于那些使用传统中断优先级架构的工程师来说,Cortex-M内核中断机制也有点笨拙(或者是说使用比较繁琐),并且违反直觉(这个主要是因为Cortex-M中断优先级数值越大代表的优先级反而越小)。本章打算描述Cortex-M的中断优先级机制,并描述怎样结合RTOS内核使用。

说明:虽然Cortex-M内核的优先级方案看上去比较复杂,但每一个官方发布的FreeRTOS 接口包(在FreeRTOSV7.2.0\FreeRTOS\Source\portable文件夹中,一般为port.c)内都会有正确配置的演示例程,可以以此为参考。

1.有效优先级

1.1Cortex-M 硬件详述

首先需要清楚有效优先级的总数,这取决于微控制器制造商怎么使用Cortex内核。所以,并不是所有的Cortex-M内核微处理器都具有相同的中断优先级级别。

Cortex-M构架自身最多允许256级可编程优先级(优先级配置寄存器最多8位,所以优先级范围从0x00~0xFF),但是绝大多数微控制器制造商只是使用其中的一部分优先级。比如,TI Stellaris Cortex-M3和Cortex-M4微控制器使用优先级配置寄存器的3个位,能提供8级优先级。再比如,NXP LPC17xx Cortex-M3微控制器使用优先级配置寄存器的5个位,能提供32级优先级。

1.2应用到RTOS

RTOS中断嵌套方案将有效的中断优先级分成两组:一组可以通过RTOS临界区屏蔽,另一组不受RTOS影响,永远都是使能的。宏configMAX_SYSCALL_INTERRUPT_PRIORITY在FreeRTOSConfig.h中配置,定义两组中断优先级的边界。逻辑优先级高于此值的中断不受RTOS影响。最优值取决于微控制器使用的优先级配置寄存器的位数。

2.与数值相反的优先级值和逻辑优先级设置

2.1Cortex-M 硬件详述

有必要先解释一下优先级值和逻辑优先级:在Cortex-M内核中,假如有8级优先级,我们说优先级值是0~7,但数值最大的优先级7却代表着最低的逻辑优先级。很多使用传统传统中断优先级架构的工程师会觉得这样比较绕,违反直觉。以下内容提到的优先级要仔细区分是优先级数值还是逻辑优先级。

接下来需要清楚的是,在Cortex-M内核中,一个中断的优先级数值越低,逻辑优先级却越高。比如,中断优先级为2的中断可以抢占中断优先级为5的中断,但反过来就不行。换句话说,中断优先级2比中断优先级5的优先级更高。

这是Cortex-M内核最容易让人犯错之处,因为大多数的非Cortex-M内核微控制器的中断优先级表述是与之相反的。

2.2应用到 RTOS

以“FromISR”结尾的FreeRTOS函数是具有中断调用保护的(执行这些函数会进入临界区),但是就算是这些函数,也不可以被逻辑优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断服务函数调用。(宏configMAX_SYSCALL_INTERRUPT_PRIORITY定义在头文件FreeRTOSConfig.h中)。因此,任何使用RTOSAPI函数的中断服务例程的中断优先级数值大于等于configMAX_SYSCALL_INTERRUPT_PRIORITY宏的值。这样就能保证中断的逻辑优先级等于或低于configMAX_SYSCALL_INTERRUPT_PRIORITY。

Cortex中断默认情况下有一个数值为0的优先级。大多数情况下0代表最高级优先级。因此,绝对不可以在优先级为0的中断服务例程中调用RTOSAPI函数。

3.Cortex-M 内部优先级概述

3.1Cortex-M 硬件详述

Cortex-M内核的中断优先级寄存器是以最高位(MSB)对齐的。比如,如果使用了3位来表达优先级,则这3个位位于中断优先级寄存器的bit5、bit6、bit7位。剩余的bit0~bit4可以设置成任何值,但为了兼容,最好将他们设置成1.

Cortex-M优先级寄存器最多有8位,如果一个微控制器只使用了其中的3位,那么这3位是以最高位对齐的,见下图:

某微控制器只使用了优先级寄存器中的3位,下图展示了优先级数值5(二进制101B)是怎样在优先级寄存器中存储的。如果优先级寄存器中未使用的位置1,下图也展示了为什么数值5(二进制0000 0101B)可以看成数值191(二进制1011 1111)的。

某微控制器只使用了优先级寄存器中的4位,下图展示了优先级数值5(二进制101B)是怎样在优先级寄存器中存储的。如果优先级寄存器中未使用的位置1,下图也展示了为什么数值5(二进制0000 0101B)可以看成数值95(二进制0101 1111)的。

3.2应用到 RTOS

上文中已经描述,那些在中断服务例程中调用RTOS API函数的中断逻辑优先级必须低于或等于configMAX_SYSCALL_INTERRUPT_PRIORITY(低逻辑优先级意味着高优先级数值)。

CMSIS以及不同的微控制器供应商提供了可以设置某个中断优先级的库函数。一些库函数的参数使用最低位对齐,另一些库函数的参数可能使用最高位对齐,所以,使用时应该查阅库函数的应用手册进行正确设置。

可以在FreeRTOSConfig.h中设置宏configMAX_SYSCALL_INTERRUPT_PRIORITY和configKERNEL_INTERRUPT_PRIORITY的值。这两个宏需要根据Cortex-M内核自身的情况进行设置,要以最高有效位对齐。比如某微控制器使用中断优先级寄存器中的3位,设置configKERNEL_INTERRUPT_PRIORITY的值为5,则代码为:

#define     configKERNEL_INTERRUPT_PRIORITY  (5<<(8-3))

宏configKERNEL_INTERRUPT_PRIORITY指定RTOS内核使用的中断优先级,因为RTOS内核不可以抢占用户任务,因此这个宏一般设置为硬件支持的最小优先级。对于Cortex-M硬件,RTOS使用到硬件的PendSV和SysTick硬件中断,在函数xPortStartScheduler()中(该函数在port.c中,由启动调度器函数vTaskStartScheduler()调用),将PendSV和SysTick硬件中断优先级寄存器设置为宏configKERNEL_INTERRUPT_PRIORITY指定的值。

有关代码如下(位于port.c):

/*PendSV优先级设置寄存器地址为0xe000ed22SysTick优先级设置寄存器地址为0xe000ed23*/
#define portNVIC_SYSPRI2_REG     ( * ( ( volatile uint32_t * ) 0xe000ed20 ))#define portNVIC_PENDSV_PRI ( ( (uint32_t)configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI ( ( (uint32_t)configKERNEL_INTERRUPT_PRIORITY ) << 24UL )
/* …. */
/*确保PendSV 和SysTick为最低优先级中断 */
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |=portNVIC_SYSTICK_PRI;

4.临界区

4.1Cortex-M 硬件详述

RTOS内核使用Cortex-M内核的BASEPRI寄存器来实现临界区(注:BASEPRI为优先级屏蔽寄存器,优先级数值大于或等于该寄存器的中断都会被屏蔽,优先级数值越大,逻辑优先级越低,但是为零时不屏蔽任何中断)。这允许RTOS内核可以只屏蔽一部分中断,因此可以提供一个灵活的中断嵌套模式。

那些需要在中断调用时保护的API函数,FreeRTOS使用寄存器BASEPRI实现中断保护临界区。当进入临界区时,将寄存器BASEPRI的值设置成configMAX_SYSCALL_INTERRUPT_PRIORITY,当退出临界区时,将寄存器BASEPRI的值设置成0。很多Bug反馈都提到,当退出临界区时不应该将寄存器设置成0,应该恢复它之前的状态(之前的状态不一定是0)。但是Cortex-M NVIC决不会允许一个低优先级中断抢占当前正在执行的高优先级中断,不管BASEPRI寄存器中是什么值。与进入临界区前先保存BASEPRI的值,退出临界区再恢复的方法相比,退出临界区时将BASEPRI寄存器设置成0的方法可以获得更快的执行速度。

4.2应用到RTOS kernel

RTOS内核通过写configMAX_SYSCALL_INTERRUPT_PRIORITY的值到BASEPRI寄存器的方法创建临界区。中断优先级0(具有最高的逻辑优先级)不能被BASEPRI寄存器屏蔽,因此,configMAX_SYSCALL_INTERRUPT_PRIORITY绝不可以设置成0。

FreeRTOS系列第7篇---Cortex-M内核使用FreeRTOS特别注意事项相关推荐

  1. FreeRTOS系列第2篇---FreeRTOS入门指南

    FreeRTOS可以被移植到很多不同架构的处理器和编译器.每一个RTOS移植都附带一个已经配置好的演示例程,可以方便快速启动开发.更好的是,每个演示例程都附带一个说明网页,提供如何定位RTOS演示工程 ...

  2. FreeRTOS系列第1篇---为什么选择FreeRTOS?

    1.为什么学习RTOS? 作为基于ARM7.Cortex-M3硬件开发的嵌入式工程师,我一直反对使用RTOS.不仅因为不恰当的使用RTOS会给项目带来额外的稳定性风险,更重要的是我认为绝大多数基于AR ...

  3. FreeRTOS系列第19篇---FreeRTOS信号量

    来自:http://blog.csdn.net/zhzht19861011/article/details/50835613 本文介绍信号量的基础知识,详细源码分析见<FreeRTOS高级篇6- ...

  4. ARM® Cortex®-M内核单片机STM32家族介绍,覆盖STM32F、STM32H、STM32L全系列

     STM32是ARM®Cortex®-M内核单片机.目前提供10大产品线(F0, F1, F2, F3, F4, F7, H7, L0, L1, L4),超过700个型号.STM32产品广泛应用于 ...

  5. 32位ARM®Cortex®-M0+内核单片机 XL32F003系列MCU

    XL32F003系列微控制器采用高性能的32位ARM®Cortex®-M0+内核,宽电压工作范围的MCU.嵌入高达64 Kbytes flash和8 Kbytes SRAM存储器,最高工作频率32 M ...

  6. 重磅!兆易创新推出中国首款Cortex®-M7内核超高性能MCU GD32H737/757/759系列

    关注.星标公众号,精彩内容每日送达 来源:网络素材 中国北京(2023年5月11日)--业界领先的半导体器件供应商兆易创新GigaDevice (股票代码 603986) 今日宣布,正式推出中国首款基 ...

  7. i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核

    i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核 概述 i. MX6UltraLite作为i.MX6系列的扩展,一系列高性能.超高效的处理器 ...

  8. 32 位 ARM® Cortex®-M0+内核 单片机

    PY32F003 系列微控制器采用高性能的 32 位 ARM® Cortex®-M0+内核,宽电压工作范围的 MCU.嵌入高达 32Kbytes flash 和 4Kbytes SRAM 存储器,最高 ...

  9. CoreOS Fest 系列之第一篇:容器江湖

    本文讲的是CoreOS Fest 系列之第一篇:容器江湖,[编者的话] 这是总结 CoreOS Fest 大会的三篇文章之一,主要介绍了 CoreOS 公司与 Docker 公司之争,新成立的 app ...

最新文章

  1. ActionBar右边菜单按钮的添加
  2. 原生js实现ajax的文件异步提交功能、图片预览功能.实例
  3. 智能手环功能模块设计_基于STM32实现智能手环设计
  4. 修改 framework 代码的经验和踩过的坑
  5. Spring boot修改Servlet配置
  6. inventor扳手制作视频_安全的安全帽是怎么制作出来的?
  7. Jquery 获取 radio选中值
  8. aws rds 加密_AWS RDS SQL Server中的加密备份和还原
  9. cad工具箱详细讲解_cad学院派工具箱(cad绘图教程配解析)V20160804 最新版
  10. 硬件虚拟化检测工具:securable
  11. Excel如何从身份证号码中提取性别
  12. java mail 匿名_java开发邮件发送匿名
  13. linux 内功修炼之一 cpu
  14. 零基础入门编程神器!苹果的免费编程应用出了Mac版了
  15. 什么是SAAS平台?三分钟了解
  16. win7下硬盘安装Ubuntu 14.04
  17. 百菜不如白菜 娃娃菜更营养吗
  18. Truncate Table用法
  19. Editplus各个版本(最新版本是5.3)注册码下载
  20. bzoj1146整体二分+树链剖分+树状数组

热门文章

  1. php 通过 ip地址 进行城市定位
  2. 无法解压文件请重新启动计算机,解压文件是弹出来说4G以上的文件无法解压是怎么回事...
  3. win10iis服务器如何配置虚拟目录,win10系统iis6部署网站时配置虚拟目录的操作方法...
  4. 2021面试题(拿到offer版本)
  5. 编程语言进化史《禅与计算机程序设计艺术》 / 陈光剑
  6. WiFi标志消失,无线网卡驱动无法启动
  7. Windows系统用bat(cmd)实现卡机,死机,蓝屏
  8. 用gnome打造自己的ubuntu桌面
  9. 】最全内部审核、管理评审过关全集,细节齐了
  10. HTC VIVE 发射线