跪求关于F4+uCOSIII多串口数据处理任务出现丢数问题

2019-07-20 15:40发布

跪求各位大神指教,我在调试STM32F429+uCOSIII多串口数据处理任务的时候,出现了数据丢失现象。

我使用了五个串口中断,USART1、USART6、USART3、UART7、USART2(模拟时钟),使用串口调试助手模拟设备发送串口数据。
在main函数中设置了4个任务来获取前四路串口的数据,并使用USART2的数据打上时间戳,然后使用FATFS将数据保存到TF卡上

当我设置自动发送周期一样的时候(比如都是500ms),数据完整无丢失
但是如果有一个发送周期不一致,比如250ms或1000ms,则会出现数据无故多一位或少一些的情况:

比如 我让四个串口发送1.111,2.222,3.333,让USART2发送2017.3.31,12:34:56
则会出现:
22017.3.31,12:34:56,1.111,2.222,3.333
或者
2017.3.31,12:34:56,11.111,2.222,3.333
甚至前面的时间戳丢失一大部分数据


请教各位大神,是任务设置的问题,还是任务调度的问题,还是串口中断优先级的问题呢。
程序由于仓促没贴上,下午贴上。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
6条回答
talenthn
1楼-- · 2019-07-20 21:07
//任务优先级
#define START_TASK_PRIO                3
//任务堆栈大小       
#define START_STK_SIZE                 128
//任务控制块
OS_TCB StartTaskTCB;
//任务堆栈       
CPU_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *p_arg);

//任务优先级
#define CAN_TASK_PRIO                4
//任务堆栈大小       
#define CAN_STK_SIZE                 128
//任务控制块
OS_TCB CAN_TaskTCB;
//任务堆栈       
CPU_STK CAN_TASK_STK[CAN_STK_SIZE];
void Can_task(void *p_arg);

//任务优先级
#define         TIME_TASK_PRIO                9
//任务堆栈大小       
#define TIME_STK_SIZE                 1024
//任务控制块
OS_TCB TIME_TaskTCB;
//任务堆栈       
CPU_STK TIME_TASK_STK[TIME_STK_SIZE];
void Time_task(void *p_arg);

//任务优先级
#define COM1_TASK_PRIO                7
//任务堆栈大小       
#define COM1_STK_SIZE                 1024
//任务控制块
OS_TCB COM1_TaskTCB;
//任务堆栈       
CPU_STK COM1_TASK_STK[COM1_STK_SIZE];
void Com1_task(void *p_arg);

//任务优先级
#define COM6_TASK_PRIO                8
//任务堆栈大小       
#define COM6_STK_SIZE                 1024
//任务控制块
OS_TCB COM6_TaskTCB;
//任务堆栈       
CPU_STK COM6_TASK_STK[COM6_STK_SIZE];
//任务函数
void Com6_task(void *p_arg);

//任务优先级
#define COM3_TASK_PRIO                5
//任务堆栈大小       
#define COM3_STK_SIZE                 1024
//任务控制块
OS_TCB COM3_TaskTCB;
//任务堆栈       
CPU_STK COM3_TASK_STK[COM3_STK_SIZE];
//任务函数
void Com3_task(void *p_arg);

//任务优先级
#define COM7_TASK_PRIO                6
//任务堆栈大小       
#define COM7_STK_SIZE                 1024
//任务控制块
OS_TCB COM7_TaskTCB;
//任务堆栈       
CPU_STK COM7_TASK_STK[COM7_STK_SIZE];
//任务函数
void Com7_task(void *p_arg);


这是串口数据处理任务:(只写了一个)
void Com1_task(void *p_arg)
{
        CPU_SR_ALLOC();
        OS_ERR err;
        OS_MSG_SIZE size;
        u8 * msg1;
        p_arg = p_arg;

        printf("Run COM1 ");       

        while(1)
        {
                msg1=OSTaskQPend((OS_TICK                )500,
                                (OS_OPT                        )OS_OPT_PEND_BLOCKING,
                                (OS_MSG_SIZE*        )&size,               
                                (CPU_TS*                )0,
                                (OS_ERR*                )&err);
               
                sprintf(u1data,"UART1:%s,%s",timedata,msg1);               
                printf("%s",u1data);
//                res_sd = f_lseek(&file1,f_size(&file1));
//                do
//                {
//                        res_sd = f_write(&file1,u1data,strlen(u1data),&fnum);
//                }
//                while(fnum<strlen(u1data));
//                f_sync(&file1);

                OSTimeDlyHMSM(0,0,0,500,OS_OPT_TIME_HMSM_STRICT,&err); //延时ms
        }
}

这是其中相对应的串口中断:
void USART1_IRQHandler(void)                       
{
                u8 Res;
//        unsigned int i;
                OS_ERR err;
//                CPU_SR_ALLOC();

        OSIntEnter();
       
        if((__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_RXNE)!=RESET))  
        {
    HAL_UART_Receive(&UART1_Handler,&Res,1,1000);
                if((Res!=0x0d)&&(Res!=0x0a))
                {
                        USART1_RX_BUF[USART1_RX_STA]=Res;
                        USART1_RX_STA++;
                }
                else if(Res==0x0d)
                {

                        USART1_RX_BUF[USART1_RX_STA]=0x0d;
                        USART1_RX_BUF[USART1_RX_STA+1]=0x0a;
                        USART1_RX_BUF[USART1_RX_STA+2]='';

                        OSTaskQPost((OS_TCB*                )&COM1_TaskTCB,               
                                                                        (void*                )&USART1_RX_BUF,
                                                                        (OS_MSG_SIZE)sizeof(USART1_RX_BUF),
                                                                        (OS_OPT                )OS_OPT_POST_FIFO,
                                                                        (OS_ERR*        )&err);

                        USART1_RX_STA=0;

                }
                else
                {
                        USART1_RX_STA=0;
                }
               
                if(USART1_RX_STA>(USART_REC_LEN-1))USART1_RX_STA=0;
                 
        }
        HAL_UART_IRQHandler(&UART1_Handler);       

        OSIntExit();                                                                                           
                                                                                         

}
talenthn
2楼-- · 2019-07-21 01:21
 精彩回答 2  元偷偷看……
talenthn
3楼-- · 2019-07-21 05:47
 精彩回答 2  元偷偷看……
hi我歌月徘徊
4楼-- · 2019-07-21 09:44
高优先级的在接收 低优先级的肯定会把数据丢了  应该都把dma打开 啥也不管 先把数据存下再说
talenthn
5楼-- · 2019-07-21 10:59
hi我歌月徘徊 发表于 2017-3-31 15:13
高优先级的在接收 低优先级的肯定会把数据丢了  应该都把dma打开 啥也不管 先把数据存下再说

您的意思是串口DMA方式接收么
talenthn
6楼-- · 2019-07-21 16:24
 精彩回答 2  元偷偷看……

一周热门 更多>