[LTP] [PATCH 2/2] device_drivers/uart01: uart01 test extension

gengcixi@gmail.com gengcixi@gmail.com
Wed Aug 12 09:35:29 CEST 2020


From: Cixi Geng <cixi.geng1@unisoc.com>

expand the uart01 test to support more options:
    -f: create a file with ramdom content,and test uart use the file
	to transfer data
    -l: support to loop test with loop number
    -k: support loopback mode test

modify: make UART_Rx and UART_Tx test into the same UART_DEV for we
usually test uart transceiver function together.

This is an updated version which comes from patch written by Cyril

https://patchwork.ozlabs.org/project/ltp/patch/20200623112827.10744-3-chrubis@suse.cz/

Signed-off-by: Cixi Geng <cixi.geng1@unisoc.com>
---
 runtest/kernel_misc                           | 10 +-
 testcases/kernel/device-drivers/Makefile      |  1 +
 testcases/kernel/device-drivers/uart/uart01.c | 94 +++++++++++++++----
 3 files changed, 80 insertions(+), 25 deletions(-)

diff --git a/runtest/kernel_misc b/runtest/kernel_misc
index a7f1d9b56..977a15697 100644
--- a/runtest/kernel_misc
+++ b/runtest/kernel_misc
@@ -13,8 +13,8 @@ zram01 zram01.sh
 zram02 zram02.sh
 zram03 zram03
 umip_basic_test umip_basic_test
-uart01_9600 uart01 -b 9600
-uart01_19200 uart01 -b 19200
-uart01_38400 uart01 -b 38400
-uart01_57600 uart01 -b 57600
-uart01_115200 uart01 -b 115200
+uart01_9600 uart01 -b 9600 -f binary -k 0 -l 2
+uart01_19200 uart01 -b 19200 -f binary -k 0 -l 3
+uart01_38400 uart01 -b 38400 -f binary -k 0 -l 1
+uart01_57600 uart01 -b 57600 -f binary -k 0 -l 3
+uart01_115200 uart01 -b 115200 -f /binary -k 0 -l 5
diff --git a/testcases/kernel/device-drivers/Makefile b/testcases/kernel/device-drivers/Makefile
index 55e0d25a0..be0d88e38 100644
--- a/testcases/kernel/device-drivers/Makefile
+++ b/testcases/kernel/device-drivers/Makefile
@@ -24,6 +24,7 @@ SUBDIRS		:= acpi \
 		   locking \
 		   pci \
 		   rcu \
+		   uart \
 		   rtc \
 		   tbio \
 		   uaccess \
diff --git a/testcases/kernel/device-drivers/uart/uart01.c b/testcases/kernel/device-drivers/uart/uart01.c
index 4647c55e3..0501cb462 100644
--- a/testcases/kernel/device-drivers/uart/uart01.c
+++ b/testcases/kernel/device-drivers/uart/uart01.c
@@ -22,6 +22,10 @@
 #include <linux/serial.h>
 
 #include "tst_test.h"
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
 
 static const char hex_asc[] = "0123456789abcdef";
 #define hex_asc_lo(x)	hex_asc[((x) & 0x0f)]
@@ -39,6 +43,7 @@ struct g_opt {
 #define MODE_DUPLEX     (MODE_TX_ONLY | MODE_RX_ONLY)
 	unsigned int mode;
 	unsigned char *cmp_buff;
+	unsigned char loopback;
 };
 
 static int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
@@ -187,7 +192,6 @@ static int stress_test_uart_once(struct g_opt *opts, int fd, unsigned char *data
 			.fd = fd,
 		};
 		int ret;
