色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

Linux系統(tǒng)串口批量產測工具

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

1、說明

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

2、串口測試硬件連接

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

1.png

引腳連接示意圖:

?

3、軟件使用方法

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

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

?

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

?

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

./[可執(zhí)行文件] –D [設備節(jié)點路徑]

實例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;
}

?

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

    關注

    60

    文章

    7961

    瀏覽量

    265117
  • Linux
    +關注

    關注

    87

    文章

    11323

    瀏覽量

    209869
  • PCI
    PCI
    +關注

    關注

    4

    文章

    670

    瀏覽量

    130343
  • 串口
    +關注

    關注

    14

    文章

    1555

    瀏覽量

    76679
  • PCIe
    +關注

    關注

    15

    文章

    1243

    瀏覽量

    82797
收藏 人收藏

    評論

    相關推薦

    藍牙多串口配置工具

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

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

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

    串口工具

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

    Linux串口編程下載

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

    串口調試工具

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

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

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

    Linux系統(tǒng)EXAR方案擴展串口

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

    愛特梅爾Linux Android生態(tài)系統(tǒng)工具

    Atmel's Linux Android生態(tài)系統(tǒng)工具支持
    的頭像 發(fā)表于 07-10 00:21 ?3273次閱讀

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

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

    串口驅動到Linux驅動模型

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

    Linux系統(tǒng)LPT打印口批量產工具

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

    Windows系統(tǒng)串口批量出廠測試工具

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

    安裝Linux系統(tǒng)安裝工具

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

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

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

    linux系統(tǒng)備份與還原工具

    Linux系統(tǒng)備份與還原工具是用于備份和恢復Linux操作系統(tǒng)工具。在日常使用中,備份和還原是
    的頭像 發(fā)表于 11-23 10:04 ?2668次閱讀
    主站蜘蛛池模板: 久久精品嫩草影院免费看| 老熟风间由美AV在线一区二区| 久久 这里只精品 免费| 亚洲AV怡红院影院怡春院| 花蝴蝶免费观看影视| 永久免费的污视频网站| 六度影院最新| 国产香蕉视频在线播放| 在线综合 亚洲 欧美| 皮皮在线精品亚洲| 国产精品嫩草免费视频| 亚洲AV日韩AV欧美在线观看网 | 久久re热在线视频精6| 1300部真实小Y女视频合集| 全黄h全肉细节全文| 国产一区二区三区乱码在线观看| 伊人青青青| 亚洲AVAV天堂AV在线网爱情| 日本免费一区二区三区最新vr| 果冻传媒9CM在线观看| 91福利在线观看| 视频专区亚洲欧美日韩| 娇妻玩4P被三个男人伺候电影| 国产白色视频在线观看w| 中文字幕亚洲欧美日韩2019 | 擦擦擦在线视频观看| 亚洲精品在线观看视频| 嫩草影院地址一二三| 国产呻吟久久久久久久92| 成人影院久久久久久影院| 伊人22222| 日本漂亮妈妈7观整有限中| 男女一边摸一边做羞羞的事情免费| 国产AV一区二区三区日韩| 中文字幕无线手机在线| 怡春院欧美一区二区三区免费| 亚洲欧美成人综合| 视频区 国产 欧美 日韩| 日韩亚射吧| 免费无码又爽又黄又刺激网站 | 久久久无码精品亚洲A片猫咪|