这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » 【STM32F103ZET6】16:分享在中断中恢复串口任务,遇到的问题

共5条 1/1 1 跳转至

【STM32F103ZET6】16:分享在中断中恢复串口任务,遇到的问题

高工
2025-12-02 10:22:15   被打赏 50 分(兑奖)     打赏
一:本帖内容在之前的帖子中,分享了在任务中,挂起和恢复串口的输出任务,今天和大家分享一下,在中断中的任务的挂起和恢复过程,以及在学习代码中遇到的问题。

二:按键中断的配置:有关外部中断的使用,及使用方法请参考之前的帖子:NUCLEO-U083RC学习历程6-exit中断学习

https://forum.eepw.com.cn/thread/386886/1

2.1 原理图部分:

16-1.png

2.2 STM32 cube MX 软件配置如下所示:

16-2.png

这里根据电路上的配置,配置成上升沿 或者是下降沿触发模式。

三:软件代码如下所示:

3.1 在LED灯闪烁的任务中,挂起串口输出任务:

void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(500);
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);        
    usart1count++ ;
    if(usart1count >=20)  vTaskSuspend(usart1sendTaskHandle); //挂起任务
  }
  /* USER CODE END StartTask02 */
}
3.2  在中断中,恢复串口输出任务

extern uint8_t usart1count ;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  BaseType_t xYieldRequired;        
        switch( GPIO_Pin)
        {
                case  GPIO_PIN_0 : // key up
                        break ;                        
                case  GPIO_PIN_3 : // key1   
                                    xYieldRequired = xTaskResumeFromISR(usart1sendTaskHandle);
                                    printf("在中断中恢复串口任务 \r\n");
                                    usart1count = 0 ;
                                    if(xYieldRequired == pdTRUE)
                                    {
                                       portYIELD_FROM_ISR(xYieldRequired);
                                    }
                        break ;                
                case  GPIO_PIN_4 : //key0
                                   vTaskSuspend(usart1sendTaskHandle);               
                        break ;                                        
                        default :
                        break ;                
        }
}
3.3 在中断中挂起串口输出任务:然后我在中断中本想在任务中挂起串口的输出任务:发现程序停止在下面的函数中:感觉任务调度的出现了问题;

void vPortEnterCritical( void )
{
        portDISABLE_INTERRUPTS();
        uxCriticalNesting++;

        /* This is not the interrupt safe version of the enter critical function so
        assert() if it is being called from an interrupt context.  Only API
        functions that end in "FromISR" can be used in an interrupt.  Only assert if
        the critical nesting count is 1 to protect against recursive calls if the
        assert function also uses a critical section. */
        if( uxCriticalNesting == 1 )
        {
                configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
        }
}
这里大概的意思是:*这并非 enter critical函数的防中断安全版本,因此应在从中断上下文调用时进行断言。只有、“FromISR”结尾的 API函数才能在中断中使用。仅在临界嵌套次数为1的情况下才进行断言以防范递归调用的情况--如果断言函数本身也使用了临界区的话。》."/3.4 按下按键key1时候,可以发现串口的输出任务可以正常输出:

16-3.png四:问题解决办法:

4.1 在中断中,放置一个标志位

 case  GPIO_PIN_4 : //key0
           printf("在中断中判断输出串口的标志位 \r\n");
           key0_flag =1 ;
//          vTaskSuspend(usart1sendTaskHandle);                
      break ;

上下文问题:ISR运行在特殊的“中断上下文”中,而不是任何任务的上下文中。它没有自己的任务控制块(TCB)。许多挂起函数的内部实现(比如需要修改任务状态链表)并不是为中断上下文设计的。

调度时机:如果ISR直接挂起一个任务,特别是当前正在运行的任务,会立即触发一次任务调度。调度器需要在ISR退出前决定下一个运行的任务。这可能导致不可预测的行为,并增加中断延迟。

重入与同步问题:任务管理函数通常不是可重入的,且需要保护内部数据结构。在ISR中直接调用可能破坏内核数据的完整性。

4.2:在LED灯闪烁任务中,挂起串口任务:

void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(500);
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);        
    usart1count++ ;
    if(usart1count >=20)  vTaskSuspend(usart1sendTaskHandle); //挂起任务
                        
    if(key0_flag == 1)
    {
     key0_flag = 0 ;
     vTaskSuspend(usart1sendTaskHandle); 
    }
  }
  /* USER CODE END StartTask02 */
}
验证图片如下所示:

16-4.png

可见,在中断中恢复任务,需要使用的函数与在任务中使用的函数并不相同。区分于后缀有所不同 FromISR:中断只做最低限度的紧急处理和事件通知,将所有复杂的业务逻辑(包括任务状态管理)交给任务去处理。学习过程中,发现不能在中断中挂起任务。



关键词: STM32F103ZET6     中断     挂起恢复任务    

助工
2025-12-02 10:46:44     打赏
2楼

在RTOS的中断中使用系统函数还是要特别注意嵌套的问题。

普通bare-metal系统下由硬件直接完成,而RTOS需要软件协助,这时如果调用失败,或者压栈入栈失败,会导致RTOS的crash


院士
2025-12-02 11:05:02     打赏
3楼

楼主的内容与思路还是非常值得借鉴,只是这例子举得有点勉强了。


院士
2025-12-03 22:02:57     打赏
4楼

继续下一个帖子 

期待中……


助工
2025-12-04 09:27:07     打赏
5楼

再给楼主 赞一下


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]