添加232数据接收和判决
基本完成功能 已简单测试
This commit is contained in:
parent
dec52d5424
commit
5e48663d0b
@ -365,16 +365,25 @@ int packAndSendLoc()
|
||||
}
|
||||
|
||||
//3.2.9深度异常告警
|
||||
int packDeepMsg(uint8_t *din, int len, uint8_t *dout)
|
||||
|
||||
/**
|
||||
* 将位置信息合入深度信息
|
||||
* @param din
|
||||
* @param len
|
||||
* @param dout
|
||||
* @return
|
||||
*/
|
||||
int packDepthMsg(uint8_t *din, int len)
|
||||
{
|
||||
//获取并更新位置信息
|
||||
uint8_t loc[]={};
|
||||
|
||||
|
||||
rt_memcpy(din+6, loc, 8);//位置数据从【】字节开始,共8个字节
|
||||
uint8_t loc[10];
|
||||
uint8_t dout[200];
|
||||
size_t nlen = getAndCheckLoc(loc, 1);
|
||||
|
||||
rt_memcpy(din+0, loc, nlen);//位置数据从【】字节开始,共len个字节
|
||||
LOG_HEX("depth",16,din,len);
|
||||
//加密。因加密后数据长度会变化,故不能只加密位置数据。
|
||||
size_t nlen = cryptByte(din, len, dout);
|
||||
nlen = cryptLocMsg(din, len, dout);
|
||||
LOG_D("位置数据加密完成");
|
||||
upSend(dout, nlen);
|
||||
|
||||
@ -506,10 +515,48 @@ void ttRunCMD(uint8_t *din, size_t len)
|
||||
|
||||
RT_WEAK int xpParse(uint8_t * din, size_t len)
|
||||
{
|
||||
LOG_D("直接调用小彭的函数进行处理。");
|
||||
// LOG_D("直接调用小彭的函数进行处理。");
|
||||
char str[200] = "RCV:";
|
||||
|
||||
int cmd = (din[4] << 8) + din[5];
|
||||
switch (cmd)
|
||||
{
|
||||
case _CMD_RTC_REQUEST: //不加前后缀的指令,仅有少数
|
||||
bytes2str(din, len, 16, "", str);
|
||||
break;
|
||||
default: //默认加前后缀
|
||||
bytes2str(din, len, 16, "", str + 4);
|
||||
strcat(str, "\r\n");
|
||||
break;
|
||||
}
|
||||
LOG_D("send '%s' to 3S.", str);
|
||||
sendTo3S(str, strlen(str));//作为字符串发送
|
||||
return 0;
|
||||
}
|
||||
|
||||
int chk3SDataValid(uint8_t *din, size_t count)
|
||||
{
|
||||
uint8_t head[]={0x5A,0xA5};
|
||||
//header[4] addr[2] func[2] len[2] data[N] fcrc[1] tail[1]
|
||||
if (memcmp(din,head,sizeof(head)))
|
||||
{
|
||||
LOG_W("0x5AA5[√] != 0x%02X%02X[×],帧头不匹配",din[0],din[1]);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if (din[count-2] != bccCRC(din+2,count-2-2))//校验位为1个字节,采用异或运算,从指令的第3个字节开始,到奇偶校验位的前一个字节结束
|
||||
{
|
||||
LOG_W("0x%02X[√] != 0x%02X[×],校验值不匹配", bccCRC(din+2,count-2-2),din[count-2] );
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
if (din[count-1] != 0xED)
|
||||
{
|
||||
LOG_W("0xED[√] != 0x%02X[×],帧尾不匹配",din[count-1]);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
// LOG_D("valid data.");
|
||||
return RT_EOK;
|
||||
}
|
||||
//原计划将指令粗解析放在上位机,考虑到上位机到位时间晚,现放到MCU端
|
||||
/**
|
||||
* @brief 校验、解析3S数据,以0x5AA5开头0xED结尾。
|
||||
@ -526,59 +573,39 @@ void parse3SData(uint8_t *din, size_t count)
|
||||
| Header | Header | targetAddr | sourceAddr | mainCMD | subCMD | lenH | lenL | data1 | ... | dataN | BbccCRC | tail |
|
||||
+--------+--------+------------+------------+---------+--------+------+------+-------+-----+-------+---------+------+
|
||||
*/
|
||||
uint8_t head[]={0x5A,0xA5};
|
||||
//header[4] addr[2] func[2] len[2] data[N] fcrc[1] tail[1]
|
||||
uint8_t rst = memcmp(din,head,sizeof(head[0]));
|
||||
if (rst)
|
||||
{
|
||||
LOG_W("0x%02X%02X != 0x%5AA5,帧头不匹配",din[0],din[1]);
|
||||
return;
|
||||
}
|
||||
if (din[count-2] != bccCRC(din+2,count-2-2))//校验位为1个字节,采用异或运算,从指令的第3个字节开始,到奇偶校验位的前一个字节结束
|
||||
{
|
||||
LOG_W("0x%02X != 0x%02X,校验值不匹配",din[count-2] , bccCRC(din+2,count-2-2));
|
||||
if (chk3SDataValid(din, count) != RT_EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (din[count-1] != 0xED)
|
||||
{
|
||||
LOG_W("0x%02X != 0xED,帧尾不匹配",din[count-1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// uint8_t dout[200];
|
||||
// size_t len=0;
|
||||
// 未采用switch case
|
||||
if (din[2] == ADDR_TT)//仅给TT的消息
|
||||
{
|
||||
ttRunCMD(din,count);
|
||||
}
|
||||
if (din[3] == ADDR_3S)//给3S的指令,需要再加工,返回数据可能也需要再加工
|
||||
if (din[2] == ADDR_3S)//给3S的指令,需要再加工,返回数据可能也需要再加工
|
||||
{
|
||||
//
|
||||
|
||||
xpParse(din,count);
|
||||
|
||||
|
||||
|
||||
//以下处理逻辑作废
|
||||
//绝大部分数据均需要转换。详见《主要指令一览》
|
||||
// int cmd = (din[4]<<8) + din[5]
|
||||
// switch (cmd)
|
||||
// {
|
||||
// case _CMD_RTC_CHECK:
|
||||
// case 0:
|
||||
// /* 不转换 */
|
||||
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// //转换
|
||||
// char rst[]="";
|
||||
// bytes2str(din,count,16,"",rst);
|
||||
// break;
|
||||
// }
|
||||
// //发送
|
||||
}
|
||||
if (din[2] == ADDR_ANJI)
|
||||
{
|
||||
//可能需要对回传信息再加工,如查询深度需要加入位置坐标
|
||||
//或是缓存任务数据
|
||||
//故需要对数据进行简单判断
|
||||
int cmd = (din[4] << 8) + din[5];
|
||||
switch (cmd)
|
||||
{
|
||||
case _CMD_DEPTH_REQUEST:
|
||||
packDepthMsg(din, count);
|
||||
break;
|
||||
default:
|
||||
cacheData(din, count);
|
||||
}
|
||||
// upSend(din, count);
|
||||
}
|
||||
}
|
||||
|
||||
void chkACK(uint8_t *msg, size_t size)
|
||||
@ -589,7 +616,7 @@ void chkACK(uint8_t *msg, size_t size)
|
||||
LOG_I("data is ACK.");
|
||||
}
|
||||
else {
|
||||
LOG_W("NONE FUNCTION MATCH.");
|
||||
LOG_W("INVALID DATA.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,8 +638,8 @@ void parseTTData(uint8_t *din, size_t len)
|
||||
*/
|
||||
uint8_t head[]={0x88,0xAA,0xBB,0x88, 0x00,0x01, 0x00,0x00, 0x70,0x21, 0x00,0xaa, 0x00, 0x27,0x22,0x22,0x22 };
|
||||
//fstart[4] fnum[2] bak[2] ftype[2] fdlen[2] fcrc[1] ftccid[4]
|
||||
uint8_t rst[10];
|
||||
size_t n=isInByte(din, len, head, 10, rst);
|
||||
uint8_t index[10];
|
||||
size_t n=isInByte(din, len, head, 10, index);
|
||||
uint8_t ndin[200];
|
||||
if (!n) {
|
||||
LOG_W("无匹配数据");
|
||||
@ -621,12 +648,12 @@ void parseTTData(uint8_t *din, size_t len)
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
//按帧头分割
|
||||
int cnt=(i+1<n)?rst[i+1]-rst[i]:len-rst[i];
|
||||
memcpy(ndin,din+rst[i],cnt);
|
||||
int cnt=(i+1<n)?index[i+1]-index[i]:len-index[i];
|
||||
memcpy(ndin,din+index[i],cnt);
|
||||
LOG_HEX("frame",16,ndin,cnt);
|
||||
|
||||
//判断是否为ACK
|
||||
if (ndin[cnt-1] != 0xed) {
|
||||
if ((ndin[10]<<8) | ndin[11] == 0x03) {//数据长度只有3
|
||||
chkACK(ndin, cnt);
|
||||
}
|
||||
//数据
|
||||
@ -653,29 +680,6 @@ void parseTTData(uint8_t *din, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
// switch (din[24] & 0x7F) // 识别指令的目标地址
|
||||
// {
|
||||
// case _ONLY_FOR_TT:
|
||||
// ttRunCMD(rawData, len - 27);
|
||||
// break;
|
||||
// case _ONLY_FOR_3S:
|
||||
// /* code */
|
||||
// // 发送数据至3S
|
||||
// break;
|
||||
// case _FOR_BOTH:
|
||||
// // 发送数据至3S
|
||||
|
||||
// // 等待返回数据
|
||||
|
||||
// // 打包
|
||||
|
||||
// // 上传
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// LOG_W("未识别到指令的目标地址");
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -687,13 +691,11 @@ void parseTTData(uint8_t *din, size_t len)
|
||||
*/
|
||||
int cacheData(uint8_t *din, size_t len)
|
||||
{
|
||||
LOG_I("FUNC = cache and upsend");
|
||||
static int cnt = 0;
|
||||
LOG_D("cached size=%d", cnt);
|
||||
char rootDir[22] = "/sd/rxdata/";
|
||||
// if (!opendir(rootDir))
|
||||
{
|
||||
mkdir(rootDir, 0);
|
||||
}
|
||||
mkdir(rootDir, 0);
|
||||
|
||||
strcat(rootDir, "2023_07_19/");
|
||||
|
||||
@ -709,10 +711,8 @@ int cacheData(uint8_t *din, size_t len)
|
||||
time2Str(ts);
|
||||
//更新文件夹
|
||||
strncpy(rootDir + strlen(rootDir) - 9, ts, 8);
|
||||
// if (!opendir(rootDir))
|
||||
{
|
||||
mkdir(rootDir, 0);
|
||||
}
|
||||
mkdir(rootDir, 0);
|
||||
|
||||
//更新文件名
|
||||
f[0] = '\0';
|
||||
strcat(f, rootDir);
|
||||
@ -752,6 +752,62 @@ void d_cacheData()
|
||||
}
|
||||
|
||||
|
||||
void parseRS232(uint8_t *din, size_t len)
|
||||
{
|
||||
//有HEX有ASCII,统一按HEX解析
|
||||
uint8_t head[]={0x41, 0x54, 0x2B, 0x53, 0x4E, 0x44, 0x20 };//"AT+SND "
|
||||
uint8_t ndin[400];
|
||||
//如果有无"AT+SND "头的数据混发则难以处理粘包,如果所有数据均以"AT+SND "开头则可以按以下方法(未完全实现)处理
|
||||
//是否存在混发需要核实
|
||||
#ifdef _MIX_DATA
|
||||
uint8_t index[10];
|
||||
size_t n=isInByte(din, len, head, sizeof(head), index);
|
||||
|
||||
if (!n) {
|
||||
LOG_W("无匹配数据");
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
//按帧头分割
|
||||
int cnt=(i+1<n)?index[i+1]-index[i]:len-index[i];
|
||||
memcpy(ndin,din+index[i],cnt);
|
||||
LOG_HEX("frame",16,ndin,cnt);
|
||||
#endif
|
||||
|
||||
#ifndef _MIX_DATA
|
||||
int cnt=len;
|
||||
memcpy(ndin,din,len);
|
||||
#endif
|
||||
//parse
|
||||
size_t offset = 0;
|
||||
if (memcmp(ndin,head,sizeof(head)) == 0) {
|
||||
//有“AT+SND ”帧头,需要处理
|
||||
offset = sizeof(head);
|
||||
}
|
||||
ndin[cnt]='\0';
|
||||
size_t ncnt = str2Byte(ndin+offset, 2, 16, ndin);
|
||||
LOG_HEX("decode",16,ndin,ncnt);
|
||||
if (chk3SDataValid(ndin, ncnt) != RT_EOK) {
|
||||
return;
|
||||
}
|
||||
parse3SData(ndin,ncnt);
|
||||
#ifdef _MIX_DATA
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define FUNC_DEMO
|
||||
|
||||
#ifdef FUNC_DEMO //测试时导出命令到控制台
|
||||
|
@ -71,7 +71,8 @@ enum
|
||||
|
||||
//3S
|
||||
#define _CMD_DEPTH_REQUEST 0x0601
|
||||
#define _CMD_RTC_CHECK 0x410F
|
||||
#define _CMD_RTC_REQUEST 0x410F
|
||||
|
||||
|
||||
//
|
||||
#define ADDR_ANJI 0x42 //0x42?
|
||||
|
@ -131,7 +131,7 @@ void show_version(void)
|
||||
uint8_t t[10];
|
||||
size_t len=time2Byte(t);
|
||||
bytes2str(t, len, 10, "", str);
|
||||
rt_kprintf("SW Version: %s build%s\n","1.43",bytes2str(t, len, 10, "", str));
|
||||
rt_kprintf("SW Version: %s build%s\n","1.44",bytes2str(t, len, 10, "", str));
|
||||
}
|
||||
|
||||
MSH_CMD_EXPORT(show_version,显示版本号);
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define SAMPLE_UART_NAME "uart3" /* 串口设备名称 */
|
||||
#endif
|
||||
#define MAX_SIZE_TO_SAVE 1024*2
|
||||
#define MIN_FRAME_LEN 27
|
||||
/* 串口接收消息结构*/
|
||||
struct rx_msg
|
||||
{
|
||||
@ -61,8 +62,15 @@ static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
struct rx_msg msg;
|
||||
rt_err_t result;
|
||||
|
||||
static cachecnt=0;
|
||||
cachecnt += size;
|
||||
if (cachecnt < MIN_FRAME_LEN) {
|
||||
LOG_W("not enough data, cached and waiting...");//处理半包
|
||||
return;
|
||||
}
|
||||
msg.dev = dev;
|
||||
msg.size = size;
|
||||
msg.size = cachecnt;
|
||||
|
||||
result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
|
||||
if ( result == -RT_EFULL)
|
||||
@ -70,6 +78,7 @@ static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
|
||||
/* 消息队列满 */
|
||||
rt_kprintf("message queue full!\n");
|
||||
}
|
||||
cachecnt = 0;
|
||||
return result;
|
||||
}
|
||||
struct rx_msg msg;
|
||||
@ -107,29 +116,29 @@ static void serial_thread_entry(void *parameter)
|
||||
/* 启动定时器1 */
|
||||
if (timer1 != RT_NULL)
|
||||
rt_timer_start(timer1);
|
||||
LOG_D("rec cnt=%d",rx_length);
|
||||
LOG_HEX("rx:",16,rx_buffer,rx_length);//print what received.
|
||||
|
||||
LOG_I("%d Bytes received from RS232",rx_length);
|
||||
LOG_HEX("232rx:",16,rx_buffer,rx_length);//print what received.
|
||||
parseRS232(rx_buffer, rx_length);
|
||||
#ifdef TR_ACK
|
||||
/* 回传收到的消息 */
|
||||
rt_device_write(serial, 0, rx_buffer+rx_length, rx_length);
|
||||
#endif
|
||||
if (0 && currLen > 1024) //大于1k则存盘
|
||||
{
|
||||
|
||||
int fd =open(f,O_WRONLY | O_CREAT|O_APPEND);
|
||||
if(fd <0)
|
||||
{
|
||||
LOG_E("open file %s failed!", f);
|
||||
}
|
||||
else
|
||||
{
|
||||
write(fd,rx_buffer,rx_length);
|
||||
close(fd);
|
||||
currLen = 0;
|
||||
rx_length=0;
|
||||
}
|
||||
}
|
||||
// if (0 && currLen > 1024) //大于1k则存盘
|
||||
// {
|
||||
//
|
||||
// int fd =open(f,O_WRONLY | O_CREAT|O_APPEND);
|
||||
// if(fd <0)
|
||||
// {
|
||||
// LOG_E("open file %s failed!", f);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// write(fd,rx_buffer,rx_length);
|
||||
// close(fd);
|
||||
// currLen = 0;
|
||||
// rx_length=0;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@ -210,7 +219,11 @@ static int uart_dma_sample(int argc, char *argv[])
|
||||
MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
|
||||
INIT_COMPONENT_EXPORT(uart_dma_sample);
|
||||
|
||||
|
||||
void sendTo3S(uint8_t *din, size_t len)
|
||||
{
|
||||
size_t rst = rt_device_write(serial, 0, din, len);
|
||||
LOG_D("send %d Bytes done.",rst);
|
||||
}
|
||||
|
||||
void sendData(int argc, char *argv[])
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user