关于STM32 uC/OS-II中任务调度和串口丢数据的原因

博客探讨了在STM32使用uC/OS-II操作系统时,由于任务调度导致的串口数据丢失问题。作者意识到串口接收应当在中断中处理,而非任务中,以避免delay_ms函数执行时的数据丢失。同时指出,当串口数据处理与中断接收共享全局变量RxCounter1时,需确保其互斥访问,以解决可能出现的并发访问问题。

贴上代码,记录遇到的问题:这部分代码只是记录调试遇到的问题,和当时的一些想法,欢迎拍砖。

void uart4_task(void *pdata)
{     
	//INT8U RxBuffer1[MAX_SERIAL_LEN4];//UART3D 接收缓存数组是全局的和局部的效果一样
	  unsigned char i=0,RxCounter1=0,checksum=0;	
	unsigned char bTemp1,bTemp2;
    while(1){
       if(USART_GetFlagStatus(UART4, USART_FLAG_RXNE) != RESET)
       {   
          // USART_ClearFlag(UART4, USART_FLAG_RXNE);
           RxBuffer1[RxCounter1++] = USART_ReceiveData(UART4);  //将读寄存器的数据缓存到接收缓冲区里
				     USART_ClearFlag(UART4, USART_FLAG_RXNE);
				 
           if(RxBuffer1[RxCounter1-1]=='$'){RxBuffer1[0]='$'; RxCounter1=1;}    //判断起始标志
           if(RxBuffer1[RxCounter1-1]==0x0a)   //判断结束标志是否是0x0d 0x0a
           {  
// 						 SendChar3 ('A'); //201402071101  
// 						 SendChar3 (RxCounter1); //201402071101 // 为什么RxCounter1的值才是17
// 						 //usart4_flag=1;
// 						 SendChar3 ('A'); //201402071101  
				//20140210
						 for(i=1; i< RxCounter1-5; i++)  {checksum=checksum^RxBuffer1[i];}//计算收到数据的校验值
						// unsigned char bTemp1,bTemp2;
    //ASCLL 变字符
            bTemp1 = checksum >> 4;
              if(bTemp1 > 9)bTemp1 += 0x37;
              else          bTemp1 += 0x30; 
     
            bTemp2 = checksum & 0x0f;
              if(bTemp2 > 9)bTemp2 += 0x37;
              else         bTemp2 += 0x30; 
     //ASCLL 变字符
						 vSendSerialString3(RxBuffer1);
						 //if((bTemp1==RxBuffer1[RxCounter1-4])&&(bTemp2==RxBuffer1[RxCounter1-3])){//判断校验是否正确,若正确则执行此块语句
// 		//20140210				 
            for(i=0; i< RxCounter1; i++) {TxBuffer1[i] = RxBuffer1[i];/* RxBuffer1[i] = 0;*/ }//将接收缓冲器的数据转到发送缓冲区,准备转发//wogaide                                             //接收成功标志
             Rec_Len=RxCounter1;
						// RxBuffer1[MAX_SERIAL_LEN4]={0};//毎接收完整的一帧RMC消息,接收缓冲区清零20140208
						//  memset(RxBuffer1,0,sizeof(RxBuffer1));//201402081024
						 //usart4_flag=1;//完整的一帧RMC消息标识20140208
             RxCounter1=0; //毎接收完一帧RMC消息,RxCounter1归零20140208   
//              if(TxBuffer1[3]=='R'&& TxBuffer1[4]=='M'&&TxBuffer1[5]=='C')
//               {
//                 GPRMC_DAT();
//               }      //接收完成,传送信号量
						usart4_flag=1;	
				    	//}else{SendChar3 ('A');} //201402101329
           } 
      }
			//delay_ms(10);//这个地方的延时不能太小,否则UCOS任务得不到调度,太长的话影响串口数据的处理
   };
}

串口接收的处理不应该放在这个任务中,应该放在中断中, 否则delay_ms函数执行时会丢掉很多数据,我之前就没有考虑到这块,就耽误了很多不应该耽误的宝贵时间。

若将串口接收数据放到中断里,串口接收的计数值RxCounter1是一个全局变量,在中断接收中, 收到一个字节有效数据就自加,收到帧结束就RxCounter1置零,而在对串口数据的处理中,需要使用到RxCounter1这个全局变量,有可能在串口中断处理的过程中,RxCounter1的值已经被中断接收修改了,这里就有问题了,中断修改RxCounter1和对串口数据的处理所使用的RxCounter1应为互斥访问。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值