1.测试方式与代码
??在上一篇文章中,我们通过C代码实现了XMODEM通信协议库设计,本篇文章我们将编写一段测试程序,实现对XMODEM库进行测试。 ??测试过程采用PC串口方式实现,操作系统为UBUNTU20,编译工具为GCC,其实现过程如下所示。
1.1.创建XMODEM对象
??首先,我们需要创建一个XMODEM对象
static xmodem_t xmodem_obj={
XMODEM_DATA_128,
XMODEM_CHK_MD_ADD,
XMODEM_REQ_NONE,
XMODEM_STATE_IDLE,
80,
0,
XMODEM_RX_ST_IDLE,
10,
0,
xmodem_tx,
xmodem_rx,
xmodem_cb,
{0},
0,
0,
};
1.2. 接口函数实现
??在对象中,存在三个接口函数,它们分别为”xmodem_tx”,”xmodem_rx”,”xmodem_cb”这三个函数。 ??其中xmodem_tx实现了XMODEM发送功能,它通过调用系统代码如下:
type_err xmodem_tx(type_uint8 *buf, type_uint16 len)
{
uart_write(uart_fd,(type_char *)buf,len);
return STATE_OK;
}
??xmodem_rx实现了XMODEM数据接收过程,同样调用系统串口实现:
xmodem_rx_st_t xmodem_rx(type_uint8 *buf, type_uint16 buf_len, type_uint16 *len, type_uint16 timeout)
{
type_int16 rx_len=0;
type_uint8 data;
printf("RECEIVING\n\r");
while(rx_len<buf_len)
{
if(uart_read(uart_fd,(type_char *)&data,1)<=0)
{
printf("RX TIMEOUT\n\r");
return XMODEM_RX_ST_TIMEOUT;
}
else if((0x04==data)&&(0==rx_len))
{
buf[rx_len]=data;
rx_len++;
*len=rx_len;
printf("NEW PACKAGE,EOT\n\r");
return XMODEM_RX_ST_OK;
}
else
{
buf[rx_len]=data;
rx_len++;
}
}
*len=rx_len;
printf("NEW PACKAGE,id=%d\n\r",buf[1]);
return XMODEM_RX_ST_OK;
}
??需要注意的是,在LINUX初始化串口时,有几个问题需要注意: 1.采用阻塞方式接收 ??在调用open函数时,不要添加非阻塞参数,初始化代码如下:
type_int32 uart_open(type_char *port)
{
type_int32 fd=-1;
return open(port,O_RDWR|O_NOCTTY);
}
2.解决0x0A,0x0D,0x11,0x13等不正常显示问题 ??在配置参数中屏蔽以下几个标志位:
options.c_iflag &= ~ (INLCR | ICRNL | IGNCR);
options.c_oflag &= ~ (ONLCR | OCRNL | IXOFF);
options.c_iflag &= ~ (BRKINT | ICRNL | INPCK | ISTRIP | IXON);
3.设置超时时间与数据接收长度 ??Linux串口通过配置以下两个参数来控制接收数据长度以及超时时间:
options.c_cc[VTIME] = 40;
options.c_cc[VMIN] = 0;
??其中VTIME为超时时间,以100ms为单位,VMIN为最小接收数据长度,上面的代码表示,如果存在接收数据则返回数据,若一直每收到数据,4秒后超时返回超时状态。
??xmodem_cb函数实现上层对XMODEM接收到的数据处理过程,在本测试过程中,通过终端对收到的数据进行打印。
void xmodem_cb(type_uint8 *buf, type_uint16 len)
{
type_uint16 pos=0;
if(!buf)
{
printf("XMODEM ERR!\n\r");
return;
}
if((buf)&&(0==len))
{
printf("XMODEM FINISH!\n\r");
return;
}
printf("===============================================\n\r");
printf("00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15\n\r");
printf("===============================================\n\r");
while(pos<len)
{
for(type_uint8 i=0;i<16;i++)
{
if(i==15)
printf("%02x",buf[pos++]);
else
printf("%02x,",buf[pos++]);
if(pos>=len)
{
printf("\n\r");
return;
}
}
printf("\n\r");
}
}
1.3. 测试主函数实现
??测试主函数,通过采用多线程实现对XMODEM进行测试,主进程用于获取用户键盘输入,从而控制当前XMODEM状态机的运行。创建线程用于XMODEM系统调用。代码如下:
void main()
{
int key;
type_char lf=0x0A;
uart_fd=uart_open("/dev/ttyUSB0");
if(0>uart_fd)
{
printf("UART OPEN ERR!\n\r");
return;
}
if(uart_set(uart_fd,UART_BAUD_115200,UART_FLOWCTRL_NONE,8,1,UART_PARITY_NONE)!=STATE_OK)
{
printf("UART CFG ERR!\n\r");
uart_close(uart_fd);
return;
}
xmodem_init(&xmodem_obj);
pthread_create(&ntid, NULL, xmodem_pth, NULL);
printf("************************************\n\r");
printf("Press X to start XMODEM transmission\n\r");
printf("Press S to stop XMODEM transmission\n\r");
printf("Press E to exit\n\r");
printf("************************************\n\r");
while(1)
{
key=getch();
switch(key)
{
case 'X':
case 'x':
printf("XMODEM START REQ\n\r");
tcflush(uart_fd,TCIFLUSH);
xmodem_req(&xmodem_obj,XMODEM_REQ_START);
break;
case 'S':
case 's':
printf("XMODEM STOP REQ\n\r");
xmodem_req(&xmodem_obj,XMODEM_REQ_STOP);
break;
case 'E':
case 'e':
uart_close(uart_fd);
exit(0);
default:
break;
}
}
}
??系统运行后,首先对UART和XMODEM进行初始化,初始化代码请详见工程内驱动。随后创建一个线程用于XMODEM系统运行。创建线程完成后打印控制信息,最后进行控制循环。
2. 编译与运行
??打开终端窗口,切换到工程目录下,输入make命令进行编译,正常则会出现下面信息: 继续输入 ./bin/xmodem_sim运行刚编译好的程序,会显示下面的界面
3. 测试
??在测试开始之前,需要准备一个xmodem传输工具,由于linux下的cutecom软件不太稳定,此处推荐Tera Term。以及两个USB转串口板。 ??首先,将两个U转串接口板插入到电脑,一个用于发送,一个用于接收,值得注意的是,TX与RX需要对调相接,如图所示: 随后,打开Tera Term,选择串口打开,并配置波特率为115200,点击 New setting 回到终端,按下x键,此时XMODEM测试程序进入到接收模式 ??回到Tera Term中,选择文件->传输->XMODEM->发送,随后选择要传输的文件,点击打开,其界面如下: 随后,XMODEM开始进行传输,如图所示: 传输完成后,会提示接收完成
4. 结束
至此,XMODEM设计、代码编写、测试过程,均已完成,相关代码可以到下面地址获取 工程代码下载
https:
|