添加232数据接收和判决

基本完成功能
已简单测试
This commit is contained in:
CSSC-WORK\murmur 2023-07-21 16:02:32 +08:00
parent dec52d5424
commit 5e48663d0b
4 changed files with 176 additions and 106 deletions

View File

@ -365,16 +365,25 @@ int packAndSendLoc()
} }
//3.2.9深度异常告警 //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[]={}; uint8_t loc[10];
uint8_t dout[200];
size_t nlen = getAndCheckLoc(loc, 1);
rt_memcpy(din+6, loc, 8);//位置数据从【】字节开始共8个字节
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("位置数据加密完成"); LOG_D("位置数据加密完成");
upSend(dout, nlen); 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) 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; 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端 //原计划将指令粗解析放在上位机考虑到上位机到位时间晚现放到MCU端
/** /**
* @brief 3S数据0x5AA50xED * @brief 3S数据0x5AA50xED
@ -526,59 +573,39 @@ void parse3SData(uint8_t *din, size_t count)
| Header | Header | targetAddr | sourceAddr | mainCMD | subCMD | lenH | lenL | data1 | ... | dataN | BbccCRC | tail | | Header | Header | targetAddr | sourceAddr | mainCMD | subCMD | lenH | lenL | data1 | ... | dataN | BbccCRC | tail |
+--------+--------+------------+------------+---------+--------+------+------+-------+-----+-------+---------+------+ +--------+--------+------------+------------+---------+--------+------+------+-------+-----+-------+---------+------+
*/ */
uint8_t head[]={0x5A,0xA5}; if (chk3SDataValid(din, count) != RT_EOK) {
//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));
return; return;
} }
if (din[count-1] != 0xED)
{
LOG_W("0x%02X != 0xED,帧尾不匹配",din[count-1]);
return;
}
// uint8_t dout[200]; // uint8_t dout[200];
// size_t len=0; // 未采用switch case
if (din[2] == ADDR_TT)//仅给TT的消息 if (din[2] == ADDR_TT)//仅给TT的消息
{ {
ttRunCMD(din,count); ttRunCMD(din,count);
} }
if (din[3] == ADDR_3S)//给3S的指令需要再加工返回数据可能也需要再加工 if (din[2] == ADDR_3S)//给3S的指令需要再加工返回数据可能也需要再加工
{ {
// //
xpParse(din,count); 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) 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."); LOG_I("data is ACK.");
} }
else { 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 }; 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] //fstart[4] fnum[2]  bak[2]  ftype[2]  fdlen[2]  fcrc[1] ftccid[4]
uint8_t rst[10]; uint8_t index[10];
size_t n=isInByte(din, len, head, 10, rst); size_t n=isInByte(din, len, head, 10, index);
uint8_t ndin[200]; uint8_t ndin[200];
if (!n) { if (!n) {
LOG_W("无匹配数据"); LOG_W("无匹配数据");
@ -621,12 +648,12 @@ void parseTTData(uint8_t *din, size_t len)
for (size_t i = 0; i < n; i++) for (size_t i = 0; i < n; i++)
{ {
//按帧头分割 //按帧头分割
int cnt=(i+1<n)?rst[i+1]-rst[i]:len-rst[i]; int cnt=(i+1<n)?index[i+1]-index[i]:len-index[i];
memcpy(ndin,din+rst[i],cnt); memcpy(ndin,din+index[i],cnt);
LOG_HEX("frame",16,ndin,cnt); LOG_HEX("frame",16,ndin,cnt);
//判断是否为ACK //判断是否为ACK
if (ndin[cnt-1] != 0xed) { if ((ndin[10]<<8) | ndin[11] == 0x03) {//数据长度只有3
chkACK(ndin, cnt); 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) int cacheData(uint8_t *din, size_t len)
{ {
LOG_I("FUNC = cache and upsend");
static int cnt = 0; static int cnt = 0;
LOG_D("cached size=%d", cnt); LOG_D("cached size=%d", cnt);
char rootDir[22] = "/sd/rxdata/"; char rootDir[22] = "/sd/rxdata/";
// if (!opendir(rootDir))
{
mkdir(rootDir, 0); mkdir(rootDir, 0);
}
strcat(rootDir, "2023_07_19/"); strcat(rootDir, "2023_07_19/");
@ -709,10 +711,8 @@ int cacheData(uint8_t *din, size_t len)
time2Str(ts); time2Str(ts);
//更新文件夹 //更新文件夹
strncpy(rootDir + strlen(rootDir) - 9, ts, 8); strncpy(rootDir + strlen(rootDir) - 9, ts, 8);
// if (!opendir(rootDir))
{
mkdir(rootDir, 0); mkdir(rootDir, 0);
}
//更新文件名 //更新文件名
f[0] = '\0'; f[0] = '\0';
strcat(f, rootDir); 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 #define FUNC_DEMO
#ifdef FUNC_DEMO //测试时导出命令到控制台 #ifdef FUNC_DEMO //测试时导出命令到控制台

View File

@ -71,7 +71,8 @@ enum
//3S //3S
#define _CMD_DEPTH_REQUEST 0x0601 #define _CMD_DEPTH_REQUEST 0x0601
#define _CMD_RTC_CHECK 0x410F #define _CMD_RTC_REQUEST 0x410F
// //
#define ADDR_ANJI 0x42 //0x42? #define ADDR_ANJI 0x42 //0x42?

View File

@ -131,7 +131,7 @@ void show_version(void)
uint8_t t[10]; uint8_t t[10];
size_t len=time2Byte(t); size_t len=time2Byte(t);
bytes2str(t, len, 10, "", str); 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,); MSH_CMD_EXPORT(show_version,);

View File

@ -30,6 +30,7 @@
#define SAMPLE_UART_NAME "uart3" /* 串口设备名称 */ #define SAMPLE_UART_NAME "uart3" /* 串口设备名称 */
#endif #endif
#define MAX_SIZE_TO_SAVE 1024*2 #define MAX_SIZE_TO_SAVE 1024*2
#define MIN_FRAME_LEN 27
/* 串口接收消息结构*/ /* 串口接收消息结构*/
struct rx_msg 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; struct rx_msg msg;
rt_err_t result; 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.dev = dev;
msg.size = size; msg.size = cachecnt;
result = rt_mq_send(&rx_mq, &msg, sizeof(msg)); result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
if ( result == -RT_EFULL) 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"); rt_kprintf("message queue full\n");
} }
cachecnt = 0;
return result; return result;
} }
struct rx_msg msg; struct rx_msg msg;
@ -107,29 +116,29 @@ static void serial_thread_entry(void *parameter)
/* 启动定时器1 */ /* 启动定时器1 */
if (timer1 != RT_NULL) if (timer1 != RT_NULL)
rt_timer_start(timer1); rt_timer_start(timer1);
LOG_D("rec cnt=%d",rx_length); LOG_I("%d Bytes received from RS232",rx_length);
LOG_HEX("rx:",16,rx_buffer,rx_length);//print what received. LOG_HEX("232rx:",16,rx_buffer,rx_length);//print what received.
parseRS232(rx_buffer, rx_length);
#ifdef TR_ACK #ifdef TR_ACK
/* 回传收到的消息 */ /* 回传收到的消息 */
rt_device_write(serial, 0, rx_buffer+rx_length, rx_length); rt_device_write(serial, 0, rx_buffer+rx_length, rx_length);
#endif #endif
if (0 && currLen > 1024) //大于1k则存盘 // if (0 && currLen > 1024) //大于1k则存盘
{ // {
//
int fd =open(f,O_WRONLY | O_CREAT|O_APPEND); // int fd =open(f,O_WRONLY | O_CREAT|O_APPEND);
if(fd <0) // if(fd <0)
{ // {
LOG_E("open file %s failed!", f); // LOG_E("open file %s failed!", f);
} // }
else // else
{ // {
write(fd,rx_buffer,rx_length); // write(fd,rx_buffer,rx_length);
close(fd); // close(fd);
currLen = 0; // currLen = 0;
rx_length=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); MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
INIT_COMPONENT_EXPORT(uart_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[]) void sendData(int argc, char *argv[])
{ {