-
 		if (opts->mode & MODE_RX_ONLY && progress_rx < data_len) {
 			pfd.events |= POLLIN;
 			wait_rx = 1;
@@ -296,7 +300,6 @@ static int stress_test_uart(struct g_opt *opts, int fd, unsigned char *data, off
 
 	opts->cmp_buff = SAFE_MALLOC(data_len);
 	memset(opts->cmp_buff, 0, data_len);
-
 	do {
 		status = stress_test_uart_once(opts, fd, data, data_len);
 		memset(opts->cmp_buff, 0, data_len);
@@ -307,14 +310,30 @@ static int stress_test_uart(struct g_opt *opts, int fd, unsigned char *data, off
 	return status;
 }
 
+void set_modem(int fd, int bits, int mask)
+{
+	int status, ret;
+
+	ret = ioctl(fd, TIOCMGET, &status);
+	if (ret < 0)
+		tst_brk(TBROK,"mcr get failed: %m\n");
+
+	status = (status & ~mask) | (bits & mask);
+
+	ret = ioctl(fd, TIOCMSET, &status);
+	if (ret < 0)
+		tst_brk(TBROK,"mcr set failed: %m\n");
+}
+
 static int setup_uart(struct g_opt *opts, int open_mode, struct termios *old_term)
 {
 	struct termios new_term;
+	struct serial_icounter_struct old_counters;
+	struct serial_icounter_struct new_counters;
 	int fd;
 	int ret;
-
-	tst_res(TINFO, "Setting up %s speed %u hwflow=%u",
-	        opts->uart_dev, opts->baud_rate, opts->hwflow);
+	tst_res(TINFO, "Setting up %s speed %u hwflow=%u,loops=%u,loopback %u",
+	        opts->uart_dev, opts->baud_rate, opts->hwflow,opts->loops,opts->loopback);
 
 	fd = SAFE_OPEN(opts->uart_dev, open_mode | O_NONBLOCK);
 
@@ -347,6 +366,18 @@ static int setup_uart(struct g_opt *opts, int open_mode, struct termios *old_ter
 			tst_brk(TBROK, "tcflush failed: %m\n");
 	}
 
+	ret = fcntl(fd, F_SETFL, 0);
+	if (ret)
+		printf("Failed to remove nonblock mode\n");
+
+	// set loopback modem
+
+	set_modem(fd, opts->loopback ? TIOCM_LOOP : 0, TIOCM_LOOP);
+
+	ret = ioctl(fd, TIOCGICOUNT, &old_counters);
+	if (ret)
+		printf("Failed to set loopback mode\n");
+
 	ret = fcntl(fd, F_SETFL, 0);
 	if (ret)
 		printf("Failed to remove nonblock mode\n");
@@ -359,6 +390,7 @@ static void restore_uart(int fd, struct termios *old_term)
 	int ret = tcsetattr(fd, TCSAFLUSH, old_term);
 	if (ret)
 		printf("tcsetattr() of old ones failed: %m\n");
+	set_modem(fd, 0, TIOCM_LOOP);
 }
 
 static void print_counters(const char *prefix,
@@ -378,6 +410,7 @@ static struct g_opt opts = {
 	.baud_rate = 115200,
 	.loops = 1,
 	.do_termios = 1,
+	.loopback = 0,
 };
 
 static char *uart_rx;
@@ -404,10 +437,7 @@ void run(void)
 
 	fd_rx = setup_uart(&opts_in, O_RDONLY, &old_term_rx);
 
-	if (!strcmp(uart_rx, uart_tx))
-		fd_tx = SAFE_OPEN(uart_tx, O_WRONLY);
-	else
-		fd_tx = setup_uart(&opts_out, O_WRONLY, &old_term_tx);
+	fd_tx = setup_uart(&opts_out, O_WRONLY, &old_term_tx);
 
 	if (!SAFE_FORK()) {
 		ioctl(fd_rx, TIOCGICOUNT, &old_counters);
@@ -439,22 +469,36 @@ void run(void)
 	close(fd_tx);
 }
 
-static void map_file(const char *fname)
+static void map_file(const char *fname,int baud)
 {
 	struct stat st;
+	int size;
 	int fd;
+	char c;
+	FILE *f_des,*f_src;
+
+	size = baud;
 
-	fd = SAFE_OPEN(fname, O_RDONLY);
+	fd = SAFE_OPEN(fname, O_RDWR|O_CREAT);
+	f_src = fopen("/dev/urandom","r");
+	f_des = fopen(fname,"w+");
 
 	SAFE_FSTAT(fd, &st);
 
-	data_len = st.st_size;
+	data_len = size;
 
 	data = SAFE_MMAP(NULL, data_len, PROT_READ,
 	                 MAP_SHARED | MAP_LOCKED | MAP_POPULATE, fd, 0);
 
 	tst_res(TINFO, "Mapped file '%s' size %li bytes", fname, data_len);
+	while(size--)
+	{
+		c = fgetc(f_src);
+		fputc(c,f_des);
+	}
 
+	fclose(f_des);
+	fclose(f_src);
 	SAFE_CLOSE(fd);
 }
 
@@ -479,6 +523,8 @@ static void map_buffer(long buf_size)
 
 static char *baud_rate;
 static char *hwflow;
+static char *loops;
+static char *loopback;
 static char *fname;
 static char *buf_size;
 
@@ -492,17 +538,23 @@ static void setup(void)
 	if (hwflow)
 		opts.hwflow = 1;
 
+	if (loops)
+		tst_parse_int(loops, &(opts.loops), 0, INT_MAX);
+
+	if (loopback)
+		tst_parse_int(loopback, &(opts.loopback), 0, INT_MAX);
+
 	if (fname && buf_size)
 		tst_brk(TBROK, "Only one of -f and -s could be set!");
 
 	if (buf_size)
 		tst_parse_long(buf_size, &size, 0, LONG_MAX);
 
-	uart_rx = getenv("UART_RX");
-	uart_tx = getenv("UART_TX");
+	uart_rx = getenv("UART_DEV");
+	uart_tx = getenv("UART_DEV");
 
 	if (fname)
-		map_file(fname);
+		map_file(fname,opts.baud_rate);
 	else
 		map_buffer(size);
 }
@@ -511,12 +563,14 @@ static struct tst_test test = {
 	.setup = setup,
 	.test_all = run,
 	.options = (struct tst_option[]) {
-		{"b:", &baud_rate, "-b       Baud rate (9600, ...)"},
-		{"w",  &hwflow   , "-w       Enable hwflow (RTS/CTS)"},
-		{"f:",  &fname,    "-f       Binary file for transfers"},
-		{"s:",  &buf_size, "-s       Binary buffer size"},
+		{"b:",  &baud_rate, "-b       Baud rate (9600, ...)"},
+		{"w",   &hwflow,    "-w       Enable hwflow (RTS/CTS)"},
+		{"f:",  &fname,     "-f       Binary file for transfers"},
+		{"l:",  &loops,     "-l       loops to perform(0=>wait for CTRL-C"},
+		{"s:",  &buf_size,  "-s       Binary buffer size"},
+		{"k:",  &loopback,  "-k       Enable loopback modem"},
 		{}
 	},
-	.needs_devices = (const char *const[]) {"UART_RX", "UART_TX", NULL},
+	.needs_devices = (const char *const[]) {"UART_DEV",NULL},
 	.forks_child = 1,
 };
-- 
2.17.1



More information about the ltp mailing list