在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux系統串口批量產測工具

jf_49670627 ? 來源:jf_49670627 ? 作者:jf_49670627 ? 2023-04-12 11:38 ? 次閱讀

1、說明

本文針對Linux系統上如何對各類串口硬件進行出廠測試進行硬件連接和軟件使用說明,提供的軟件測試工具wchsertest,適用于USB、PCI、PCIe轉串口設備等、同樣也適用于原生ttyS串口。

2、串口測試硬件連接

在測試前,需要制作單獨的硬件治具,按下表連接信號線:

1.png

引腳連接示意圖:

?

3、軟件使用方法

(1)插入待測試USB/PCI/PCIe轉串口設備。

(2)以CH342F(USB轉2串口芯片)為例,安裝對應VCP廠商驅動程序,進入/dev目錄查看出現如下設備節點:

?

以CH382為例,安裝對應VCP廠商驅動程序,進入/dev目錄查看出現如下設備節點:

?

(3)運行軟件,輸入命令格式:

./[可執行文件] –D [設備節點路徑]

實例1(測試CH342的UART0):sudo ./serial_port_test -D /dev/ttyCH343USB0

實例2(測試CH382的UART0):sudo ./serial_port_test -D /dev/ttyWCH0

4、測試錯誤碼說明

根據輸出的錯誤碼和終端輸出信息可判斷故障信號線,下表為錯誤碼和說明。

錯誤碼 錯誤碼說明
0 DTR--DSR線錯誤
1 DTR--DCD線錯誤
2 RTS--CTS線錯誤
3 RTS--RI線錯誤
4 TXD--RXD線錯誤

5、測試實例

(1)測試成功實例

軟件分別以2400bps、9600bps、115200bps各測試一次。

? ?

(2)測試錯誤實例

?

根據輸出信息可知,DTR—DSR信號通訊存在錯誤,錯誤碼:0。

6、wchsertest工具源碼

/*
 * serial port factory test utility.
 *
 * Copyright (C) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
 * Web:     http://wch.cn
 * Author:  WCH 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define termios asmtermios
#include 
#undef termios
#include 

#define DTR_ON	    1
#define DTR_OFF	    0
#define RTS_ON	    1
#define RTS_OFF	    0
#define BUF_SIZE    64
#define DTR_ON_CMD  0x0
#define DTR_OFF_CMD 0x1
#define RTS_ON_CMD  0x2
#define RTS_OFF_CMD 0x3

extern int ioctl(int d, int request, ...);

static const char *device = "/dev/ttyCH343USB0";
static int hardflow = 0;
static int verbose = 0;
static FILE *fp;

static const struct option lopts[] = {
	{ "device", required_argument, 0, 'D' },
	{ NULL, 0, 0, 0 },
};

static void print_usage(const char *prog)
{
	printf("Usage: %s [-DSvf]
", prog);
	puts("  -D --device    tty device to use
");
	exit(1);
}

static void parse_opts(int argc, char *argv[])
{
	int c;

	while (1) {
		c = getopt_long(argc, argv, "D:S:h", lopts, NULL);
		if (c == -1) {
			break;
		}
		switch (c) {
		case 'D':
			if (optarg != NULL)
				device = optarg;
			break;
		case 'h':
		default:
			print_usage(argv[0]);
			break;
		}
	}
}

/**
 * libtty_setcustombaudrate - set baud rate of tty device
 * @fd: device handle
 * @speed: baud rate to set
 *
 * The function return 0 if success, or -1 if fail.
 */
static int libtty_setcustombaudrate(int fd, int baudrate)
{
	struct termios2 tio;

	if (ioctl(fd, TCGETS2, &tio)) {
		perror("TCGETS2");
		return -1;
	}

	tio.c_cflag &= ~CBAUD;
	tio.c_cflag |= BOTHER;
	tio.c_ispeed = baudrate;
	tio.c_ospeed = baudrate;

	if (ioctl(fd, TCSETS2, &tio)) {
		perror("TCSETS2");
		return -1;
	}

	if (ioctl(fd, TCGETS2, &tio)) {
		perror("TCGETS2");
		return -1;
	}

	return 0;
}

