精华内容
下载资源
问答
  • DSP中断优先级的设置

    2020-08-19 00:34:29
    原以为2812中断不能设置优先级。实际上硬件上优先级是做好的。但软件上有办法来设置优先级。请往下看
  • 包含五个中断源,两级中断优先级,优先级可编程设置,通过IP进行设置:  51单片机中断优先级的设置方法解析  PX0(IP.0),外部中断0优先级设定位;  PT0(IP.1),定时/计数器T0优先级设定位;...
  • 说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。
  • 中断系统是整个计算机系统必不可少的重要组成部分。利用中断屏蔽技术修改中断优先级
  • STM32中断优先级详细讲解,还有简单的例子。综述,有限级判断,优先级分组等。
  • 说最基本的,老的51单片机(80C51系列)有5个中断源,2个优先级,可以实现二级中断服务嵌套。现在很多扩展的51单片机已经有4个优先级(或更多)和更多的中断源了。
  • 中断优先级

    千次阅读 2019-05-12 16:57:34
    中断优先级 文章参考:https://blog.csdn.net/huangtonggao/article/details/6441876 结论: 1)抢占优先级越小,优先级越高;相同抢占优先级的中断不能嵌套; 2)相同抢占优先级N个中断发生时,响应优先级越小的...

    中断优先级

    文章参考:https://blog.csdn.net/huangtonggao/article/details/6441876

    结论:
    1)抢占优先级越小,优先级越高;相同抢占优先级的中断不能嵌套;
    2)相同抢占优先级N个中断发生时,响应优先级越小的中断首先执行(不能嵌套),如果响应优先级也均相同,则根据各中断对应向量表的位置来确定,向量表中越靠前的中断先响应。

    STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作’亚优先级’或’副优先级’,每个中断源都需要被指定这两种优先级。

    具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。

    当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理哪一个。

    既然每个中断源都需要被指定这两种优先级,就需要有相应的寄存器位记录每个中断的优先级;在Cortex-M3中定义了8个比特位用于设置中断源的优先级,这8个比特位可以有8种分配方式,如下:

    所有8位用于指定响应优先级
    最高1位用于指定抢占式优先级,最低7位用于指定响应优先级
    最高2位用于指定抢占式优先级,最低6位用于指定响应优先级
    最高3位用于指定抢占式优先级,最低5位用于指定响应优先级
    最高4位用于指定抢占式优先级,最低4位用于指定响应优先级
    最高5位用于指定抢占式优先级,最低3位用于指定响应优先级
    最高6位用于指定抢占式优先级,最低2位用于指定响应优先级
    最高7位用于指定抢占式优先级,最低1位用于指定响应优先级

    这就是优先级分组的概念。

    **Cortex-M3允许具有较少中断源时使用较少的寄存器位指定中断源的优先级,因此STM32把指定中断优先级的寄存器位减少到4位,这4个寄存器位的分组方式如下:
    第0组:所有4位用于指定响应优先级

    第1组:最高1位用于指定抢占式优先级,最低3位用于指定响应优先级
    第2组:最高2位用于指定抢占式优先级,最低2位用于指定响应优先级
    第3组:最高3位用于指定抢占式优先级,最低1位用于指定响应优先级
    第4组:所有4位用于指定抢占式优先级
    

    可以通过调用STM32的固件库中的函数NVIC_PriorityGroupConfig()选择使用哪种优先级分组方式,这个函数的参数有下列5种:

    NVIC_PriorityGroup_0 => 选择第0组
    NVIC_PriorityGroup_1 => 选择第1组
    NVIC_PriorityGroup_2 => 选择第2组
    NVIC_PriorityGroup_3 => 选择第3组
    NVIC_PriorityGroup_4 => 选择第4组
    

    接下来就是指定中断源的优先级,下面以一个简单的例子说明如何指定中断源的抢占式优先级和响应优先级:

    // 选择使用优先级分组第1组
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    // 使能EXTI0中断
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 指定抢占式优先级别1
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别0
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    // 使能EXTI9_5中断
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);**
    

    要注意的几点是:

    1)如果指定的抢占式优先级别或响应优先级别超出了选定的优先级分组所限定的范围,将可能得到意想不到的结果;

    2)抢占式优先级别相同的中断源之间没有嵌套关系;

    3)如果某个中断源被指定为某个抢占式优先级别,又没有其它中断源处于同一个抢占式优先级别,则可以为这个中断源指定任意有效的响应优先级别。

    下面是一个牛人的理解:

    绕来绕去终于大概明白了。

    STM32有43个channel的settable的中断源;AIRC(Application Interrupt and Reset Register)寄存器中有用于指定优先级的4 bits。这4个bits用于分配preemption优先级和sub优先级,在STM32的固件库中定义如下

    /* Preemption Priority Group -------------------------------------------------*/
    #define NVIC_PriorityGroup_0          ((u32)0x700) /* 0 bits for pre-emption priority
                                                          4 bits for subpriority */
    #define NVIC_PriorityGroup_1          ((u32)0x600) /* 1 bits for pre-emption priority
                                                          3 bits for subpriority */
    #define NVIC_PriorityGroup_2          ((u32)0x500) /* 2 bits for pre-emption priority
                                                          2 bits for subpriority */
    #define NVIC_PriorityGroup_3          ((u32)0x400) /* 3 bits for pre-emption priority
                                                          1 bits for subpriority */
    #define NVIC_PriorityGroup_4          ((u32)0x300) /* 4 bits for pre-emption priority
                                                          0 bits for subpriority */
    

    形象化的理解是:

    你是上帝,
    造了43个人,这么多人要分社会阶级和社会阶层了;
    因为“阶级”的词性比较重;"阶层"比较中性,
    所以preemption优先级->阶级;每个阶级内部,有一些阶层,sub优先级->阶层;

    如果按照NVIC_PriorityGroup_4这么分,就分为了16个阶级(1个阶层就是1个preemption优先级),0个阶层;高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和15级嵌套。
    每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级8”,则

    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 8; // 指定抢占式优先级别,可取0-15
    

    另外,在同一阶级内部,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
    还有,如果他们两个同时想做事,因为没有阶层,那么就根据Vector table中的物理排序,让排名靠前的人去做;

    又有1个人SPI1_IRQChannel,设定如下
    NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 指定抢占式优先级别,可取0-15

    SPI1_IRQChannel的阶级高,EXTI0_IRQChannel做事的时候可以打断(嵌套)。

    如果按照NVIC_PriorityGroup_3这么分,就分为了8个阶级(1个阶级是1个preemption优先级),每个阶级内有2个阶层(sub优先级);高阶级的人,可以打断低阶级的正在做事的人(嵌套),最多可以完成1个中断和7级嵌套。

    每个阶级(每个preemption优先级),你来指定这43人中,谁进入该阶级;一个人叫EXTI0_IRQChannel,你指定他进入“阶级3”,则:
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别,可取0-7
    还需要指定他的阶层:
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 指定响应优先级别,可取0-1

    另有1个人叫EXTI9_5_IRQChannel,他的阶级和阶层设定如下
    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 指定抢占式优先级别,可取0-7
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别

    那么这两个人是同一阶级的兄弟,一个人在做事的时候,另外一个人不能打断他;(preemption优先级别相同的中断源之间没有嵌套关系)
    如果他们两个同时想做事,因为前者的阶层高,所以前者优先。

    还有一个人叫USART1_IRQChannel,他的阶级和阶层设定如下
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 指定抢占式优先级别,可取0-7
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 指定响应优先级别

    USART1_IRQChannel的优先级最高,当前面两个人做事的时候,他都可以打断(嵌套)。

    其他的类推。

    展开全文
  • 最近在使用FreeRTOS的时候,突然发现程序在运行了几分钟之后所有的任务都不再调用了,只有几个中断能正常使用,看来是系统挂掉了,连续测试了几次想找出问题,可是这个真的有点不知所措。
  • 1.理解AT89C51单片机中断优先级和优先权。 2.用PROTEUS设计、仿真基于AT89C51单片机的中断优先级实验。 3.掌握中断编程。 优先级实验
  • STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级中断可以在具有低抢占式优先级的...
  • 实现控制和控制分别由特殊功能寄存器区中的中断允许寄存器IE和中断优先级寄存器IP来实现的。下面介绍这两个特殊功能寄存器。 中断允许寄存器IE 的CPU对各中断源的开放或屏蔽,是由片内的中断允许寄存器IE控制的。...
  • STM32-中断优先级管理NVIC 1.NVIC中断优先级分组 NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器。STM32F中文参考手册中搜索向量表可以找到相应的中断说明。 CM4/CM7 内核支持256个中断,...

    STM32-中断优先级管理NVIC

    1.NVIC中断优先级分组

    NVIC的全称是Nested vectoredinterrupt controller,即嵌套向量中断控制器。STM32F中文参考手册中搜索向量表可以找到相应的中断说明。
    CM4/CM7 内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
    STM32F4/F7并没有使用CM4内核的全部东西,而是只用了它的一部分。
    STM32F40xx/STM32F41xx总共有92个中断。10个内核中断,82个可屏蔽中断。
    STM32F42xx/STM32F43xx则总共有97个中断。10个内核中断,87个可屏蔽中断。
    STM32F76x总共118个中断,10个内核中断,108个可屏蔽中断。

    STM32具有16级可编程的中断优先级,而我们常用的就是这些可屏蔽中断。

    几十个中断,怎么管理?

    首先,对STM32中断进行分组,组0~4。同时,对每个中断设置一个抢占优先级和一个响应优先级值。

    分组配置是在寄存器SCB->AIRCR中配置: IP bit[7:4]有4位,2^4=16,所以说它们的优先级可以有16个值,这时候如果是2位抢占优先级,那么它的值可能为0、1、2、3。也就是抢占优先级可以取0到3 。首先进行分组来决定几位抢占优先级、几位响应优先级。数越小它的优先级越高。

    AIRCR[10:8]IP bit[7:4]分配情况分配结果
    01110:40位抢占优先级,4位响应优先级
    11101:31位抢占优先级,3位响应优先级
    21012:22位抢占优先级,2位响应优先级
    31003:13位抢占优先级,1位响应优先级
    40114:04位抢占优先级,0位响应优先级

    抢占优先级 & 响应优先级区别:

    高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。抢占决定了是否能打断别人。
    抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
    抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
    如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

    举例:

    假定设置中断优先级组为2,然后设置

    中断3(RTC中断)的抢占优先级为2,响应优先级为1。

    中断6(外部中断0)的抢占优先级为3,响应优先级为0

    中断7(外部中断1)的抢占优先级为2,响应优先级为0。

    那么这3个中断的优先级顺序为:中断7>中断3>中断6。

    一般情况下,系统代码执行过程中,只设置一次中断优先级分组,比如分组2,设置好分组之后一般不会再改变分组。随意改变分组会导致中断管理混乱,程序出现意想不到的执行结果。

    中断优先级分组函数位于HALLIB中的stm32f7xx_hal_cortex.c:void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);

    void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
    {
      /* Check the parameters */
      assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
      
      /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
      NVIC_SetPriorityGrouping(PriorityGroup);
    }
    

    可以找到IS_NVIC_PRIORITY_GROUP的定义,进而确定PriorityGroup参数怎么写。

    #define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PRIORITYGROUP_0) || \
                                           ((GROUP) == NVIC_PRIORITYGROUP_1) || \
                                           ((GROUP) == NVIC_PRIORITYGROUP_2) || \
                                           ((GROUP) == NVIC_PRIORITYGROUP_3) || \
                                           ((GROUP) == NVIC_PRIORITYGROUP_4))
    

    在stm32f7xx_hal.c中可以找到HAL_Init函数:其中HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);可以看到中断分组为2 。

    HAL_StatusTypeDef HAL_Init(void)
    {
      /* Configure Flash prefetch and Instruction cache through ART accelerator */ 
    #if (ART_ACCLERATOR_ENABLE != 0)
       __HAL_FLASH_ART_ENABLE();
    #endif /* ART_ACCLERATOR_ENABLE */
    
      /* Set Interrupt Group Priority */
      HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
    
      /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
      HAL_InitTick(TICK_INT_PRIORITY);
      
      /* Init the low level hardware */
      HAL_MspInit();
      
      /* Return function status */
      return HAL_OK;
    }
    

    2.NVIC中断优先级设置

    分组设置好之后,怎么设置单个中断的抢占优先级和响应优先级?

    中断设置相关寄存器:

    _IO uint8_t IP[240]; //中断优先级控制的寄存器组

    _IO uint32_t ISER[8]; //中断使能寄存器组
    _IO uint32_t ICER[8]; //中断失能寄存器组
    _IO uint32_t ISPR[8]; //中断挂起寄存器组
    _IO uint32_t ICPR[8]; //中断解挂寄存器组
    _IO uint32_t IABR[8]; //中断激活标志位寄存器组

    位于core_cm7.h中:NVIC_Type结构体中成员变量就是那些寄存器。

    /**
      \brief  Structure type to access the Nested Vectored Interrupt Controller (NVIC).
     */
    typedef struct
    {
      __IOM uint32_t ISER[8U];               /*!< Offset: 0x000 (R/W)  Interrupt Set Enable Register */
            uint32_t RESERVED0[24U];
      __IOM uint32_t ICER[8U];               /*!< Offset: 0x080 (R/W)  Interrupt Clear Enable Register */
            uint32_t RSERVED1[24U];
      __IOM uint32_t ISPR[8U];               /*!< Offset: 0x100 (R/W)  Interrupt Set Pending Register */
            uint32_t RESERVED2[24U];
      __IOM uint32_t ICPR[8U];               /*!< Offset: 0x180 (R/W)  Interrupt Clear Pending Register */
            uint32_t RESERVED3[24U];
      __IOM uint32_t IABR[8U];               /*!< Offset: 0x200 (R/W)  Interrupt Active bit Register */
            uint32_t RESERVED4[56U];
      __IOM uint8_t  IP[240U];               /*!< Offset: 0x300 (R/W)  Interrupt Priority Register (8Bit wide) */
            uint32_t RESERVED5[644U];
      __OM  uint32_t STIR;                   /*!< Offset: 0xE00 ( /W)  Software Trigger Interrupt Register */
    }  NVIC_Type;
    
    

    对于每个中断怎么设置优先级?

    中断优先级控制的寄存器组:IP[240],全称是:Interrupt Priority Registers

    240个8位寄存器,每个中断使用一个寄存器来确定优先级。STM32F40x系列一共82个可屏蔽中断,使用IP[81]~IP[0]。

    每个IP寄存器的高4位用来设置抢占和响应优先级(根据分组),低4位没有用到。

    在stm32f7xx_hal_cortex.c可找到:

    /**
      * @brief  Sets the priority of an interrupt.
      * @param  IRQn: External interrupt number.
      *         This parameter can be an enumerator of IRQn_Type enumeration
      *         (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f7xxxx.h))
      * @param  PreemptPriority: The preemption priority for the IRQn channel.
      *         This parameter can be a value between 0 and 15
      *         A lower priority value indicates a higher priority 
      * @param  SubPriority: the subpriority level for the IRQ channel.
      *         This parameter can be a value between 0 and 15
      *         A lower priority value indicates a higher priority.          
      * @retval None
      */
    void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
    { 
      uint32_t prioritygroup = 0x00;
      
      /* Check the parameters */
      assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
      assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
      
      prioritygroup = NVIC_GetPriorityGrouping();
      
      NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
    }
    
    

    中断优先级设置步骤:

    • 系统运行后在HAL_Init函数中设置中断优先级分组。调用函数:
      HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
      //中断优先级分组2 整个系统执行过程中,只设置一次中断分组。
    • 针对每个中断,设置对应的抢占优先级和响应优先级:
      void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t
      PreemptPriority, uint32_t SubPriority);
    • 使能中断通道:
      void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
    void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
    {
      /* Check the parameters */
      assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
      
      /* Enable interrupt */
      NVIC_EnableIRQ(IRQn);
    }
    
    
    展开全文
  • cotex_m3中断优先级的描述和配置,非常仔细
  • 中断异常向量表中的优先级应该是指的中断、异常的硬件优先级,如果两个或更多的中断指定了相同的优先级,则由它们的硬件优先级来决定处理器对它们进行处理时的顺序。
  • XS128中断优先级设置

    2012-07-10 15:43:41
    XS128中断优先级设置,MC9s12xs128中断优先级设置,MC9s12xs128中断优先级设置,
  • 对于 M3 和 M4 内核的 MCU,每个中断优先级都是用寄存器中的 8 位来设置的。 8 位的话就可以 设置 2^8 = 256 级中断,实际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如 ST 的 STM32F1xx 和 F4...

    NVIC 的全称是 Nested vectored interrupt controller,即嵌套向量中断控制器。
    对于 M3 和 M4 内核的 MCU,每个中断的优先级都是用寄存器中的 8 位来设置的。 8 位的话就可以
    设置 2^8 = 256 级中断,实际中用不了这么多,所以芯片厂商根据自己生产的芯片做出了调整。比如 ST
    的 STM32F1xx 和 F4xx 只使用了这个 8 位中的高四位[7:4],低四位取零,这样 2^4=16,只能表示 16
    级中断嵌套。
    对于这个 NVIC,有个重要的知识点就是优先级分组,抢占优先级和子优先级,下面就以 STM32 为
    例进行介绍,STM32F1xx 和 F4xx 都是只使用了这个 8 位寄存器的高四位[7:4]。 

    从上面的表格可以看出,STM32 支持 5 种优先级分组,系统上电复位后,默认使用的是优先级分组
    0,也就是没有抢占式优先级,只有子优先级,关于这个抢占优先级和这个子优先级有几点一定要说清楚。
     具有高抢占式优先级的中断可以在具有低抢占式优先级的中断服务程序执行过程中被响应,即中
    断嵌套,或者说高抢占式优先级的中断可以抢占低抢占式优先级的中断的执行。
     在抢占式优先级相同的情况下,有几个子优先级不同的中断同时到来,那么高子优先级的中断优
    先被响应。
     在抢占式优先级相同的情况下,如果有低子优先级中断正在执行,高子优先级的中断要等待已被
    响应的低子优先级中断执行结束后才能得到响应,即子优先级不支持中断嵌套。
     Reset、 NMI、 Hard Fault 优先级为负数,高于普通中断优先级,且优先级不可配置。
     对于初学者还有一个比较纠结的问题就是系统中断(比如:PendSV,SVC,SysTick)是不是一
    定比外部中断(比如 SPI,USART)要高,答案:不是的,它们是在同一个 NVIC 下面设置的。 

    具体可以点击这里查看之前的随笔。

    强烈推荐用户将 Cortex-M3 内核的 STM32F103 和 Cortex-M4 内核的 STM32F407 以及
    STM32F429 的 NVIC 优先级分组设置为 4,即:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);这
    样中断优先级的管理将非常方便。 这个也是官方强烈建议的。

    (注意:一旦初始化好 NVIC 的优先级分组后,切不可以在应用中再次更改。)
    设置 NVIC 的优先级分组为 4 表示支持 0-15 级抢占优先级 (注意, 0-15 级是 16 个级别,包含 0 级), 不支持子优先级。 
    在这里继续强调下这一点,在 NVIC 分组为 4 的情况下,抢占优先级可配置范围是 0-15,那么数值越小,抢占优先级的级别越高,即 0 代表最高优先级,15 代表最低优先级。 


    FreeRTOS 配置选项中 NVIC 相关配置
    FreeRTOSConfig.h 配置文件中设置到 NVIC 中断的有如下几个选项: 

    复制代码

    /*
     * Cortex-M内核使用8bit来配置优先级,但是STM32只使用了高4bit,数值越小,优先级越高。
     * 在往寄存器里面写数值配置的时候,是按照8bit来写的,所以真正写的时候需要经过转换,公式为:
     * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我们配置的真正的优先级
     */
    #ifdef __NVIC_PRIO_BITS  /* __NVIC_PRIO_BITS 已经在stm32f4xx.h里面定义为4 */
        #define configPRIO_BITS               __NVIC_PRIO_BITS
    #else
        #define configPRIO_BITS               4
    #endif
    /*============================================== SysTick中断优先级配置 ============================================*/
    /*
     * 在往寄存器里面写数值配置的时候,是按照8bit来写的,所以真正写的时候需要经过转换,公式为:
     * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我们配置的真正的优先级。经过这个公式之后得到的是
     * 下面的这个宏:configKERNEL_INTERRUPT_PRIORITY
     * SysTick的优先级我们一般配置为最低,即0xf 。这样可以提高系统的实时响应能力,即其他的外部中断可以及时的得到响应。
     */
    #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            0xf
    #define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
    
    /*===========================================可屏蔽的中断优先级配置====================================================*/
    /*
     * 用于配置STM32的特殊寄存器basepri寄存器的值,用于屏蔽中断,当大于basepri值的优先级的中断将被全部屏蔽。basepri只有4bit有效,
     * 默认只为0,即全部中断都没有被屏蔽。configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY配置为:5,意思就是中断优先级大于5的中断都被屏蔽。
     * 当把配置好的优先级写到寄存器的时候,是按照8bit来写的,所以真正写的时候需要经过转换,公式为:
     * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我们配置的真正的优先级。经过这个公式之后得到的是下面的这个宏:
     * configMAX_SYSCALL_INTERRUPT_PRIORITY
     *
     * 在FreeRTOS中,关中断是通过配置basepri寄存器来实现的,关掉的中断由配置的basepri的值决定,小于basepri值的
     * 中断FreeRTOS是关不掉的,这样做的好处是可以系统设计者可以人为的控制那些非常重要的中断不能被关闭,在紧要的关头必须被响应。
     * 而在UCOS中,关中断是通过控制PRIMASK来实现的,PRIMASK是一个单1的二进制位,写1则除能除了NMI和硬 fault的所有中断。当UCOS关闭
     * 中断之后,即使是你在系统中设计的非常紧急的中断来了都不能马上响应,这加大了中断延迟的时间,如果是性命攸关的场合,那后果估计挺严重。
     * 相比UCOS的关中断的设计,FreeRTOS的设计则显得人性化很多。
     *
     */
    #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
    #define configMAX_SYSCALL_INTERRUPT_PRIORITY     ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

    复制代码

    #define configPRIO_BITS 4
    此宏定义用于配置 STM32 的 8 位优先级设置寄存器实际使用的位数。 STM32F103,STM32F407
    和 STM32F429 都是使用的 4 位。 另外注意一点,这里使用了一个条件编译,用户可以选择将条件编
    译删掉,直接定义一个#define configPRIO_BITS 4 即可。使用条件编译的好处就是方便与系统统
    一。这个__NVIC_PRIO_BITS 在 STM32F103 标准库的头文件 stm32f10x.h 中以及 STM32F407/439
    的标准库的头文件 stm32f4xx.h 中分别有定义。如果用户在 FreeRTOSConfig.h 文件里面包含了这个
    标准库的头文件,那么就会执行条件编译选项:
    #define configPRIO_BITS __NVIC_PRIO_BITS 

    #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f
    此宏定义是用来配置 FreeRTOS 用到的 SysTick 中断和 PendSV 中断的优先级。在 NVIC 分组设置为
    4 的情况下,此宏定义的范围就是 0-15,即专门配置抢占优先级。这里配置为了 0x0f,即 SysTick
    和 PendSV 都是配置为了最低优先级,实际项目中也建议大家配置最低优先级即可。
     SVC 中断
    在 FreeRTOS 的移植文件 ports.c 中有用到 SVC 中断的 0 号系统服务,即 SVC 0。此中断在 FreeRTOS
    中仅执行一次, 用于启动第一个要执行的任务。 另外, 由于 FreeRTOS 没有配置 SVC 的中断优先级,
    默认没有配置的情况下, SVC 中断的优先级就是最高的 0。 如果用户在不清楚自己配置的 PendSV 和
    SysTick 中断是否跟实际情况一致时,可以进行硬件调试。 比如 MDK,我们可以在硬件调试的状态下,
    先点击全速运行,然后查看如下调试组件: 

    #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY  0x01
    此宏定义比较重要,定义了受 FreeRTOS 管理的最高优先级中断。简单的说就是允许用户在这个中断
    服务程序里面调用 FreeRTOS 的 API 的最高优先级。 设置 NVIC 的优先级分组为 4 的情况下。 配置
    configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 为 0x01 表示用户可以在抢占式优先级为 1 

    到 15 的中断里面调用 FreeRTOS 的 API 函数,抢占式优先级为 0 的中断里面是不允许调用的。 不受
    FreeRTOS 管理的中断有什么深层的含义吗?

    不受 FreeRTOS 管理中断的深入讨论
    讲解不受 FreeRTOS 管理的中断之前要说一个小知识点----中断延迟。 中断延迟时间是衡量 RTOS 实
    时操作系统的一项重要指标,那什么又是中断延迟呢?从中断触发到执行中断服务程序的第一条指令这段
    时间就是中断延迟时间。
    FreeRTOS 内核源码中有多处开关全局中断的地方,这些开关全局中断会加大中断延迟时间。 比如在
    源码的某个地方关闭了全局中断,但是此时有外部中断触发,这个中断的服务程序就需要等到再次开启全
    局中断后才可以得到执行。开关中断之间的时间越长,中断延迟时间就越大,这样极其影响系统的实时性。
    如果这是一个紧急的中断事件,得不到及时执行的话,后果是可想而知的。
    针对这种情况,FreeRTOS 就专门做了一种新的开关中断实现机制。 关闭中断时仅关闭受 FreeRTOS
    管理的中断,不受 FreeRTOS 管理的中断不关闭,这些不受管理的中断都是高优先级的中断,用户可以在
    这些中断里面加入需要实时响应的程序。 FreeRTOS 能够实现这种功能的奥秘就在于 FreeRTOS 开关中断
    使用的是寄存器 basepri,而像 uCOS 这种使用的是 primask,详情请看下面整理的表格: 

     

    #define configKERNEL_INTERRUPT_PRIORITY
    宏定义 configLIBRARY_LOWEST_INTERRUPT_PRIORITY的数值经过 4bit偏移后得到一个 8bit
    的优先级数值,即宏定义 configKERNEL_INTERRUPT_PRIORITY 的数值。这个 8bit 的数值才可以
    实际赋值给相应中断的优先级寄存器。
    也许初学者有疑问了,为什么前面 NVIC 配置的时候不是 8bit 的方式进行配置?这是因为 ST 的
    库函数 NVIC_Init()已经为我们做好了。 这里的宏定义数值是供 PendSV 和 SysTick 中断进行优先级
    配置的。 比如:我们这里配置宏定义 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 是 0x0f,经
    过 4bit 偏移后就是 0xf0,即 SysTick 和 PendSV 的中断优先级就是 240。

    #define configMAX_SYSCALL_INTERRUPT_PRIORITY
    宏定义 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 的数值经过 4bit 偏移后得到一
    个 8bit 的优先级数值,即宏定义 configMAX_SYSCALL_INTERRUPT_PRIORITY 的数值。 这个数值
    是赋值给寄存器 basepri 使用的,8bit 的数值才可以实际赋值给相应中断的优先级寄存器。
    这里的宏定义数值赋给寄存器 basepri 后就可以实现全局的开关中断操作了。 比如:我们这里配
    置宏定义 configLIBRARY_LOWEST_INTERRUPT_PRIORITY 是 0x01,经过 4bit 偏移后就是 0x10,
    即 16。 调用了 FreeRTOS 的关中断后,所有优先级数值大于等于 16 的中断都会被关闭。优先级数值
    小于 16 的中断不会被关闭,对寄存器 basepri 寄存器赋值 0,那么被关闭的中断会被打开。

    上面的优先级数值,240和16,是十进制数,是真正8bit的数值,但是ST给我们了库函数,我们只配置4-7位,就可以了,其实就在配置这4-7位为0xf,表示优先级为15,实际十进制为240,配置这4-7位为 0x1,表示优先级为1,实际十进制为16.不要混淆了。
     NOTE:

    这里configMAX_SYSCALL_INTERRUPT_PRIORITY的优先级是个8bit的,之前的configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY是4bit,注意有没有LIBRARY。

    展开全文
  • DSP软件设置中断优先级的原理 根据网上查到的一些信息和研学TI的官方例程,得出以下结论. 在正常情况下,cpu进入中断后,默认会屏蔽所有中断,这样不会发生中断嵌套 如果cpu进入中断后,软件打开中断开关的话,如果有新的...

    DSP软件设置中断优先级的原理
    28335的外设级中断由PIE模块进行管理,这与stm32的NVIC中断管理模块有很大的区别.首先PIE模块已经将各个外设级中断的优先级固化,而这些固化了的优先级并不一定适合各种应用程序.所以我们需要对外设的中断优先级进行重新分配.其次,在28335中使用软件对外设中断优先级进行修改相当复杂.下面将进行讲解.

    首先,如果你使用DSP2833x_DefaultIsr.c对中断进行管理的话,不知道你有没有注意到,当低优先级的终端任务正在执行时,即使高的优先级来的话,cpu也不会去执行高的优先级任务.相信你一定不这样认为,那么你可以在低优先级的中断函数里加入while(1);,然后查看能否进入高优先级的任务.

    其次,如果上一步你发现事实正如我所说的那样的话.那么你可以进行下一步的实验了,毕竟实践是检验真理的唯一标准.这时你在优先级的任务中加入EINT;while(1);.这次你觉得会发生什么,你是不是认为这次还是一直在while(1)卡住.但事实是,当低优先级的任务来临时,此时cpu会去执行低优先级的任务,而不是卡在while(1).是不是觉得很奇怪.

    最后,我们进行一个简单的实验,那就是再任意的中断服务函数中加入DINT,这次你会认为发生什么?你不是觉得外设中断都被屏蔽了,以后CPU不会再相应新的中断了.但事实是吗,事实是外设中断照样得到响应.

    **做到这里是不是觉得很懵逼.**下面听完我的解释,你一定会豁然开朗.

    其实,cpu每次进入中断都会执行DINT语句,这样即使有高优先级的任务到来时,也不会得到执行,也就是说无法进行中断嵌套,你是不是对第一个实验的结果有了新的认识.而如果你在中断里调用EINT语句就打开了所有可屏蔽中断,这样也就可以响应新的中断,来完成中断嵌套,而这种嵌套是不分优先级的嵌套,只要来新中断就会执行,你是不是明白第二个实验的结果了.最后cpu退出中断时都会执行EINT语句.这样第三个实验的结果也得到了解释.

    你可能会问DSP这样做是为了什么.说实在的我也懂得为什么要这么做.我好lalalallalalaji.

    但是不懂我们也可以用啊.利用这个特性就可以进行软件设置中断优先级了.其原理就在下面.

    本人总结出以下结论:

    • 在正常情况下,cpu进入中断后,默认会屏蔽所有中断(相当于DINT),这样不会发生中断嵌套,cpu退出中断时也会再次打开可屏蔽中断(相当于EINT).
    • 如果cpu进入中断后,软件打开中断开关的话(即执行EINT),如果有新的中断来,cpu都会执行新的中断,而不会管新的中断的优先级是否比现在正在执行的中断优先级高.
    • 如果想按照软件设置的优先级进行中断嵌套的话,需要每当进入中断后只打开比本中断优先级高的所有中断,这样就实现了中断嵌套,也即完成了优先级的配置.

    如果你持怀疑态度,可以去研究28334的软件优先级的官方例程

    如果想了解跟多DSP的知识,可以关注我,后续会持续更新的.

    展开全文
  • 文章目录 抢占优先级和响应优先级 抢占 响应 NVIC 的优先级组 中断寄存器 ISER[8] ICER[8] ISPR[8] ICPR[8] IABR[8] IP[240] 中断优先级设置步骤总结 Ref. 抢占优先级和响应优先级 STM32 的中断向量具有两个属性,一...
  • 单片机中断优先级以T0及T1中断为例
  • configMAX_SYSCALL_INTERRUPT_PRIORITY 中断优先级设置问题 从CortexM角度 Cortex-M构架自身最多允许256级可编程优先级(优先级配置寄存器最多8位,所以优先级范围从0x00~0xFF), 是绝大多数微控制器制造商只是使用...
  • OLED_ROSC中断优先级.zip

    2017-12-06 09:27:00
    SYD8801 OLED_ROSC 中断优先级 SYD8801 OLED_ROSC 中断优先级 SYD8801 OLED_ROSC 中断优先级
  • STM32 中断优先级

    2020-02-13 20:33:37
    1.ARM cortex_m3 内核支持 256 个中断(16 个内核+240 外部)和可编程 256 级中断优先级 的设置,与其相关的中断控制和中断优先级控制寄存器(NVIC、SYSTICK 等)也都属于 cortex_m3 内核的部分。STM32 采用了 ...
  • STM32F103 中断优先级理解

    万次阅读 2019-01-14 10:22:48
    串口都能正常收发数据,但是有一个串口发送数据帧给另一个主控时,数据帧出现了分包,我判断了一下,可能是通信串口发送中断被调试串口的打印中断给“截胡”了,所以来专门研究一下STM32的中断优先级,用更改串口...
  • STM32 NVIC 中断优先级管理 CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断,并且具有 256级的可编程中断设置。 STM32 并没有使用 CM3 内核的全部东西,而是只用了它的一部分。STM32 有 84 ...
  • cubemax设置中断优先级

    2021-08-18 00:15:57
    1.打开cubemax,例如设置两个GPIO引脚高低电平产生的外部...3.选择NVIC控制器,分配抢占优先级和响应优先级位数,一共有5种分配方式,打钩进行中断使能,最后设置优先级,数字越小表示优先级越高。 ...
  • 一般使用多个中断时,就会考虑中断的重要性及其之间的优先级关系。HAL库中可以通过HAL_NVIC_SetPriority函数来设置中断优先级,决定中断是否能够被抢占。 开发环境: MCU:STM32L071CBT6 IDE:KEIL5、STM32...
  • STM32----NVIC中断优先级 之前在学习和应用STM32时总是有疑惑,总是感觉优先级分组有点混乱,而且在排序中断优先级时没有一定的头绪,在疫情期间对这一方面的知识进行了深入的了解,下面将我学到的一些知识分享给...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 157,557
精华内容 63,022
关键字:

中断优先级