打印
[STM32F4]

HAL_UART_RxCpltCallback串口接收中断回调不正常

[复制链接]
509|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AC, LTC, UART, ck, tc

背景:【MXCube+FreeRTOS+STM32F407】

为了将串口数据上下文分离。在回调函数中,使用消息队列将接收的字符发至队列。在任务线程中进行处理数据。


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

  //taskENTER_CRITICAL();

  /* Prevent unused argument(s) compilation warning */

  //UNUSED(huart);

  if (huart->Instance == USART2) {

    osMessageQueuePut(remoteQueueHandle, (uint8_t*)&remoteTmpBuffer[0], 0, 0);

  } else if(huart->Instance == USART6) {

    osMessageQueuePut(ledQueueHandle, (uint8_t*)&ledTmpBuffer[0], 0, 0);

  } else if(huart->Instance == USART3) {

          osMessageQueuePut(lockQueueHandle, (uint8_t*)&lockTmpBuffer[0], 0, 0);

  }

  //taskEXIT_CRITICAL();

}



使用特权

评论回复
沙发
是你的乱码|  楼主 | 2022-11-17 14:21 | 只看该作者
Step1分析:

osMessageQueuePut 使用在中断,需要设置 timeout 参数为0;

使用特权

评论回复
板凳
是你的乱码|  楼主 | 2022-11-17 14:22 | 只看该作者
Step2分析:

osMessageQueuePut 在中断中使用最终调用为:xQueueGenericSendFromISR

使用特权

评论回复
地板
是你的乱码|  楼主 | 2022-11-17 14:23 | 只看该作者
在单步追踪中:void vPortValidateInterruptPriority( void ),最终在此函数ASSERT断言

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

                /* Obtain the number of the currently executing interrupt. */
                ulCurrentInterrupt = vPortGetIPSR();

                /* Is the interrupt number a user defined interrupt? */
                if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
                {
                        /* Look up the interrupt's priority. */
                        ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

                        /* 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.
                        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.
                        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 maintains separate thread and ISR API functions to ensure
                        interrupt entry is as fast and simple as possible.
                        The following links provide detailed information:
                        http://www.freertos.org/RTOS-Cortex-M3-M4.html
                        http://www.freertos.org/FAQHelp.html */
                        configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
                }

                /* 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 unpredictable behaviour. */
                configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
        }

使用特权

评论回复
5
是你的乱码|  楼主 | 2022-11-17 14:24 | 只看该作者
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

注释明白的讲明, 当前中断优先级大于等于FREERTOS系统能调用的最大优先级,起初以为FreeRTOS配置没对,将Timer、Systick等按MXCube生成的优先级进行调整,无作用。

使用特权

评论回复
6
是你的乱码|  楼主 | 2022-11-17 14:26 | 只看该作者
FreeRTOS 控制的优先级范围:5~15

Timer:2 -> 5

Systick :0 -> 5

使用特权

评论回复
7
是你的乱码|  楼主 | 2022-11-17 14:27 | 只看该作者
Step3分析:

既然网上搜到优先级不对,会不会是串口优先级 高于 FreeRTOS的控制范围?

使用特权

评论回复
8
是你的乱码|  楼主 | 2022-11-17 14:28 | 只看该作者
MXCube里将USART相关中断优先级降低至6,问题解决

使用特权

评论回复
9
是你的乱码|  楼主 | 2022-11-17 14:30 | 只看该作者
总结:MXCude好东西,解耦了需要对底层寄存器的理解,但对原理不稍微掌握,还是会出些难以预测的问题,在网上还不一定有答案。

使用特权

评论回复
10
OKAKAKO| | 2024-6-25 15:42 | 只看该作者
回调不正常一般是回调函数调用有问题

使用特权

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

本版积分规则

25

主题

286

帖子

1

粉丝