通用uart测试工具
为了方便对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测试工具相关推荐
- live http工具下载_使用通用测试工具探索Blueworks Live REST API资源
live http工具下载 本系列的第1部分介绍了5个一般用例,它们是使用IBM®Blueworks Live的代表性状态转移(REST)应用程序编程接口(API)的最佳方法. 您还为每种用例学习了不 ...
- 11种流行的渗透测试工具
11种笔测试工具,非常适合检测漏洞并准确模拟网络攻击.让我们看一下它们的功能和兼容的平台. 您是否一直在寻找最能满足您的Web应用程序和网络安全测试要求的渗透测试工具?您是否要比较和分析不同的渗透测试 ...
- sender通用收发包测试工具
sender工具是通用的发包工具,支持xml文件,在使用sender工具之前需要先把头文件中的结构体转化成xml文件,然后进一步使用sender工具实现发包功能.下面将详细描述此工具的使用: 1获取结 ...
- 通用WsSocket压力测试工具
通用WsSocket压力测试工具 需求分析: 现在的游戏服务器为支持多端,很多通讯协议都使用了wssocket来进行通讯,当项目进行到后端的时候,都需要开发一个模拟客户端的工具来进行压力测试,测试服务 ...
- FW 每秒百万级别的 HTTP 请求 sung: 重型的(heavy-duty)、分布式的、多协议测试工具...
本文是构建能够每秒处理 3 百万请求的高性能 Web 集群系列文章的第一篇.它记录了我使用负载生成器工具的一些经历,希望它能帮助每一个像我一样不得不使用这些工具的人节省时间. 负载生成器是一些生成用于 ...
- 基于Java的四大开源测试工具
摘要:成功的应用程序离不开测试人员和QA团队反复地测试,应用程序在进行最后的部署之前,需要通过测试来确保它的负载管理能力以及在特殊情况下的工作条件和工作加载情况. %R[)vA t]N0 测试是应用程 ...
- mysql 工具_MySQL压力测试工具,值得收藏
一.MySQL自带的压力测试工具--Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出查询更新 ...
- Python中的测试工具
当我们在写程序的时候,我们需要通过测试来验证程序是否出错或者存在问题,但是,编写大量的测试来确保程序的每个细节都没问题会显得很繁琐.在Python中,我们可以借助一些标准模块来帮助我们自动完成测试过程 ...
- python 两个[]_Python中的两个测试工具
♚ 作者:jclian,喜欢算法,热爱分享,希望能结交更多志同道合的朋友,一起在学习Python的道路上走得更远! 当我们在写程序的时候,我们需要通过测试来验证程序是否出错或者存在问题,但是,编写大量 ...
最新文章
- Spring Boot框架敏感信息泄露的完整介绍与SRC实战(附专属字典与PoC)
- 【BZOJ4300】—绝世好题(二进制dp)
- python高并发架构_python高并发的解决方案
- LeetCode-Letter Combinations of a Phone Number-电话号码字母组合-DFS
- js日期函数表达天,时,分,秒
- 试读《JavaScript语言精粹(修订版)》
- 前端之JQuery:JQuery文档操作
- 教你用手机代替各类门禁卡
- springboot+mybatis报错处理
- 猿人学web端爬虫攻防大赛赛题解析_第六题:js 混淆 - 回溯
- NPN和PNP的区别和总结
- 【转】常见英语单词前缀
- 6个Web前端值得收藏很实用的菜单模板(上)
- phalcon index.php,phalcon简易指南
- The alias ‘TaskType‘ is already mapped to the value ‘com.xxx.entity.Tasktype‘.
- zcmu oj 1087: 统计字符
- HDU 5514Frogs
- 2020 豆瓣API使用(代理方法) 解决无key方法 code 104解决方法
- 引导区坏 计算机无法启动,windows7旗舰版系统下注册表损坏导致无法引导启动怎么解决...
- 西软服务器linux,详细讲解西软FOXHIS增量备份与恢复方法