为了方便对UART驱动进行测试,特意开发了通用UART测试工具,该工具同时也可用于UART硬件测试和UART应用开发参考。

简要说明

  • 命令行解析基于cmdParse模块,这个模块的功能和用法会单独说明。
  • 命令每次只针对一个UART端口进行操作。
  • 该命令运行后会创建3个执行线程,接收线程,反射线程和发送线程。
  • -help 选项是个通用选项,会输出相应命令的选项列表。
  • -info 选项用于打印命令默认运行参数。
  • -f 选项指定UART设备文件名称,使用 ll /dev/ 命令可以查看当前系统有哪些串口设备。
  • -d [on/off] 选项用于控制是否打印运行信息。对于较高频率的动作执行时一般要关闭调试信息。
  • -e [on/off]选项用于控制是否开启接收反射功能。开启后会把收到的数据原样发送出去。
  • -b 选项用于设置串口波特率,默认为115200。
  • -o 选项用于设置串口校验方式,默认无校验。
  • -i 选项用于设置发送间隔,单位是毫秒,默认为1000毫秒。
  • -n 选项用于设置发送次数。
  • -w 选项用于设置发送数据内容。后跟uint8_t类型数据数组。

命令执行

显示选项列表

显示命令默认配置

只接收数据

接收并反射数据

发送数据

