问题遇到的现象和发生背景
我为我的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;
发现可以正常闪灯,任务也可以重复运行
我想要达到的结果
我希望我的红外发射过后,所有的任务还能够保持正常的运行