打印
[应用相关]

笔记---FreeRtos系统中外设中断优先级设置的要点

[复制链接]
2943|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Larm1|  楼主 | 2019-4-16 16:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
      最近在写一个串口通讯的程序,软件、硬件平台如下:
硬件: STM32F429ZG
系统: FreeRtos、HAL库
工具:  Iar7.6

      计划是利用串口DMA+IDLE空闲中断的方式接收数据,在中断内将接收到的数据通过队列的方式发送出去,在任务内部等待接收队列,串口中断配置及ISR如下:
//// 中断配置,优先级大小不能乱配置
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

void USART1_IRQHandler(void)
{
        uint32_t                 flag=0;
        BaseType_t        pHigherPriorityTaskWoken = pdFALSE;
       
        flag = __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE);
        if((flag != RESET))
        {
                __HAL_UART_CLEAR_IDLEFLAG(&huart1);
                huart1.Instance->SR;  
                huart1.Instance->DR;

                HAL_UART_DMAStop(&huart1);
                xQueueSendFromISR(UrtK125RcvQueue, DrvUsartRcvBuf, &pHigherPriorityTaskWoken);
                portYIELD_FROM_ISR(pHigherPriorityTaskWoken);
        }
}
      //// 为什么代码提交后,代码对齐格式变了呢???

      调试发现进入中断后,程序卡在了函数xQueueSendFromISR(UrtK125RcvQueue, DrvUsartRcvBuf, &pHigherPriorityTaskWoken)内部configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )处,具体为:
#if( configASSERT_DEFINED == 1 )

        void vPortValidateInterruptPriority( void )
        {
        uint32_t ulCurrentInterrupt;
        uint8_t ucCurrentPriority;

                /* Obtain the number of the currently executing interrupt. */
                __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
                //// ulCurrentInterrupt 调试显示为53

                /* Is the interrupt number a user defined interrupt? */
                if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
                {
                        /* Look up the interrupt's priority. */
                        ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];
                        //// 当串口优先级设置小于5时,ucCurrentPriority的值小于0x50,导致下面的宏断
                        //// 言configASSERT条件值"==0",进而卡住
                        //// 当串口优先级设置大于等于5时,ucCurrentPriority的值大于等于0x50,下面的
                        //// 宏configASSERT条件值"==1",所以不会卡住

                        /* The following assertion will fail if a service routine (ISR) for
                        an interrupt that has been assigned a priority above
                        configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API
                        function.  ISR safe FreeRTOS API functions must *only* be called
                        from interrupts that have been assigned a priority at or below
                        configMAX_SYSCALL_INTERRUPT_PRIORITY.
                        //// 如果一个调用FreeRtos安全ISR API接口的中断ISR优先级分配大于
                        //// configMAX_SYSCALL_INTERRUPT_PRIORITY(即中断优先级值小于
                        //// configMAX_SYSCALL_INTERRUPT_PRIORITY,因为FreeRtos中值越小优先级越高),
                        //// 下面的断言就会失败。FreeRtos安全ISR API接口必须只能在优先级分配大于
                        //// configMAX_SYSCALL_INTERRUPT_PRIORITY的中断ISR中调用
                        
                        Numerically low interrupt priority numbers represent logically high
                        interrupt priorities, therefore the priority of the interrupt must
                        be set to a value equal to or numerically *higher* than
                        configMAX_SYSCALL_INTERRUPT_PRIORITY.
                        //// 数值小的中断优先级逻辑上具有高的中断有限权,因此设置时,中断的优先级
                        //// 值必须必configMAX_SYSCALL_INTERRUPT_PRIORITY大

                        Interrupts that        use the FreeRTOS API must not be left at their
                        default priority of        zero as that is the highest possible priority,
                        which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY,
                        and        therefore also guaranteed to be invalid.
                        //// 使用FreeRTOS API的中断的优先级禁止使用其0的认值,因为此时中断优先级最
                        //// 高,0值的优先级必然大于configMAX_SYSCALL_INTERRUPT_PRIORITY,因此也必
                        //// 然无效

                        FreeRTOS maintains separate thread and ISR API functions to ensure
                        interrupt entry is as fast and simple as possible.
                        //// FreeRTOS为了确保中断入口尽可能的快和简单,因此分离了线程ISR API接口

                        The following links provide detailed information:
                        http://www.freertos.org/RTOS-Cortex-M3-M4.html
                        http://www.freertos.org/FAQHelp.html */
                        configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); //// 程序卡住位置
                        //// ucMaxSysCallPriority值为0x50
                }

                /* Priority grouping:  The interrupt controller (NVIC) allows the bits
                that define each interrupt's priority to be split between bits that
                define the interrupt's pre-emption priority bits and bits that define
                the interrupt's sub-priority.  For simplicity all bits must be defined
                to be pre-emption priority bits.  The following assertion will fail if
                this is not the case (if some bits represent a sub-priority).

                If the application only uses CMSIS libraries for interrupt
                configuration then the correct setting can be achieved on all Cortex-M
                devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
                scheduler.  Note however that some vendor specific peripheral libraries
                assume a non-zero priority group setting, in which cases using a value
                of zero will result in unpredicable behaviour. */
                configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
        }

#endif /* configASSERT_DEFINED */


简单总结如下:

      使用了FreeRtos操作系统后,外设中断优先级值不能设置小于configMAX_SYSCALL_INTERRUPT_PRIORITY,否则会导致了宏configASSERT的条件成立,进而卡住了。

使用特权

评论回复
沙发
mmuuss586| | 2019-4-18 09:45 | 只看该作者
感谢分享

使用特权

评论回复
板凳
木木guainv| | 2019-5-7 10:09 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
地板
xiaoqizi| | 2019-5-7 10:15 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
5
renzheshengui| | 2019-5-7 10:52 | 只看该作者
感谢楼主分享

使用特权

评论回复
6
paotangsan| | 2019-5-7 11:20 | 只看该作者
代码非常详细

使用特权

评论回复
7
keaibukelian| | 2019-5-7 11:36 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
8
guanjiaer| | 2019-5-7 11:44 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
9
heimaojingzhang| | 2019-5-7 11:46 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
10
磨砂| | 2019-5-8 08:19 | 只看该作者
代码好详细啊

使用特权

评论回复
11
晓伍| | 2019-5-8 08:26 | 只看该作者
是跑的系统吗

使用特权

评论回复
12
八层楼| | 2019-5-8 08:36 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:大爱无疆

53

主题

389

帖子

0

粉丝