问题描述
在对接调试中,有时候需要看16进制的协议,这个往往是比较晦涩的,当时间旧了之后再去看这个协议就很烦,于是想能否直接在协议输出数据的时候直接格式化输出
问题分析
此处使用数据结构的自动计算偏移拆分协议
协议格式:注意协议是2级指令协议,在data域还有一层协议
typedef struct
{
uint8_t Sof;
uint8_t dev;
uint8_t cmd;
uint8_t seqid[4];
uint8_t Len;
uint8_t Data[SPI_PAC_DATA_MAX]; // DATA 与中有很多小指令格式:[ cmd(1b) + len(1b) + data(nb) ]
uint8_t Xor;
uint8_t Eof;
} spi_pac_t;
协议解析函数:
if ((port_ant[port].dbg_en.bits.shex_en == 1) && (((uint8_t *)send_buf)[(unsigned long)(&((spi_pac_t *)0)->Len)] != 0x7F))
{
uint8_t i;
uint8_t *pdata = (uint8_t *)send_buf;
uint8_t cmd_pos = 0;
uint8_t len_pos = 0;
uint8_t dtq_pos = 0;
uint8_t crc_pos = (unsigned long)(&((spi_pac_t *)0)->Data) + tpac->Len;
LOG_RAW("[%d]: [ %d:%02x ] s_SPI%d: cmd:%02x, crc: data:", HAL_GetTick(),
*(uint32_t *)(tpac->seqid),
tpac->Data[tpac->Len], port, ((uint8_t *)send_buf)[(unsigned long)(&((spi_pac_t *)0)->Len)]);
for (i = 0; i < tpac->Len + 10; i++)
{
if (port_ant[port].dbg_en.bits.scmd_en == 1)
{
/* s0: SPI 层指令切割 */
switch (i)
{
case (unsigned long)(&((spi_pac_t *)0)->Sof):
LOG_RAW("\nsof:");
break;
case (unsigned long)(&((spi_pac_t *)0)->dev):
LOG_RAW("\ndev:");
break;
case (unsigned long)(&((spi_pac_t *)0)->cmd):
LOG_RAW("\ncmd:");
break;
case (unsigned long)(&((spi_pac_t *)0)->seqid):
LOG_RAW("\nseq:");
break;
case (unsigned long)(&((spi_pac_t *)0)->Len):
LOG_RAW("\nlen:");
break;
case (unsigned long)(&((spi_pac_t *)0)->Data):
cmd_pos = (unsigned long)(&((spi_pac_t *)0)->Data);
len_pos = (unsigned long)(&((spi_pac_t *)0)->Data) + 1;
dtq_pos = (unsigned long)(&((spi_pac_t *)0)->Data) + 2;
break;
}
if (i == crc_pos)
LOG_RAW("\ncrc:");
if (i == (crc_pos + 1))
LOG_RAW("\neof:");
/* s1: DTQ 层指令切割 */
if (((cmd_pos > 0) && (i == cmd_pos)) && (crc_pos > i))
LOG_RAW("\ndtq_cmd:");
if (((len_pos > 0) && (i == len_pos)) && (crc_pos > i))
LOG_RAW(" len:");
if (((dtq_pos > 0) && (i == dtq_pos)) && (crc_pos > i))
{
LOG_RAW(" dat:");
cmd_pos = dtq_pos + pdata[len_pos];
len_pos = cmd_pos + 1;
dtq_pos = cmd_pos + 2;
}
}
LOG_RAW(" %02x", pdata[i]);
}
LOG_RAW("\n\n");
}
日志输出效果如下:
00> [80085]: [ 2430:1a ] s_SPI0: cmd:10, crc: data:
00> sof: 61
00> dev: 02
00> cmd: 10
00> seq: 7e 09 00 00
00> len: 73
00> dtq_cmd: 01 len: 4b dat: 64 00 00 00 08 63 00 00 00 08 62 00 00 00 08 61 00 00 00 08 ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00> dtq_cmd: 09 len: 07 dat: 67 84 7c 66 00 00 40
00> dtq_cmd: 0c len: 13 dat: 08 08 08 08 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00> dtq_cmd: 0e len: 06 dat: 01 04 07 9f 3b 83
00> crc: 1a
00> eof: 21
相对于满屏的16进制,这个稍微看起来会更加容易理解些。使用这个格式一下数据,在排查协议异常的问题就会方便很多