叫我杨哥5240 2023-05-03 11:50
浏览 31
已结题

freeRTOS不正常运行

问题遇到的现象和发生背景

我为我的STM32集成了freeRTOS并开启了四个任务,其他任务都能完美并且正常运行。可是知道运行发射红外信号的任务的时候只能执行一次之后再无反应,连同其他的任务也受到了影响。以下是发生任务执行异常的代码

/* USER CODE BEGIN Header_StartSendLearnTask */
/**
* @brief Function implementing the SendLearnTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartSendLearnTask */
void StartSendLearnTask(void const * argument)
{
  /* USER CODE BEGIN StartSendLearnTask */
  osEvent event;
  uint8_t bykey = 0;
  /* Infinite loop */
  for(;;)
  {
    
    event = osMessageGet(keyCodeQueueHandle, osWaitForever); 
        if(event.status == osEventMessage)
        {
            bykey = event.value.v;
            
            switch(bykey)
            {
              case 1 : //learning mode
                LearnLight_ON();
                //Open learning record
                Re_Record_ON();
                
                //waiting for study to end
                while(infrared.IR_Status == IR_RECEIVING);
                TIM3CH4_CAP_STA = 0;
                TIM3CH4_CAP_VAL = 0;
                
                for(int i = 0; i < infrared.Count; i++) {
                  printf("infrared.KeepTime:%ld us\r\n",infrared.KeepTime[i]);
                }
                printf("Count:%d \r\n",infrared.Count);
                
                //Prevent data discrepancies and do updates
                recoverData();
                
                printf("last pos:%d \r\n", pos);
                //After learning, store the learning results
                save_struct_to_flash();
                
                //Close Study Record
                Re_Record_OFF();
                
                //Store the offset of the infrared signal in each sector in the first sector
                W25QXX_Erase_Sector(0);
                //record data offset
                dataOff[index++] = pos;
                //save the offset array
                uint8_t tempDataOff[240];
                for(uint16_t i = 0; i < index << 2; i += 4) {
                
                  tempDataOff[i] = dataOff[i] >> 24;
                  tempDataOff[i + 1] = dataOff[i] >> 16;
                  tempDataOff[i + 2] = dataOff[i] >> 8;
                  tempDataOff[i + 3] = dataOff[i];
                
                
                }
                W25QXX_Page_Program(tempDataOff, 0, index << 2);
                //Prompt to learn to complete
                LearnDone();
                
                break;
                
            case 2: 
                //send infrared signal
                ir_send();
//              SendLight_ON();
//              HAL_Delay(1000);
//              SendLight_OFF();
                
                break;
              
              
            }
        }
    
        
    osDelay(1);
  }
    
  /* USER CODE END StartSendLearnTask */
}

其实重点是在'ir_send();'

void ir_send() {
  
  
    //Prevent data discrepancies and do updates
    if(infrared.Count == 0) {
    
      recoverData();
      //No infrared signal has been stored yet
      if(index == 0)
        Error_Handler();
      
      
    }
    
    // Convert the data in the buffer to a structure type
      load_struct_from_flash();
    
  
    uint16_t Count = 1; //Send the infrared signal from the first digit, the first digit is an invalid code
    uint8_t count = *buffer;
    uint16_t tempKeep[256] = {0};
    for(uint16_t i = 0; i < count; i++) {
    
      tempKeep[i] = *(buffer + Count) | (*(buffer + Count + 1)) << 8;
      Count += 2;
    
    }
    
    
    SendLight_ON();
    __HAL_TIM_SET_COUNTER(&htim2, 0);
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 946);   // Set the PWM to 50
    Delay_us_bySysTick(9000);
    
    uint8_t keepIndex = 1;
    while(keepIndex < count &&  infrared.IR_Status == IR_IDLE) {
      
        if((keepIndex & 1) == 0) {
            //Turn on the transmit status light
             SendLight_ON();
             __HAL_TIM_SET_COUNTER(&htim2, 0);
             __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 946);   //  Set the PWM to 50
             Delay_us_bySysTick(tempKeep[keepIndex] - 25);
             

            
        }else {
            //Turn off the transmit status light
            SendLight_OFF();
            __HAL_TIM_SET_COUNTER(&htim2, 0);
            __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);   // Set the PWM to 0
            Delay_us_bySysTick(tempKeep[keepIndex] + 25);
            
          
        }
        
        
        keepIndex++;
    
    }
    
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);   // Set the PWM to 0
    SendLight_OFF();
    free(buffer);


}


只要这段代码运行任务就不正常

操作环境、软件版本等信息

我的操作系统是Win11 64位的,软件使用6.6.1的STM32CubeMX生成的代码,编译器用的是8.3.2的IAR Embedded Workbench

尝试过的解决方法

我试过直接将

 case 2: 
                //send infrared signal
                ir_send();
                
                break;

改为

 case 2: 
          
             SendLight_ON();
             HAL_Delay(1000);
             SendLight_OFF();
                
                break;


发现可以正常闪灯,任务也可以重复运行

我想要达到的结果

我希望我的红外发射过后,所有的任务还能够保持正常的运行

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 5月11日
    • 创建了问题 5月3日

    悬赏问题

    • ¥30 STM32 INMP441无法读取数据
    • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
    • ¥15 用visualstudio2022创建vue项目后无法启动
    • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
    • ¥500 把面具戴到人脸上,请大家贡献智慧
    • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
    • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
    • ¥30 c#打开word开启修订并实时显示批注
    • ¥15 如何解决ldsc的这条报错/index error
    • ¥15 VS2022+WDK驱动开发环境