程序源码

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                SylixOS(TM)  LW : long wing
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: uartAccessCmd.c
**
** 创   建   人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2017 年 10 月 17 日
**
** 描        述: 通用串口测试工具
*********************************************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "cmdParse/cmdParse.h"
/*********************************************************************************************************宏定义
*********************************************************************************************************/
#define CFG_DEFAULT_BUF_SIZE                (64)                        /*  默认缓存大小                */
#define CFG_DEFAULT_BUF_COUNT               (32)                        /*  默认缓存个数                */
/*********************************************************************************************************宏函数
*********************************************************************************************************/
#if 1
#define PRINT_DEBUG(fmt, ...)     do {printf(fmt, ##__VA_ARGS__);} while (0)
#else
#define PRINT_DEBUG(fmt, ...)
#endif#define PRINT_ERROR(fmt, ...)     do {printf("[ERROR]%s:%d---", __FILE__, __LINE__); \printf(fmt, ##__VA_ARGS__);  } while (0)#define PRINT_DATA_UINT8(ptr, len, fmt, ...)                            \do {UINT  j;                                            \printf(fmt, ##__VA_ARGS__);                         \for (j = 0; j < (len); j++) {                       \if ((j & 0x0f) == 0) {printf("\r\n[%04x]", j);} \printf(" %02x", ((UINT8 *)ptr)[j]);             \} printf("\n");} while (0)
/*********************************************************************************************************设备配置参数结构
*********************************************************************************************************/
typedef struct {UINT32                      uiEchoState;                            /*  0 不反射 1反射接收的数据    */UINT32                      uiDisplayState;                         /*  0 不显示收发数据 1显示      */INT                         iFd;                                    /*  设备文件标识符              */pthread_t                   tidRecv;                                /*  接收线程ID                  */pthread_t                   tidEcho;                                /*  反射线程ID                  */pthread_t                   tidSend;                                /*  发送线程ID                  */LW_OBJECT_HANDLE            hQueueSend;                             /*  消息队列句柄                */CHAR                        cFileName[64];                          /*  波特率                      */UINT32                      uiBaud;                                 /*  波特率                      */UINT32                      uiOption;                               /*  硬件选项                    */UINT32                      uiRecvCount;                            /*  串口接收数据计数            */UINT32                      uiEchoCount;                            /*  串口反射数据计数            */UINT32                      uiSendCount;                            /*  串口发送数据计数            */UINT32                      uiSendInterval;                         /*  发送间隔,单位毫秒          */UINT32                      uiSendNumber;                           /*  串口发送次数                */INT32                       uiBufLength;                            /*  缓冲区有效数据长度          */UINT8                       ucBuf[CFG_DEFAULT_BUF_SIZE];            /*  缓冲区                      */} DEV_ARG_ST;
/*********************************************************************************************************
** 名称: getInfo
** 输入: cmd        命令参数
**       opti       参数索引
** 输出: 错误码,NONE成功,ERROR错误
** 说明: 获取 info 选项
*********************************************************************************************************/
static int  getInfo (command_st  *cmd, int opti)
{DEV_ARG_ST  *pArg;pArg = cmd->priv;printf("echo     = %d\n", pArg->uiEchoState);printf("display  = %d\n", pArg->uiDisplayState);printf("iFd      = %d\n", pArg->iFd);printf("tidRecv  = %08x\n", (UINT)pArg->tidRecv);printf("tidEcho  = %08x\n", (UINT)pArg->tidEcho);printf("tidSend  = %08x\n", (UINT)pArg->tidSend);printf("file     = %s\n", pArg->cFileName);printf("uiBaud   = %d\n", pArg->uiBaud);printf("uiOption = %08x\n", pArg->uiOption);printf("recvCount= %d\n", pArg->uiRecvCount);printf("echoCount= %d\n", pArg->uiEchoCount);printf("sendCount= %d\n", pArg->uiSendCount);printf("interval = %d\n", pArg->uiSendInterval);printf("number   = %d\n", pArg->uiSendNumber);printf("uiLength = %d\n", pArg->uiBufLength);if (pArg->uiBufLength) {PRINT_DATA_UINT8(pArg->ucBuf, pArg->uiBufLength, "send data :");}return  (ERROR);
}
/*********************************************************************************************************
** 名称: getClose
** 输入: cmd        命令参数
**       opti       参数索引
** 输出: 错误码,NONE成功,ERROR错误
** 说明: 获取 Option 选项
*********************************************************************************************************/
static int  getOption (command_st  *cmd, int opti)
{option_st   *opt;DEV_ARG_ST  *pArg;char        *str;pArg = cmd->priv;opt  = &cmd->optv[opti];if (opt->argc <= 0) {return  (NONE);}str = cmd->argv[opt->index + 1];if (strcmp(str, "none") == 0) {pArg->uiOption = CREAD | CS8;} else if (strcmp(str, "odd") == 0) {pArg->uiOption = CREAD | CS8 | PARENB | PARODD;} else if (strcmp(str, "even") == 0) {pArg->uiOption = CREAD | CS8 | PARENB;} else {pArg->uiOption = strtoul(str, NULL, 0);}return  (NONE);
}
/*********************************************************************************************************
** 名称: devPthreadRecv
** 描述: 串口接收线程
** 输入: pvArg       参数结构
** 输出: ERROR_CODE
*********************************************************************************************************/
static  void   *devPthreadRecv (void * pvArg)
{INT          res;UINT8        buf[CFG_DEFAULT_BUF_SIZE];DEV_ARG_ST  *pArg = (DEV_ARG_ST  *)pvArg;while(1) {res = read(pArg->iFd, buf, sizeof(buf));if (res > 0) {                                                  /*  接收数据                    */pArg->uiRecvCount += res;if (pArg->uiEchoState) {Lw_MsgQueue_SendEx2(pArg->hQueueSend,(PVOID)buf,res,LW_OPTION_NOT_WAIT,LW_OPTION_DEFAULT);}if (pArg->uiDisplayState) {PRINT_DATA_UINT8(buf, res, "[uart %s] recv %d byte, data :", pArg->cFileName, res);}} else {PRINT_ERROR("read err,res = %d \n", res);break;}}return  (NULL);
}
/*********************************************************************************************************
** 名称: devPthreadEcho
** 描述: 串口反射线程
** 输入: pvArg       参数结构
** 输出: ERROR_CODE
*********************************************************************************************************/
static  void   *devPthreadEcho (void * pvArg)
{INT          res;size_t       txLen;UINT8        buf[CFG_DEFAULT_BUF_SIZE];DEV_ARG_ST  *pArg = (DEV_ARG_ST  *)pvArg;while(1) {res = Lw_MsgQueue_Receive(pArg->hQueueSend,buf,CFG_DEFAULT_BUF_SIZE,&txLen,LW_OPTION_WAIT_INFINITE);if (res < 0) {PRINT_ERROR("Lw_MsgQueue_Receive,res = %d", res);break;} else {                                                        /*  接收数据                    */if (pArg->uiDisplayState) {pArg->uiEchoCount += txLen;write(pArg->iFd, buf, txLen);PRINT_DATA_UINT8(buf, txLen, "[uart %s] echo %d byte, data :", pArg->cFileName, txLen);}}}return  (NULL);
}
/*********************************************************************************************************
** 名称: devPthreadSend
** 描述: 串口发送线程
** 输入: pvArg       参数结构
** 输出: ERROR_CODE
*********************************************************************************************************/
static  void   *devPthreadSend (void * pvArg)
{DEV_ARG_ST  *pArg = (DEV_ARG_ST  *)pvArg;while(pArg->uiBufLength && pArg->uiSendNumber--) {if (pArg->uiDisplayState) {PRINT_DATA_UINT8(pArg->ucBuf, pArg->uiBufLength,"[uart %s] send %d byte, data :", pArg->cFileName, pArg->uiBufLength);}pArg->uiSendCount += pArg->uiBufLength;write(pArg->iFd, pArg->ucBuf, pArg->uiBufLength);usleep(pArg->uiSendInterval * 1000);}return  (NULL);
}
/*********************************************************************************************************
** 名称: main
** 输入: argc       参数个数
**       argv       参数列表
** 输出: 错误码,NONE成功,ERROR错误
** 说明: 通用串口测试工具
*********************************************************************************************************/
static int uartTool (int argc, char *argv[])
{DEV_ARG_ST  devArg = {.uiEchoState    = 0,.uiDisplayState = 1,.iFd            = -1,.cFileName      = "/dev/ttyS1",.uiBaud         = SIO_BAUD_115200,.uiOption       = CREAD | CS8,.uiRecvCount    = 0,.uiEchoCount    = 0,.uiSendCount    = 0,.uiSendInterval = 1000,.uiSendNumber   = 0,.uiBufLength    = 0,.ucBuf          = { 0 },};option_st  optv[] = {{ATT_BUF_SIZE(sizeof(devArg.cFileName)) |ATT_TYPE_SBUF, &devArg.cFileName,      "f",      "set uart device file name"},{ATT_TYPE_BOOL, &devArg.uiDisplayState, "d",      "set dispaly state"},{ATT_TYPE_BOOL, &devArg.uiEchoState,    "e",      "set echo state"},{ATT_TYPE_U32,  &devArg.uiBaud,         "b",      "set baudrate"},{ATT_FUNC,      getOption,              "o",      "set option, none/odd/even/0x0e"},{ATT_TYPE_U32,  &devArg.uiSendInterval, "i",      "set send interval, ms"},{ATT_TYPE_U32,  &devArg.uiSendNumber,   "n",      "set send number"},{ATT_ARRAY(GET_ARRAY_COUNT(devArg.ucBuf)) |ATT_TYPE_U8,   &devArg.ucBuf,          "w",      "set send data", &devArg.uiBufLength},{ATT_FUNC,      getInfo,                "info",   "print cmd info"},};command_st      cmd;DEV_ARG_ST     *pArg = &devArg;int             err;LW_CLASS_THREADATTR  hThreadAttr;cmd.argc = argc;cmd.argv = argv;cmd.optc = GET_OPTC(optv);cmd.optv = optv;cmd.priv = &devArg;err = cmdParse(&cmd);if (err != NONE) {return  (err);}pArg->hQueueSend = Lw_MsgQueue_Create("uartQueue",CFG_DEFAULT_BUF_COUNT,CFG_DEFAULT_BUF_SIZE,LW_OPTION_WAIT_FIFO | LW_OPTION_OBJECT_LOCAL,NULL);pArg->iFd = open(pArg->cFileName, O_RDWR, 0666);if (pArg->iFd < 0) {PRINT_ERROR("open device [%s] faild\n", pArg->cFileName);return  (PX_ERROR);}ioctl(pArg->iFd, FIOFLUSH, NULL);                                   /*  清空设备收发缓冲区          */if (ioctl(pArg->iFd, SIO_BAUD_SET, pArg->uiBaud) != ERROR_NONE) {PRINT_ERROR("set baudrate faild\n");close(pArg->iFd);return  (PX_ERROR);}if (ioctl(pArg->iFd, SIO_HW_OPTS_SET, pArg->uiOption) != ERROR_NONE) {PRINT_ERROR("set opt faild\n");close(pArg->iFd);return  (PX_ERROR);}Lw_ThreadAttr_Build(&hThreadAttr, 4 * LW_CFG_KB_SIZE, LW_PRIO_NORMAL + 0, 0, (void *)pArg);Lw_Thread_Create("t_uartRecv", devPthreadRecv, &hThreadAttr, &pArg->tidRecv);Lw_ThreadAttr_Build(&hThreadAttr, 4 * LW_CFG_KB_SIZE, LW_PRIO_NORMAL + 1, 0, (void *)pArg);Lw_Thread_Create("t_uartEcho", devPthreadEcho, &hThreadAttr, &pArg->tidEcho);Lw_ThreadAttr_Build(&hThreadAttr, 4 * LW_CFG_KB_SIZE, LW_PRIO_NORMAL + 2, 0, (void *)pArg);Lw_Thread_Create("t_uartSend", devPthreadSend, &hThreadAttr, &pArg->tidSend);Lw_Thread_Join(pArg->tidRecv, NULL);Lw_Thread_Join(pArg->tidEcho, NULL);return  (ERROR_NONE);
}
/*********************************************************************************************************END
*********************************************************************************************************/