/**
 * libtty_setopt - config tty device
 * @fd: device handle
 * @speed: baud rate to set
 * @databits: data bits to set
 * @stopbits: stop bits to set
 * @parity: parity to set
 * @hardflow: hardflow to set
 *
 * The function return 0 if success, or -1 if fail.
 */
static int libtty_setopt(int fd, int speed, int databits, int stopbits, char parity, char hardflow)
{
	struct termios newtio;
	struct termios oldtio;
	int i;

	bzero(&newtio, sizeof(newtio));
	bzero(&oldtio, sizeof(oldtio));

	if (tcgetattr(fd, &oldtio) != 0) {
		perror("tcgetattr");
		return -1;
	}
	newtio.c_cflag |= CLOCAL | CREAD;
	newtio.c_cflag &= ~CSIZE;

	/* set data bits */
	switch (databits) {
	case 5:
		newtio.c_cflag |= CS5;
		break;
	case 6:
		newtio.c_cflag |= CS6;
		break;
	case 7:
		newtio.c_cflag |= CS7;
		break;
	case 8:
		newtio.c_cflag |= CS8;
		break;
	default:
		fprintf(stderr, "unsupported data size
");
		return -1;
	}

	/* set parity */
	switch (parity) {
	case 'n':
	case 'N':
		newtio.c_cflag &= ~PARENB; /* Clear parity enable */
		newtio.c_iflag &= ~INPCK;  /* Disable input parity check */
		break;
	case 'o':
	case 'O':
		newtio.c_cflag |= (PARODD | PARENB); /* Odd parity instead of even */
		newtio.c_iflag |= INPCK;	     /* Enable input parity check */
		break;
	case 'e':
	case 'E':
		newtio.c_cflag |= PARENB;  /* Enable parity */
		newtio.c_cflag &= ~PARODD; /* Even parity instead of odd */
		newtio.c_iflag |= INPCK;   /* Enable input parity check */
		break;
	default:
		fprintf(stderr, "unsupported parity
");
		return -1;
	}

	/* set stop bits */
	switch (stopbits) {
	case 1:
		newtio.c_cflag &= ~CSTOPB;
		break;
	case 2:
		newtio.c_cflag |= CSTOPB;
		break;
	default:
		perror("unsupported stop bits
");
		return -1;
	}

	if (hardflow)
		newtio.c_cflag |= CRTSCTS;
	else
		newtio.c_cflag &= ~CRTSCTS;

	newtio.c_cc[VTIME] = 10; /* Time-out value (tenths of a second) [!ICANON]. */
	newtio.c_cc[VMIN] = 64; /* Minimum number of bytes read at once [!ICANON]. */

	tcflush(fd, TCIOFLUSH);

	if (tcsetattr(fd, TCSANOW, &newtio) != 0) {
		perror("tcsetattr");
		return -1;
	}

	/* set tty speed */
	if (libtty_setcustombaudrate(fd, speed) != 0) {
		perror("setbaudrate");
		return -1;
	}

	return 0;
}

/**
 * libtty_open - open tty device
 * @devname: the device name to open
 *
 * In this demo device is opened blocked, you could modify it at will.
 */
static int libtty_open(const char *devname)
{
	int fd = open(devname, O_RDWR | O_NOCTTY);
	int flags = 0;

	if (fd < 0) {
		perror("open device failed");
		return -1;
	}

	if (fcntl(fd, F_SETFL, 0) < 0) {
		printf("fcntl failed.
");
		return -1;
	}

	if (isatty(fd) == 0) {
		printf("not tty device.
");
		return -1;
	}

	return fd;
}

/**
 * libtty_close - close tty device
 * @fd: the device handle
 *
 * The function return 0 if success, others if fail.
 */
static int libtty_close(int fd)
{
	return close(fd);
}

/**
 * libtty_tiocmset - modem set
 * @fd: file descriptor of tty device
 * @bDTR: 0 on inactive, other on DTR active
 * @bRTS: 0 on inactive, other on RTS active
 *
 * The function return 0 if success, others if fail.
 */
static int libtty_tiocmset(int fd, char bDTR, char bRTS)
{
	unsigned long controlbits = 0;

	if (bDTR)
		controlbits |= TIOCM_DTR;
	if (bRTS)
		controlbits |= TIOCM_RTS;

	return ioctl(fd, TIOCMSET, &controlbits);
}

/**
 * libtty_tiocmget - modem get
 * @fd: file descriptor of tty device
 * @modembits: pointer to modem status
 *
 * The function return 0 if success, others if fail.
 */
static int libtty_tiocmget_check(int fd, unsigned long *modembits, int cmd)
{
	int ret = 0;

	ret = ioctl(fd, TIOCMGET, modembits);
	if (ret == 0) {
		switch (cmd) {
		case DTR_OFF_CMD: // DTR--DSR/DCD
			if ((*modembits & TIOCM_DSR) != 0) {
				printf("[error code: %d] DTR--DSR ERROR
", 0);
				ret = -1;
			}
			if ((*modembits & TIOCM_CD) != 0) {
				printf("[error code: %d] DTR--DCD ERROR
", 1);
				ret = -1;
			}
			break;
		case DTR_ON_CMD:
			if ((*modembits & TIOCM_DSR) == 0) {
				printf("[error code: %d] DTR--DSR ERROR
", 0);
				ret = -1;
			}
			if ((*modembits & TIOCM_CD) == 0) {
				printf("[error code: %d] DTR--DCD ERROR
", 1);
				ret = -1;
			}
			break;
		case RTS_OFF_CMD: // RTS--CTS/RI
			if ((*modembits & TIOCM_CTS) != 0) {
				printf("[error code: %d] RTS--CTS ERROR
", 2);
				ret = -1;
			}
			if ((*modembits & TIOCM_RI) != 0) {
				printf("[error code: %d] RTS--RI ERROR
", 3);
				ret = -1;
			}
			break;
		case RTS_ON_CMD:
			if ((*modembits & TIOCM_CTS) == 0) {
				printf("[error code: %d] RTS--CTS ERROR
", 2);
				ret = -1;
			}
			if ((*modembits & TIOCM_RI) == 0) {
				printf("[error code: %d] RTS--RI ERROR
", 3);
				ret = -1;
			}
			break;
		default:
			break;
		}
	}
	return ret;
}

static void sig_handler(int signo)
{
	printf("capture sign no:%d
", signo);
	if (fp != NULL) {
		fflush(fp);
		fsync(fileno(fp));
		fclose(fp);
	}
	exit(0);
}

void start_test(int fd)
{
	int ret, i, times, num, nwrite, nread, len;
	int len_w, pos_w, ret1, ret2, ret3;
	int total = 0, off_w, off_r;
	char c;
	unsigned long modemstatus;
	unsigned char buf_write[BUF_SIZE];
	unsigned char buf_read[BUF_SIZE];

	memset(buf_write, 0x00, BUF_SIZE);
	memset(buf_read, 0x00, BUF_SIZE);

	for (times = 0; times < 64; times++) {
		for (i = 0; i < BUF_SIZE; i++)
			buf_write[i] = i + BUF_SIZE * (times % 4);

		/* Send 64 bytes */
        off_w = 0;
        len = BUF_SIZE;
        while (len > 0) {
            nwrite = write(fd, buf_write + off_w, len);
            if (nwrite < 0) {
                perror("write");
                exit(1);
            }
            off_w += nwrite;
            len -= nwrite;
        }
        
		/* Receive and judge */
        off_r = 0;
		while (nwrite > 0) {
			nread = read(fd, buf_read + off_r, nwrite);
            if (nread < 0) {
                printf("read error!
");
				exit(1);
            }
            off_r += nread;
            nwrite -= nread;
		}

		total += nread;

		/* compare the buffer contents */
		if (memcmp(buf_read, buf_write, BUF_SIZE) != 0) {
			printf("[error code: %d] TXD/RXD test error
", 4);
			goto exit;
		}
	}
	printf("TXD/RXD test passed
");

	/* Set DTR invalid */
	if (libtty_tiocmset(fd, DTR_OFF, RTS_OFF) != 0)
		goto exit;
	usleep(10000);
	ret1 = libtty_tiocmget_check(fd, &modemstatus, DTR_OFF_CMD);

	/* Set DTR valid */
	if (libtty_tiocmset(fd, DTR_ON, RTS_OFF) != 0)
		goto exit;
	usleep(10000);
	ret2 = libtty_tiocmget_check(fd, &modemstatus, DTR_ON_CMD);

	/* Set RTS valid */
	if (libtty_tiocmset(fd, DTR_OFF, RTS_ON) != 0)
		goto exit;
	usleep(10000);
	ret3 = libtty_tiocmget_check(fd, &modemstatus, RTS_ON_CMD);

	if ((ret1 || ret2 || ret3) == 0)
		printf("DTR/RTS/DSR/CTS/DCD/RI test passed
");
	printf("
");

exit:
	return;
}

int main(int argc, char *argv[])
{
	int fd, ret, i, num, nwrite, nread;
	int len_w, pos_w, ret1, ret2, ret3, ret4;
	int total = 0, off = 0;
	char c;
	unsigned long modemstatus;
	unsigned char buf_write[BUF_SIZE];
	unsigned char buf_read[BUF_SIZE];

	parse_opts(argc, argv);
	signal(SIGINT, sig_handler);

	fd = libtty_open(device);
	if (fd < 0) {
		printf("libtty_open: %s error.
", device);
		exit(0);
	}

	/* 2400bps test */
	ret = libtty_setopt(fd, 2400, 8, 1, 'n', hardflow);
	if (ret != 0) {
		printf("libtty_setopt error.
");
		exit(0);
	}
	start_test(fd);

	/* 9600bps test */
	ret = libtty_setopt(fd, 9600, 8, 1, 'n', hardflow);
	if (ret != 0) {
		printf("libtty_setopt error.
");
		exit(0);
	}
	start_test(fd);

	/* 115200bps test */
	ret = libtty_setopt(fd, 115200, 8, 1, 'n', hardflow);
	if (ret != 0) {
		printf("libtty_setopt error.
");
		exit(0);
	}
	start_test(fd);

	ret = libtty_close(fd);
	if (ret != 0) {
		printf("libtty_close error.
");
		exit(0);
	}

	return 0;
}

?

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    7959

    瀏覽量

    265084
  • Linux
    +關注

    關注

    87

    文章

    11320

    瀏覽量

    209851
  • PCI
    PCI
    +關注

    關注

    4

    文章

    670

    瀏覽量

    130337
  • 串口
    +關注

    關注

    14

    文章

    1555

    瀏覽量

    76665
  • PCIe
    +關注

    關注

    15

    文章

    1243

    瀏覽量

    82782
收藏 人收藏

    評論

    相關推薦

    藍牙多串口配置工具

    工具是一種多串口配置工具,基于MCF開發,可以將配置信息同時下發到多個串口,支持配置文件信息下發、文本下發和十六進制下發,一般用于芯片等配置工裝,提高生產效率。 多
    發表于 03-25 19:22

    【U盤量產問題】常見U盤量產的七大問題

    心中有數再動手。另外量產前要先備份U盤的數據,因為一旦量產就會破壞U盤上的所有文件。 2、操作系統:因為量產工具的讀寫需涉及到硬件方面,所以
    發表于 06-24 10:54

    串口工具

    串口工具.exe
    發表于 04-26 16:45 ?37次下載
    <b class='flag-5'>串口</b><b class='flag-5'>工具</b>

    Linux串口編程下載

    linux 中的串口設備文件存放于/dev 目錄下,其中串口一,串口二對應設備名依次為/dev/ttyS0、/dev/ttyS1。在linux
    發表于 11-15 17:39 ?108次下載

    串口調試工具

    串口調試工具 便于單片機下載 串口調試工具 串口調試工具
    發表于 11-20 16:35 ?42次下載

    TxtModify Txt文件內容批量修改工具

    Txt文件內容批量修改工具
    發表于 02-28 23:03 ?0次下載

    Linux系統EXAR方案擴展串口

      本文以Toradex基于NXP i.MX6D/6Q處理器的Apalisi.MX6D/QARM計算機模塊,在Linux系統下通過EXAR方案擴展8路串口。
    發表于 09-18 08:40 ?16次下載

    愛特梅爾Linux Android生態系統工具

    Atmel's Linux Android生態系統工具支持
    的頭像 發表于 07-10 00:21 ?3273次閱讀

    linux命令輕松把單個工具變成批量執行工具

    我們經常遇到這樣的業務場景,我們開發了一個線上工具,需要在Linux操作系統下面執行處理某些事情,例如我們開發了一個將用戶某個活動數據清0的工具,命令如下:。/clearTools -
    的頭像 發表于 01-21 17:36 ?2044次閱讀

    串口驅動到Linux驅動模型

    本文通過對Linux串口驅動的分析。由最上層的C庫。到操作系統系統調用層的封裝。再到tty子系統的核心。再到一系列線路規程。再到最底層的硬
    的頭像 發表于 11-04 14:50 ?2666次閱讀

    Linux系統LPT打印口批量產工具

    該軟件用于在Linux平臺測試CH35X/CH38X(PCI/PCIe轉串并口)的并口各引腳功能是否正常。方便對設備進行出廠測試。
    的頭像 發表于 04-12 11:44 ?2749次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>系統</b>LPT打印口<b class='flag-5'>批量產</b>測<b class='flag-5'>工具</b>

    Windows系統串口批量出廠測試工具

    ? WCHUsbSerTest是一款用于WCH USB轉串口系列產品出廠測試的工具軟件,方便用戶對產品進行批量化功能測試。
    的頭像 發表于 04-12 11:48 ?2927次閱讀
    Windows<b class='flag-5'>系統</b><b class='flag-5'>串口</b><b class='flag-5'>批量</b>出廠測試<b class='flag-5'>工具</b>

    安裝Linux系統安裝工具

    安裝_Linux系統安裝工具,可以安裝各類Linux操作系統。通過iso鏡像文件的格式安裝。也可以安裝在U盤上,本人親測通過。 ?
    發表于 09-11 10:21 ?0次下載

    Banana Pi BPI-W3 RK3588開發平臺批量產測軟件,全面批量測試

    Banana Pi BPI-W3 RK3588開發平臺批量產測軟件,全面批量測試
    的頭像 發表于 11-02 09:08 ?1350次閱讀
    Banana Pi BPI-W3 RK3588開發平臺<b class='flag-5'>批量產</b>測軟件,全面<b class='flag-5'>批量</b>測試

    linux系統備份與還原工具

    Linux系統備份與還原工具是用于備份和恢復Linux操作系統工具。在日常使用中,備份和還原是
    的頭像 發表于 11-23 10:04 ?2668次閱讀
    主站蜘蛛池模板: 日韩精品免费一区二区三区| 老色皮| 校园 春色 欧美 另类 小说| 伊人天堂在线| 亚洲视频欧美视频| 亚欧成人乱码一区二区| 色在线视频网站| 欧美三级第一页| 国产稀缺精品盗摄盗拍| 99国产精品农村一级毛片| 天天躁夜夜躁狠狠躁躁88| 久久久精品免费观看| 日韩激情淫片免费看| 情趣店上班h系列小说| 亚洲精品美女视频| 欧洲性freefree大白屁股| 狠狠色丁香婷婷综合久久来| 站长工具天天爽视频| 久久精品国产免费| 亚洲天堂视频在线观看免费| 最新bt合集| 日本色免费| 成人精品在线观看| 免费午夜不卡毛片| 一区二区三区四区视频| 亚洲婷婷影院| 欧美feer| 站长工具天天爽视频| 国产亚洲美女精品久久久久狼| 中文一区二区在线观看| 亚洲aaaa级特黄毛片| 美女视频一区| 亚洲免费看片| 桃花岛亚洲精品tv自拍网站| 婷五月综合| 久青草免费在线视频| 最近高清免费观看视频大全 | 国产成人乱码一区二区三区| 四虎免费永久观看| 黄色毛片免费网站| 热99re久久精品2久久久|