完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本章节为大家讲解ThreadX中断优先级配置,此章节非常重要,初学者经常在这里犯迷糊。对于初学者来说,本章节务必要整明白。
11.1 初学者重要提示
NVIC的全称是Nested vectored interrupt controller,即嵌套向量中断控制器。 对于M3和M4内核的MCU,每个中断的优先级都是用寄存器中的8位来设置的。8位的话就可以设置2^8 = 256级中断,实际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如ST的STM32F1xx,F4xx,H7xx只使用了这个8位中的高四位[7:4],低四位取零,这样2^4=16,只能表示16级中断嵌套。 对于这个NVIC,有个重要的知识点就是优先级分组,抢占优先级和子优先级,下面就以STM32为例进行介绍,STM32F1xx,F4xx,H7xx都是只使用了这个8位寄存器的高四位[7:4]。 从上面的表格可以看出,STM32支持5种优先级分组,系统上电复位后,默认使用的是优先级分组0,也就是没有抢占式优先级,只有子优先级,关于这个抢占优先级和这个子优先级有几点一定要说清楚。
掌握了这些基础知识基本就够用了。另外特别注意一点,配置抢占优先级和子优先级,他们合并成的4bit数字的数值越小,优先级越高,这一点千万不要搞错了,下面通过11.2小节举一个实例。 11.3 使用ThreadX时如何配置外设NVIC 强烈推荐用户将STM32的NVIC优先级分组设置为4,即:这样中断优先级的管理将非常方便。此函数在程序优先调用:(注意:一旦初始化好NVIC的优先级分组后,切不可以在应用中再次更改。) 设置NVIC的优先级分组为4表示支持0-15级抢占优先级(注意,0-15级是16个级别,包含0级),不支持子优先级。反映在STM32的HAL配置上就是如下: /* * 函 数 名: System_Init * 功能说明: 系统初始化,主要是MPU,Cache和系统时钟配置 * 形 参:无 * 返 回 值: 无 */ void System_Init(void) { /* 配置MPU */ MPU_Config(); /* 使能L1 Cache */ CPU_CACHE_Enable(); /* STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HIS时钟: - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。 - 设置NVIC优先级分组为4。 */ HAL_Init(); /* 配置系统时钟到400MHz - 切换使用HSE。 - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。 */ SystemClock_Config(); /* Event Recorder: - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。 - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章 */ #if Enable_EventRecorder == 1 /* 初始化EventRecorder并开启 */ EventRecorderInitialize(EventRecordAll, 1U); EventRecorderStart(); #endif #if Enable_RTTViewer == 1 /* 配置通道0,上行配置*/ SEGGER_RTT_ConfigUpBuffer(0, “RTTUP”, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP); /* 配置通道0,下行配置*/ SEGGER_RTT_ConfigDownBuffer(0, “RTTDOWN”, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP); #endif } 在这里继续强调下这一点,在NVIC分组为4的情况下,抢占优先级可配置范围是0-15,那么数值越小,抢占优先级的级别越高,即0代表最高优先级,15代表最低优先级。 11.4 不受ThreadX管理中断的深入讨论 11.4.1 实现原理 讲解不受ThreadX管理的中断之前要说一个小知识点----中断延迟。中断延迟时间是衡量RTOS实时操作系统的一项重要指标,那什么又是中断延迟呢?从中断触发到执行中断服务程序的第一条指令这段时间就是中断延迟时间。 ThreadX内核源码中有多处开关全局中断的地方,这些开关全局中断会加大中断延迟时间。比如在源码的某个地方关闭了全局中断,但是此时有外部中断触发,这个中断的服务程序就需要等到再次开启全局中断后才可以得到执行。开关中断之间的时间越长,中断延迟时间就越大,这样极其影响系统的实时性。如果这是一个紧急的中断事件,得不到及时执行的话,后果是可想而知的。 针对这种情况,我们为ThreadX就专门做了一种新的开关中断实现机制。关闭中断时仅关闭受ThreadX管理的中断,不受ThreadX管理的中断不关闭,这些不受管理的中断都是高优先级的中断,用户可以在这些中断里面加入需要实时响应的程序。ThredX能够实现这种功能的奥秘就在于ThreadX开关中断使用的是寄存器basepri,而非官方默认配套使用的primask,详情请看下面整理的表格: 对寄存器basepri我们举一个例子,帮助大家理解,比我们配置寄存器basepri的数值为16,所有优先级数值大于等于16的中断都会被关闭,优先级数值小于16的中断不会被关闭。对寄存器basepri寄存器赋值0,那么被关闭的中断会被打开。这个就是ThreadX开关中断的实现方案。 11.4.2 实现代码(AC5,AC6,IAR和GCC均支持) 实现代码如下,大家仅需修改tx_port.h文件中的TX_DISABLE,TX_RESTORE和_tx_thread_system_return_inline实现为如下即可: #include "stm32h7xx_hal.h" #define ThreadX_MAX_INTERRUPT_PRIORITY (0x10) #define TX_INTERRUPT_SAVE_AREA uint32_t was_masked; #define TX_DISABLE was_masked = __get_BASEPRI(); __set_BASEPRI(ThreadX_MAX_INTERRUPT_PRIORITY); #define TX_RESTORE __set_BASEPRI(was_masked); #define _tx_thread_system_return _tx_thread_system_return_inline static void _tx_thread_system_return_inline(void) { unsigned int was_masked; /* Set PendSV to invoke ThreadX scheduler. */ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_IPSR() == 0) { was_masked = __get_BASEPRI(); __set_BASEPRI(0); __set_BASEPRI(was_masked); } } 注意:我们这里设置宏定义ThreadX_MAX_INTERRUPT_PRIORITY为0x10,表示调用函数TX_DISABLE关闭中断的时候,仅关闭抢占优先级1到15,抢占优先级0未不关闭(NVIC的优先级分组为4,STM32仅使用高4bit)。大家可以根据自己的情况做修改调整。 11.5 实验例程 配套例子: V7-3006_ThreadX BasePri Interrupt 实验目的:
1、共创建了如下几个任务,通过按下按键K1可以通过串口或者RTT打印任务堆栈使用情况 =================================================== OS CPU Usage = 1.94% =================================================== Prio StackSize CurStack MaxStack Taskname 2 4092 383 391 App Task Start 3 4092 543 659 App Msp Pro 4 4092 391 391 App Task UserIF 5 4092 543 659 App Task COM 30 1020 519 519 App Task STAT 31 1020 143 71 App Task IDLE 0 1020 391 391 System Timer Thread 串口软件可以使用SecureCRT或者H7-TOOL RTT查看打印信息。 App Task Start任务 :启动任务,这里用作BSP驱动包处理。 App Task MspPro任务 :消息处理,这里未使用。 App Task UserIF任务 :按键消息处理。 App Task COM任务 :这里用作LED闪烁。 App Task STAT任务 :统计任务 App Task IDLE任务 :空闲任务 System Timer Thread任务:系统定时器任务 2、 (1) 凡是用到printf函数的全部通过函数App_Printf实现。 (2) App_Printf函数做了信号量的互斥操作,解决资源共享问题。 3、默认上电是通过串口打印信息,如果使用RTT打印信息 (1) MDK AC5,MDK AC6或IAR通过使能bsp.h文件中的宏定义为1即可 #define Enable_RTTViewer 1 (2) Embedded Studio继续使用此宏定义为0, 因为Embedded Studio仅制作了调试状态RTT方式查看。 实验操作:
波特率 115200,数据位 8,奇偶校验位无,停止位 1 RTT打印信息方式(AC5,AC6和IAR): Embedded Studio仅支持调试状态RTT打印: 由于Embedded Studio不支持中文,所以中文部分显示乱码,不用管。 程序执行框图: 11.6 总结 本章节为大家讲解ThreadX中断优先级配置,特别是不受ThreadX管理中断的实现方案,望大家熟练掌握。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1646 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1566 浏览 1 评论
993 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
692 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1611 浏览 2 评论
1871浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
656浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
526浏览 3评论
543浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
515浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-27 06:00 , Processed in 0.840320 second(s), Total 48, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号