通用uart测试工具相关推荐

  1. live http工具下载_使用通用测试工具探索Blueworks Live REST API资源

    live http工具下载 本系列的第1部分介绍了5个一般用例,它们是使用IBM®Blueworks Live的代表性状态转移(REST)应用程序编程接口(API)的最佳方法. 您还为每种用例学习了不 ...

  2. 11种流行的渗透测试工具

    11种笔测试工具,非常适合检测漏洞并准确模拟网络攻击.让我们看一下它们的功能和兼容的平台. 您是否一直在寻找最能满足您的Web应用程序和网络安全测试要求的渗透测试工具?您是否要比较和分析不同的渗透测试 ...

  3. sender通用收发包测试工具

    sender工具是通用的发包工具,支持xml文件,在使用sender工具之前需要先把头文件中的结构体转化成xml文件,然后进一步使用sender工具实现发包功能.下面将详细描述此工具的使用: 1获取结 ...

  4. 通用WsSocket压力测试工具

    通用WsSocket压力测试工具 需求分析: 现在的游戏服务器为支持多端,很多通讯协议都使用了wssocket来进行通讯,当项目进行到后端的时候,都需要开发一个模拟客户端的工具来进行压力测试,测试服务 ...

  5. FW 每秒百万级别的 HTTP 请求 sung: 重型的(heavy-duty)、分布式的、多协议测试工具...

    本文是构建能够每秒处理 3 百万请求的高性能 Web 集群系列文章的第一篇.它记录了我使用负载生成器工具的一些经历,希望它能帮助每一个像我一样不得不使用这些工具的人节省时间. 负载生成器是一些生成用于 ...

  6. 基于Java的四大开源测试工具

    摘要:成功的应用程序离不开测试人员和QA团队反复地测试,应用程序在进行最后的部署之前,需要通过测试来确保它的负载管理能力以及在特殊情况下的工作条件和工作加载情况. %R[)vA t]N0 测试是应用程 ...

  7. mysql 工具_MySQL压力测试工具,值得收藏

    一.MySQL自带的压力测试工具--Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新 ...

  8. Python中的测试工具

    当我们在写程序的时候,我们需要通过测试来验证程序是否出错或者存在问题,但是,编写大量的测试来确保程序的每个细节都没问题会显得很繁琐.在Python中,我们可以借助一些标准模块来帮助我们自动完成测试过程 ...

  9. python 两个[]_Python中的两个测试工具

    ♚ 作者:jclian,喜欢算法,热爱分享,希望能结交更多志同道合的朋友,一起在学习Python的道路上走得更远! 当我们在写程序的时候,我们需要通过测试来验证程序是否出错或者存在问题,但是,编写大量 ...

