IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> XMODEM设计与C代码实现(3.测试篇) -> 正文阅读

[C++知识库]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++]);
            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对象
    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
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 13:54:18  更:2021-09-27 13:56:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:00:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码