添加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深度异常告警
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数据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 |
+--------+--------+------------+------------+---------+--------+------+------+-------+-----+-------+---------+------+
*/
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 //测试时导出命令到控制台

View File

@ -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?

View File

@ -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,);

View File

@ -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[])
{