最新文章

  1. Spring Boot框架敏感信息泄露的完整介绍与SRC实战(附专属字典与PoC)
  2. 【BZOJ4300】—绝世好题(二进制dp)
  3. python高并发架构_python高并发的解决方案
  4. LeetCode-Letter Combinations of a Phone Number-电话号码字母组合-DFS
  5. js日期函数表达天,时,分,秒
  6. 试读《JavaScript语言精粹(修订版)》
  7. 前端之JQuery:JQuery文档操作
  8. 教你用手机代替各类门禁卡
  9. springboot+mybatis报错处理
  10. 猿人学web端爬虫攻防大赛赛题解析_第六题:js 混淆 - 回溯
  11. NPN和PNP的区别和总结
  12. 【转】常见英语单词前缀
  13. 6个Web前端值得收藏很实用的菜单模板(上)
  14. phalcon index.php,phalcon简易指南
  15. The alias ‘TaskType‘ is already mapped to the value ‘com.xxx.entity.Tasktype‘.
  16. zcmu oj 1087: 统计字符
  17. HDU 5514Frogs
  18. 2020 豆瓣API使用(代理方法) 解决无key方法 code 104解决方法
  19. 引导区坏 计算机无法启动,windows7旗舰版系统下注册表损坏导致无法引导启动怎么解决...
  20. 西软服务器linux,详细讲解西软FOXHIS增量备份与恢复方法

热门文章

  1. YARN 内存参数终极详解
  2. jupyter notebook 配置
  3. Python的Numpy库的ndarray对象常用构造方法及初始化方法
  4. 【100%通过率】华为OD机试真题 C++ 实现【字符串解密】【2022.11 Q4 新题】
  5. maven中的GROUPID和ARTIFACTID是什么?作用是啥?
  6. 两款C++静态检查工具
  7. 数据挖掘入门:二手车交易价格预测
  8. 二维码扫描之Zxing的一次实操记录,配合添加手电筒开关
  9. 用手机拍商品图的技巧 、五步拍出不输相机效果的商品图、新品发朋友圈的技巧
  10. 还有20小时!神泣龙之反击上线倒计时