论坛元老
- 积分
- 4638
- 金钱
- 4638
- 注册时间
- 2017-7-6
- 在线时间
- 705 小时
|
10金钱
main:里面创建多个任务
static void AppTaskStart (void *p_arg)
{
p_arg = p_arg;
BSP_Init();
OS_CPU_SysTickInit();
#if (OS_TASK_STAT_EN > 0)
OSStatInit();
#endif
initAppStartData();
DeviceInit();
QueueCreate(CABuf,CABUF_QUEUE_ALL_SIZE, CABUF_QUEUE_SIZE, 0, 0);
OSTaskCreate(TaskBMS, 0, StackBMS + (APP_TASK_START_STK_SIZE - 1), APP_TASK_BMS_PRIO);
OSTaskCreate(TaskTouch, 0, StackTouch + (APP_TASK_START_STK_SIZE - 1), APP_TASK_TOUCH_PRIO);
OSTaskCreate(Monitor, 0, StackMonitor + (APP_TASK_START_STK_SIZE - 1), APP_TASK_PEROIDSEND_PRIO);
OSTaskCreate(SendTouch, 0, StackSend + (APP_TASK_START_STK_SIZE - 1), APP_TASK_SEND_PRIO);
OSTaskCreate(AdcProcess, 0, StackADCProcess + (APP_TASK_START_STK_SIZE - 1), APP_ADC_PROCESS_PRIO);
while(1)
{
RunJ1939Interface();
DelayMs(1);
}
}
和上位机通信的任务:
上面的#if 0是原来工程师搞的,读2次队列并读空,打开CAN报文标志if(g_CatchCanDataFlag)和透传CAN报文UartWrite(1, g_RS232SendBuf2, sendSize2);也是在ProModbusRTU_Frame2解析函数里面,可能就是这个读2次的原因。
后面发现上位机稍微数据发送太快,通过串口打印,发现会导致多帧数据叠加在一起,所以后面把他的改了,改成下面的分帧处理,并把透传CAN报文的函数移出来;发现打开CAN报文透传标志后,上位机控制下位机的某些动作失效,偶然性的,可能关机再开机还有可能是测试久了也会。
经过仿真也没看到具体原因,希望大佬指点一下,初次接触ucos。
void Monitor(void *p_arg)
{
CPU_INT08U os_err;
uint16_t len2 = 0;
uint8_t i;
g_pUart232Sem2 = OSSemCreate(1);
uint8_t tempBuffer[128];
uint8_t index = 0;
uint8_t RecvBuf;
uint8_t sendSize2 = 0;
ModbusRTU_Frame_t2 tempBuffer2;
uint16_t DataCRC16 = 0;
while(1)
{
#if 0
OSSemPend(g_pUart232Sem2,0,&os_err); //cnt信号量,大于0,执行该任务;等于0,等待信号量的队列
len2 = ReadComFifo(&g_RS232Fifo2, g_RS232RecvBuf2, sizeof(g_RS232RecvBuf2));
ProModbusRTU_Frame2(g_RS232RecvBuf2, len2);
while(len2 = ReadComFifo(&g_RS232Fifo2, g_RS232RecvBuf2, sizeof(g_RS232RecvBuf2)))
{
ProModbusRTU_Frame2(g_RS232RecvBuf2, len2);
}
if(g_CatchCanDataFlag)
{
OSSemPost(g_pUart232Sem2); //释放信号量,有多少任务等待该g_pUart232Sem2信号量,最高优先级将得到信号量
}
#endif
// #if 0
OSSemPend(g_pUart232Sem2,0,&os_err);
len2 = ReadComFifo(&g_RS232Fifo2, (char *)g_RS232RecvBuf2, sizeof(g_RS232RecvBuf2)); //读取队列多个数据,分帧处理
for(i = 0;i < len2;i++) //循环读取队列所有的数据,分帧处理
{
switch (m_frmAlaysisStep)
{
case 0:
{
if (g_RS232RecvBuf2[i] == 0x7e)
{
index = 0;
tempBuffer[index++] = g_RS232RecvBuf2[i];
m_frmAlaysisStep = 1;
}
}
break;
case 1:
{
tempBuffer[index++] = g_RS232RecvBuf2[i];
if(tempBuffer[index-1] == 0x0D)
{
DataCRC16 = crc16(tempBuffer, index);
if (i+2 < len2)
{
tempBuffer[index++] = g_RS232RecvBuf2[i+1];
tempBuffer[index++] = g_RS232RecvBuf2[i+2];
if(DataCRC16 == ((tempBuffer[index - 2] << 8) + tempBuffer[index - 1]))
{
i += 2; //校验成功,下一帧数据从上一帧校验后面开始循环 不加也行,多执行2次,浪费点时间而已
m_frmAlaysisStep = 0;
ProModbusRTU_Frame2(tempBuffer, index);
}
}
else
{
m_frmAlaysisStep = 0;
break;
}
}
}
break;
default:
{
m_frmAlaysisStep = 0;
}
break;
}
}
if(g_CatchCanDataFlag)
{
if (UsartQueuePop(&buffer, &tempBuffer2) == TRUE)
{
sendSize2 = modbusRTU_Frame2Buf2(&tempBuffer2, g_RS232SendBuf2);
UartWrite(1, g_RS232SendBuf2, sendSize2); //透传CAN报文
}
OSSemPost(g_pUart232Sem2); //释放信号量,有多少任务等待该g_pUart232Sem2信号量,最高优先级将得到信号量
}
// #endif
DelayMs(1);
}
}
ProModbusRTU_Frame2的函数:
void ProModbusRTU_Frame2 (uint8_t *pReqFrameBuf2, uint16_t reqFrameBufSize2)
{
uint16_t sendSize2 = 0,value = 0;
uint16_t i = 0;
ModbusRTU_Frame_t2 *pReqFrame2 = &g_ReqFrame2;
// if(g_CatchCanDataFlag) //用了分帧处理,把这个屏蔽,放外面去
// {
// if (UsartQueuePop(&buffer, &g_RepFrame2) == TRUE)
// {
// sendSize2 = modbusRTU_Frame2Buf2(&g_RepFrame2, g_RS232SendBuf2);
// UartWrite(1, g_RS232SendBuf2, sendSize2);
// }
// }
if (FALSE == buf2ModbusRTU_Frame2(pReqFrameBuf2, reqFrameBufSize2, pReqFrame2))//解析帧失败则直接返回
return;
g_MonitorTimer = 0;
g_MonitorComFlag = 1;
g_usartsendflag = 1;
g_RepFrame2.SOI = g_SOI;
g_RepFrame2.Addr1 = pReqFrame2->Addr1;
g_RepFrame2.Addr2 = pReqFrame2->Addr2;
g_RepFrame2.CMDType = pReqFrame2->CMDType | 0x40;
g_RepFrame2.CMD = (uint8_t)pReqFrame2->CMD;
g_RepFrame2.EOI = g_EOI;
if(pReqFrame2->CMDType == FC_CMDTYPERead)
。。。。。。。。。。。。。逻辑处理的等语句
}
|
|