usblink.c
文件中,包含两个任务usblinkRxTask
和usblinkTxTask
。
这两个任务是与上位机通信而设置的。
USB 通信发送任务。该任务主要负责发送 atkpTxTask 发送过来的数据 包,这些数据包主要是传感器数据、姿态数据等。
代码很短就直接贴上了
//USB发送ATKPPacket任务
void usblinkTxTask(void *param)
{
atkp_t p;
u8 sendBuffer[64];
u8 cksum;
u8 dataLen;
while(1)
{
xQueueReceive(txQueue, &p, portMAX_DELAY);//一直等待
sendBuffer[0] = UP_BYTE1;//上行帧头AA
sendBuffer[1] = UP_BYTE2;//上行帧头AA
sendBuffer[2] = p.msgID;
sendBuffer[3] = p.dataLen;
memcpy(&sendBuffer[4], p.data, p.dataLen);//拷贝p.data到sendBuffer
cksum = 0;
for (int i = 0; i < p.dataLen+4; i++)
{
cksum += sendBuffer[i];
}
dataLen = p.dataLen + 5;
sendBuffer[dataLen - 1] = cksum;
usbsendData(sendBuffer, dataLen);
ledseqRun(DATA_TX_LED, seq_linkup);/*运行led的sequence序列*/
}
}
这个任务就是将txQueue队列,接收到p中,再按照上位机格式存到数组sendBuffer[]中。对匿名上位机的格式,在上一节已经叙述过了,这里不再过多解释。
USB 通信接收任务。该任务主要负责接收上位机发下来(USB 虚拟串口方式)的数据,然后对数据进行打包和校验,打包成 ATKP 格式并校验无误后发送到 atkpRxAnlTask 的接收队列里。
//USB虚拟串口接收ATKPPacket任务
void usblinkRxTask(void *param)
{
u8 c;
u8 dataIndex = 0;
u8 cksum = 0;
rxState = waitForStartByte1;
while(1)
{
if (usbGetDataWithTimout(&c))//radiolink的是uartslkGetDataWithTimout(&c)
{
switch(rxState)
{
case waitForStartByte1:
rxState = (c == DOWN_BYTE1) ? waitForStartByte2 : waitForStartByte1;
cksum = c;
break;
case waitForStartByte2:
rxState = (c == DOWN_BYTE2) ? waitForMsgID : waitForStartByte1;
cksum += c;
break;
case waitForMsgID:
rxPacket.msgID = c;
rxState = waitForDataLength;
cksum += c;
break;
case waitForDataLength:
if (c <= ATKP_MAX_DATA_SIZE)
{
rxPacket.dataLen = c;
dataIndex = 0;
rxState = (c > 0) ? waitForData : waitForChksum1; /*c=0,数据长度为0,校验1*/
cksum += c;
} else
{
rxState = waitForStartByte1;
}
break;
case waitForData:
rxPacket.data[dataIndex] = c;
dataIndex++;
cksum += c;
if (dataIndex == rxPacket.dataLen)
{
rxState = waitForChksum1;
}
break;
case waitForChksum1:
if (cksum == c) /*所有校验正确*/
{
ledseqRun(DATA_RX_LED, seq_linkup);
atkpReceivePacketBlocking(&rxPacket);
}
else /*校验错误*/
{
rxState = waitForStartByte1;
IF_DEBUG_ASSERT(1);
}
rxState = waitForStartByte1;
break;
default:
ASSERT(0);
break;
}
}
else /*超时处理*/
{
rxState = waitForStartByte1;
}
}
}
将虚拟串口接收的数据,存入rxPacket结构体中,校验正确则运行led,并死等将rxPacket发送到rxQueue队列中。