XMODEM设计与C代码实现(3.测试篇)
1.测试方式与代码
在上一篇文章中,我们通过C代码实现了XMODEM通信协议库设计,本篇文章我们将编写一段测试程序,实现对XMODEM库进行测试。
测试过程采用PC串口方式实现,操作系统为UBUNTU20,编译工具为GCC,其实现过程如下所示。
1.1.创建XMODEM对象
首先,我们需要创建一个XMODEM对象
//定义XMODEM对象
static xmodem_t xmodem_obj={XMODEM_DATA_128, //采用128字节数据XMODEM_CHK_MD_ADD, //累加和方式校验XMODEM_REQ_NONE, //初始化XMODEM请求XMODEM_STATE_IDLE, //初始化XMODEM状态80, //等待阈值80次0, //初始化等待计数器XMODEM_RX_ST_IDLE, //初始化接收空闲10, //接收重试超时阈值10次0, //初始化超时重试计数器xmodem_tx, //注册发送过程xmodem_rx, //注册接收过程xmodem_cb, //注册回调过程{0}, //初始化缓冲区0, //当前接收长度0, //初始化帧计数
};
1.2. 接口函数实现
在对象中,存在三个接口函数,它们分别为”xmodem_tx”,”xmodem_rx”,”xmodem_cb”这三个函数。
其中xmodem_tx实现了XMODEM发送功能,它通过调用系统代码如下:
//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接收过程,配置给串口
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;}//若收到EOT则直接返回接收完成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; /* 读取一个字符等待1*(1/10)s */
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;}//若缓冲有效且长度为0,则显示接收完成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++]);elseprintf("%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对象xmodem_init(&xmodem_obj);//创建xmodem处理线程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'://请求开始xmodem传输printf("XMODEM START REQ\n\r");tcflush(uart_fd,TCIFLUSH);xmodem_req(&xmodem_obj,XMODEM_REQ_START);break;case 'S':case 's'://请求结束xmodem传输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://gitee.com/ekd/XMODEM.git
XMODEM设计与C代码实现(3.测试篇)相关推荐
- XMODEM设计与C代码实现(2.代码设计篇)
1. 关键数据定义 在上一篇中,我们对XMODEM的系统结构以及关键流程进行了详细设计,所以,我们在设计代码前,先对几个重要的数据进行定义,相关的解释我都写在注释中. typedef enum x ...
- XMODEM设计与C代码实现(1.整体设计篇)
1. XMODEM协议 XMODEM帧结构按照校验形式分为2种,如下表所示: 校验和校验帧结构 BYTE1 BYTE2 BYTE3 BYTE4~131 BYTE132 头标志 帧序号 ~帧序号 帧数据 ...
- SDM For Face Alignment流程介绍及Matlab代码实现之测试篇
测试很简单了,只需要载入数据,然后做正则化处理,使用训练模型产生的{Rk}\{R_k\},就可以预测特征点了. face_alignment.m:用来预测特征点 function shape = fa ...
- 选课系统html页面设计,网上选课系统的设计与实现(代码)..doc
网上选课系统的设计与实现(代码). 网上选课系统的设计与实现(代码) 目录 摘要1 ABSTRACT2 第一章 引言3 1.1课题背景及意义3 1.2开发工具的选用及介绍3 1.3 课题的可行性分析5 ...
- AT串口抽象层的设计思路及代码实现
文章目录 1 AT串口抽象层的设计思路及代码实现 1.1 AT串口抽象层的设计思路 1.2 AT串口抽象层的代码实现 1 AT串口抽象层的设计思路及代码实现 1.1 AT串口抽象层的设计思路 我们先来 ...
- 设计稿生成代码与 Serverless 的前世今生与未来!
一场脑洞实验 云栖大会云上 Hello World 活动火热进行中!每位参与者都可收获一份阿里云出品的全球唯一序列号纪念证书! 作为阿里经济体前端委员会的四大技术方向之一,前端智能化方向一被提及,就不 ...
- 测试设计中需要考虑的22种测试类型
测试设计中需要考虑的22种测试类型 测试设计中需要考虑的22种测试类型 纪玉春 来自21CMM 黑盒测试:不基于内部设计和代码的任何知识,而是基于需求和功能性. 白盒测试:基于一个应用代码的内部逻辑知 ...
- 前端架构设计1:代码核心
现在的前端领域, 随着JS框架, UI框架和各种库的丰富, 前端架构也变得十分的重要. 如果一个大型项目没有合理的前端架构设计, 那么前端代码可能因为不同的开发人员随意的引入各种库和UI框架, 导致代 ...
- (26)FPGA计数器设计(VHDL代码实现)
(26)FPGA计数器设计(VHDL代码实现) 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)FPGA计数器设计(VHDL代码实现) 5)结语 1.2 FPGA简介 F ...
最新文章
- SQL Server 2005 处理交叉表
- 激光点云格式转换 bin 相互 pcd转换
- processing python模式_python学习Processing
- MySQL锁的用法之行级锁
- Linux下SVN安装配置全程实录(转)
- 数据结构实验:连通分量个数
- html怎么设置椭圆文本框,html – 避免CSS border-radius中的椭圆形状
- 借教室(codevs 1217)
- WSL1安装GUI界面
- 深入了解JavaScript目录(持续更新)
- 猜数字游戏编程C语言0到9,【游戏编程】猜数字游戏(C语言)
- 王道考研操作系统笔记(第二章)附:王道考研408所有PPT和思维导图
- 交友小程序服务器,又是陌生人交友小程序,探探Lite到底有什么不同?
- AGV机器人RFID传感器CK-G06A与西门子1200PLC应用手册
- 项目经理之初为项目经理
- 计算机boot指令,计算机基本知识(8001)---MBR(master boot record)主引导记录
- F5 BIG-IP 17.0.0
- 检测运行程序,强制电脑关机代码
- Chrome源码chromium下载编译详细步骤
- Linux 大数据(hadoop)