Android 串口驱动和应用测试

智者不为愚者谋,勇者不为怯者死。这篇文章主要讲述Android 串口驱动和应用测试相关的知识,希望能为你提供帮助。
 
    这篇博客主要是通过一个简单的例子来了解android的串口驱动和应用,为方便后续对Android
串口服务和USB虚拟串口服务的了解。这个例子中,参考了《Linux Device Drivers》书中的例子,
并在该例子中增加了串口接收的处理。由于手上的机器是手机,硬件上只保留了一个串口用于debug。
而且这里只做一个回环测试,因此使用一个FIFO模拟硬件的读写:

void serial_in(char *data)//硬件:读取串口,FIFO:出队 void serial_out(char data)//硬件:写串口,FIFO:入队


通过这两个函数就可以模拟串口的读写。
    关于linux串口驱动框架,可以参考Linux Device Drivers》书中的《TTY Drivers》章节,比较
简单,这里不再复述。
    串口应用方面的了解,可以参考《Serial Programming Guide for POSIX Operating Systems》
文件,Google可以搜得到。
(A) 添加串口驱动
(B) 添加应用测试
(C) 测试
(A) 添加串口驱动
    主要是注册驱动,配置硬件,提供硬件读写接口,并生成ttyxxx节点,这里是生成ttytiny0,为
用户空间提供串口的读写,配置等接口。
kernel/drivers/tty/serial/tiny_serial.c
1 #include < linux/kernel.h> 2 #include < linux/errno.h> 3 #include < linux/init.h> 4 #include < linux/slab.h> 5 #include < linux/tty.h> 6 #include < linux/tty_flip.h> 7 #include < linux/serial.h> 8 #include < linux/serial_core.h> 9 #include < linux/module.h> 10 11 12 #define TINY_SERIAL_DEBUG 13 #define pr_fmt(fmt) "tiny_serial: " fmt 14 15 #if defined(TINY_SERIAL_DEBUG) 16 #define DBG(fmt, ...)printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) 17 #else 18 #define DBG(fmt, ...)no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 19 #endif 20 21 #define DRIVER_AUTHOR "Greg Kroah-Hartman < [email  protected]> " 22 #define DRIVER_DESC "Tiny serial driver" 23 24 /* Module information */ 25 MODULE_AUTHOR( DRIVER_AUTHOR ); 26 MODULE_DESCRIPTION( DRIVER_DESC ); 27 MODULE_LICENSE("GPL"); 28 29 #define DELAY_TIME100// HZ * 2/* 2 seconds per character */ 30 #define TINY_DATA_CHARACTER‘t‘ 31 32 #define TINY_SERIAL_MAJOR4 //240/* experimental range */ 33 #define TINY_SERIAL_MINORS68 //1/* only have one minor */ 34 #define UART_NR1/* only use one port */ 35 36 #define TINY_SERIAL_NAME"ttytiny" 37 38 #define MY_NAMETINY_SERIAL_NAME 39 40 #define BUF_SIZE 200 41 42 static char buf[BUF_SIZE]; 43 static char *read_ptr; 44 static char *write_ptr; 45 46 static struct timer_list *timer; 47 48 49 static void serial_out(char data) 50 { 51*write_ptr = data; 52write_ptr++; 53if (write_ptr > = buf + BUF_SIZE) 54write_ptr = buf; 55 } 56 57 static void serial_in(char *data) 58 { 59if (read_ptr == NULL) { 60DBG("pointer is null !\n"); 61} 62 63if (read_ptr & & (read_ptr != write_ptr)) { 64*data = https://www.songbingjia.com/android/*read_ptr; 65read_ptr++; 66if(read_ptr > = buf + BUF_SIZE) 67read_ptr = buf; 68} 69 } 70 71 72 static void tiny_stop_tx(struct uart_port *port) 73 { 74DBG("tiny_stop_tx()\n"); 75 } 76 77 static void tiny_stop_rx(struct uart_port *port) 78 { 79DBG("tiny_stop_rx()\n"); 80 } 81 82 static void tiny_enable_ms(struct uart_port *port) 83 { 84DBG("tiny_enable_ms()\n"); 85 } 86 87 static void tiny_rx_chars(struct uart_port *port, int size) 88 { 89int i = 0; 90char byte; 91char flag; 92struct tty_port *tty = & port-> state-> port; 93 94if (size < = 0) { 95return; 96} 97 98while (size--) { 99serial_in(& byte); 100DBG("read: 0x%2x\n", byte); 101flag = TTY_NORMAL; 102port-> icount.rx++; 103 104if (uart_handle_sysrq_char(port, byte)) { 105DBG("found ignore char !\n"); 106goto ignore_char; 107} 108 109uart_insert_char(port, 0, 0, byte, flag); 110 ignore_char: 111i ++; 112} 113tty_flip_buffer_push(tty); 114DBG("push to user space !\n"); 115 } 116 117 static int tiny_tx_chars(struct uart_port *port) 118 { 119struct circ_buf *xmit = & port-> state-> xmit; 120int count; 121 122DBG("tiny_tx_chars()\n"); 123 124if (port-> x_char) { 125DBG("wrote 0x%2x\r\n", port-> x_char); 126port-> icount.tx++; 127port-> x_char = 0; 128return; 129} 130if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { 131tiny_stop_tx(port); 132return; 133} 134 135count = port-> fifosize > > 1; 136 137do { 138DBG("wrote 0x%2x\r\n", xmit-> buf[xmit-> tail]); 139serial_out(xmit-> buf[xmit-> tail]); 140xmit-> tail = (xmit-> tail + 1) & (UART_XMIT_SIZE - 1); 141port-> icount.tx++; 142if (uart_circ_empty(xmit)) 143break; 144} while (--count > 0); 145 146if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 147uart_write_wakeup(port); 148 149if (uart_circ_empty(xmit)) 150tiny_stop_tx(port); 151 152return ((port-> fifosize > > 1) - count + 1); 153 } 154 155 static void tiny_start_tx(struct uart_port *port) 156 { 157DBG("tiny_start_tx()\n"); 158 } 159 160 static void tiny_timer(unsigned long data) 161 { 162struct uart_port *port; 163struct tty_port *tport; 164int ret = 0; 165 166DBG("tiny_timer()\n"); 167port = (struct uart_port *)data; 168if (!port) 169return; 170if (!port-> state) 171return; 172tport = & port-> state-> port; 173 174 #if 0 /* [cgw]: but it really push the data through */ 175/* add one character to the tty port */ 176/* this doesn‘t actually push the data through unless tty-> low_latency is set */ 177tty_insert_flip_char(tport, TINY_DATA_CHARACTER, 0); 178 179tty_flip_buffer_push(tport); 180 #endif 181 182/* resubmit the timer again */ 183timer-> expires = jiffies + DELAY_TIME; 184add_timer(timer); 185 186/* see if we have any data to transmit */ 187ret = tiny_tx_chars(port); 188tiny_rx_chars(port, ret); 189 } 190 191 static unsigned int tiny_tx_empty(struct uart_port *port) 192 { 193DBG("tiny_tx_empty()\n"); 194return 0; 195 } 196 197 static unsigned int tiny_get_mctrl(struct uart_port *port) 198 { 199DBG("tiny_get_mctrl()\n"); 200return 0; 201 } 202 203 static void tiny_set_mctrl(struct uart_port *port, unsigned int mctrl) 204 { 205DBG("tiny_set_mctrl()\n"); 206 } 207 208 static void tiny_break_ctl(struct uart_port *port, int break_state) 209 { 210DBG("tiny_set_mctrl()\n"); 211 } 212 213 static void tiny_set_termios(struct uart_port *port, 214struct ktermios *new, struct ktermios *old) 215 { 216int baud, quot, cflag = new-> c_cflag; 217 218DBG("tiny_set_termios()\n"); 219 220/* get the byte size */ 221switch (cflag & CSIZE) { 222case CS5: 223DBG(" - data bits = 5\n"); 224break; 225case CS6: 226DBG(" - data bits = 6\n"); 227break; 228case CS7: 229DBG(" - data bits = 7\n"); 230break; 231default: // CS8 232DBG(" - data bits = 8\n"); 233break; 234} 235 236/* determine the parity */ 237if (cflag & PARENB) 238if (cflag & PARODD) 239DBG(" - parity = odd\n"); 240else 241DBG(" - parity = even\n"); 242else 243DBG(" - parity = none\n"); 244 245/* figure out the stop bits requested */ 246if (cflag & CSTOPB) 247DBG(" - stop bits = 2\n"); 248else 249DBG(" - stop bits = 1\n"); 250 251/* figure out the flow control settings */ 252if (cflag & CRTSCTS) 253DBG(" - RTS/CTS is enabled\n"); 254else 255DBG(" - RTS/CTS is disabled\n"); 256 257/* Set baud rate */ 258//baud = uart_get_baud_rate(port, new, old, 0, port-> uartclk/16); 259baud = uart_get_baud_rate(port, new, old, 9600, 115200); 260quot = uart_get_divisor(port, baud); 261 262//UART_PUT_DIV_LO(port, (quot & 0xff)); 263//UART_PUT_DIV_HI(port, ((quot & 0xf00) > > 8)); 264 } 265 266 static int tiny_startup(struct uart_port *port) 267 { 268/* this is the first time this port is opened */ 269/* do any hardware initialization needed here */ 270 271DBG("tiny_startup()\n"); 272 273/* create our timer and submit it */ 274if (!timer) { 275timer = kmalloc(sizeof(*timer), GFP_KERNEL); 276if (!timer) 277return -ENOMEM; 278init_timer(timer); 279} 280timer-> data = https://www.songbingjia.com/android/(unsigned long)port; 281timer-> expires = jiffies + DELAY_TIME; 282timer-> function = tiny_timer; 283add_timer(timer); 284return 0; 285 } 286 287 static void tiny_shutdown(struct uart_port *port) 288 { 289/* The port is being closed by the last user. */ 290/* Do any hardware specific stuff here */ 291 292DBG("tiny_shutdown()\n"); 293 294/* shut down our timer */ 295del_timer(timer); 296 } 297 298 static const char *tiny_type(struct uart_port *port) 299 { 300DBG("tiny_type()\n"); 301return "tinytty"; 302 } 303 304 static void tiny_release_port(struct uart_port *port) 305 { 306DBG("tiny_release_port()\n"); 307 } 308 309 static int tiny_request_port(struct uart_port *port) 310 { 311DBG("tiny_request_port()\n"); 312return 0; 313 } 314 315 static void tiny_config_port(struct uart_port *port, int flags) 316 { 317DBG("tiny_config_port()\n"); 318 } 319 320 static int tiny_verify_port(struct uart_port *port, struct serial_struct *ser) 321 { 322DBG("tiny_verify_port()\n"); 323return 0; 324 } 325 326 static struct uart_ops tiny_ops = { 327.tx_empty= tiny_tx_empty, 328.set_mctrl= tiny_set_mctrl, 329.get_mctrl= tiny_get_mctrl, 330.stop_tx= tiny_stop_tx, 331.start_tx= tiny_start_tx, 332.stop_rx= tiny_stop_rx, 333.enable_ms= tiny_enable_ms, 334.break_ctl= tiny_break_ctl, 335.startup= tiny_startup, 336.shutdown= tiny_shutdown, 337.set_termios= tiny_set_termios, 338.type= tiny_type, 339.release_port= tiny_release_port, 340.request_port= tiny_request_port, 341.config_port= tiny_config_port, 342.verify_port= tiny_verify_port, 343 }; 344 345 static struct uart_port tiny_port = { 346.ops= & tiny_ops, 347.line= 0, 348.type= 104, 349.iotype= SERIAL_IO_PORT, 350.fifosize= 128, 351.flags= ASYNC_BOOT_AUTOCONF, 352.irq= 0, 353 }; 354 355 static struct uart_driver tiny_reg = { 356.owner= THIS_MODULE, 357.driver_name= TINY_SERIAL_NAME, 358.dev_name= TINY_SERIAL_NAME, 359.major= TINY_SERIAL_MAJOR, 360.minor= TINY_SERIAL_MINORS, 361.nr= UART_NR, 362 }; 363 364 static int __init tiny_init(void) 365 { 366int result; 367 368DBG(KERN_INFO "Tiny serial driver loaded\n"); 369 370result = uart_register_driver(& tiny_reg); 371if (result) { 372DBG("tiny_init() error!\n"); 373return result; 374} 375 376result = uart_add_one_port(& tiny_reg, & tiny_port); 377if (result) { 378DBG("uart_add_one_port() error!\n"); 379uart_unregister_driver(& tiny_reg); 380} 381 382read_ptr = buf; 383write_ptr = buf; 384 385return result; 386 } 387 388 module_init(tiny_init);

 
kernel/drivers/tty/serial/Makefile 
1 ...... 2 obj-$(CONFIG_SERIAL_TINY_SERIAL) += tiny_serial.o

 
kernel/drivers/tty/serial/Kconfig
1 ...... 2 config SERIAL_TINY_SERIAL 3tristate "Tiny UART support" 4select SERIAL_CORE 5help 6This driver supports the virtual UART port.

 
device/.../common/rootdir/root/ueventd.xxx.rc
1 ...... 2 /dev/ttytiny00660systemsystem

 
 
(B) 添加应用测试
    这是一个简单的串口应用测试,主要是打开串口,设置,读写数据,关闭串口等操作。这里通过
发送“hello, tiny serial driver !”到串口,并从串口读回,模拟回环测试。

frameworks/base/tests/TinySerialTest/tiny_serial_test.c 
1 #define LOG_TAG "TinySerialTest" 2 3 #include < stdio.h> 4 #include < stdlib.h> 5 #include < string.h> 6 #include < strings.h> 7 #include < sys/types.h> 8 #include < sys/stat.h> 9 #include < fcntl.h> 10 #include < unistd.h> 11 #include < utils/Log.h> 12 #include < termios.h> 13 14 #include < sys/select.h> 15 #include < sys/time.h> 16 17 #define PAR_NONE0 18 #define PAR_EVEN1 19 #define PAR_ODD2 20 21 #define DATA_8BIT1 22 #define DATA_7BIT2 23 24 #define STOP_1BIT1 25 #define STOP_2BIT2 26 27 28 struct tiny_op { 29int max_fd; 30int fd; 31fd_set rfds; 32fd_set wfds; 33fd_set efds; 34struct timeval r_timeout; 35struct timeval w_timeout; 36 }; 37 38 static struct tiny_op tops; 39 40 41 static void set_termios(struct termios *termios, int baudrate, int parity, int bits, int stop) 42 { 43termios-> c_cflag |= CLOCAL | CREAD; 44 45termios-> c_cflag & = ~CSIZE; 46switch (bits) { 47case DATA_7BIT: 48termios-> c_cflag |= CS7; 49break; 50 51case DATA_8BIT: 52termios-> c_cflag |= CS8; 53break; 54 55default: 56termios-> c_cflag |= CS8; 57break; 58} 59 60switch (parity) { 61case PAR_NONE: 62termios-> c_cflag & = ~PARENB; 63termios-> c_cflag & = ~PARODD; 64break; 65 66case PAR_EVEN: 67termios-> c_cflag |= PARENB; 68termios-> c_cflag & = ~PARODD; 69break; 70 71case PAR_ODD: 72termios-> c_cflag |= PARENB; 73termios-> c_cflag |= PARODD; 74break; 75 76default: 77termios-> c_cflag & = ~PARENB; 78termios-> c_cflag & = ~PARODD; 79break; 80} 81 82switch (stop) { 83case STOP_1BIT: 84termios-> c_cflag & = ~CSTOPB; 85break; 86 87case STOP_2BIT: 88termios-> c_cflag |= CSTOPB; 89break; 90 91default: 92termios-> c_cflag & = ~CSTOPB; 93break; 94} 95 96termios-> c_iflag |= INPCK | ISTRIP; 97termios-> c_lflag = 0; 98termios-> c_oflag = 0; 99 100termios-> c_cc[VTIME] = 5; 101termios-> c_cc[VMIN]= 0; 102 #if 1 103cfsetspeed(termios, baudrate); 104 #else 105cfsetispeed(termios, baudrate); 106cfsetospeed(termios, baudrate); 107 #endif 108 } 109 110 111 static int tiny_write(struct tiny_op *op, char *buff, int size) 112 { 113int ret = -1; 114int len = 0; 115 116op-> w_timeout.tv_sec= 5; 117op-> w_timeout.tv_usec = 0; 118 119ret = select(op-> max_fd, NULL, & op-> wfds, & op-> efds, & op-> w_timeout); 120if (ret < 0) { 121ALOGE("select failed !"); 122return -1; 123} if (0 == ret) { 124ALOGW("select times out !"); 125} else { 126if (FD_ISSET(op-> fd, & op-> wfds)) { 127ALOGI("we can write something to tiny serial !"); 128len = write(op-> fd, (const void *)buff, size); 129if (len == size) { 130ALOGW("succeed to write ttytiny0"); 131} else { 132ALOGI("len = %d", len); 133} 134} 135 136if (FD_ISSET(op-> fd, & op-> efds)) { 137ALOGW("oops, exception occur !"); 138return -1; 139} 140} 141 142return 0; 143 } 144 145 146 static int tiny_read(struct tiny_op *op, char *buff, int size) 147 { 148int ret = -1; 149int len = 0; 150 151op-> r_timeout.tv_sec = 5; 152op-> r_timeout.tv_usec = 0; 153 154ret = select(op-> max_fd, & op-> rfds, NULL, & op-> efds, & op-> r_timeout); 155if (ret < 0) { 156ALOGE("select failed !"); 157return -1; 158} if (0 == ret) { 159ALOGW("select times out !"); 160} else { 161if (FD_ISSET(op-> fd, & op-> rfds)) { 162ALOGI("we have something to read !"); 163len = read(op-> fd, (void *)buff, size); 164ALOGI("read form tiny serial: %s, len: %d", buff, len); 165} 166 167if (FD_ISSET(op-> fd, & op-> efds)) { 168ALOGW("oops, exception occur !"); 169return -1; 170} 171} 172 173return 0; 174 } 175 176 177 int main(int argc, char **argv) 178 { 179int fd = -1, ret = -1; 180struct termios oldtio, newtio; 181 182char *str = {"hello, tiny serial driver !\0"}; 183char buff[strlen(str)]; 184 185 186bzero((void *)& oldtio, sizeof(oldtio)); 187bzero((void *)& newtio, sizeof(newtio)); 188 189fd = open("/dev/ttytiny0", O_RDWR | O_NOCTTY | O_NONBLOCK); 190if (fd == -1) { 191ALOGW("failed to open /dev/ttytiny0 !"); 192return -1; 193} 194 195ALOGW("succeed to open /dev/ttytiny0 !"); 196 197ret = tcgetattr(fd, & oldtio); 198if (ret != 0) { 199ALOGW("failed to get attr !"); 200close(fd); 201return -1; 202} 203 204set_termios(& newtio, B38400, PAR_EVEN, DATA_8BIT, STOP_1BIT); 205tcflush(fd, TCIOFLUSH); 206 207ret = tcsetattr(fd, TCSANOW, & newtio); 208if (ret != 0) { 209ALOGW("failed to set termios !"); 210close(fd); 211return -1; 212} 213 214tops.fd = fd; 215tops.max_fd = tops.fd + 1; 216 217FD_ZERO(& tops.rfds); 218FD_ZERO(& tops.wfds); 219FD_ZERO(& tops.efds); 220FD_SET(tops.fd, & tops.rfds); 221FD_SET(tops.fd, & tops.wfds); 222FD_SET(tops.fd, & tops.efds); 223 224if (tiny_write(& tops, str, strlen(str)) != 0) { 225close(fd); 226return -1; 227} 228 229if (tiny_read(& tops, buff, sizeof(buff)) != 0) { 230close(fd); 231return -1; 232} 233 234ret = tcsetattr(fd, TCSANOW, & oldtio); 235if (ret != 0) { 236ALOGW("failed to restore attr !"); 237} 238 239tcflush(fd, TCIOFLUSH); 240 241if (close(fd) != 0) { 242ALOGW("failed to close ttytiny0 !"); 243return -1; 244} 245 246return 0; 247 }

 
frameworks/base/tests/TinySerialTest/Android.mk
1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3 4 LOCAL_SRC_FILES:=5tiny_serial_test.c 6 7 LOCAL_SHARED_LIBRARIES :=8libutils9libcutils 10 11 #LOCAL_C_INCLUDES := 12 13 LOCAL_MODULE:= tiny_serial_test 14 15 include $(BUILD_EXECUTABLE)

 
(C) 测试
    mmm编译生成tiny_serial_test.bin文件,push到目标板/system/bin目录,在执行:
用户空间打印:
...... 01-01 08:07:11.83224622462 W TinySerialTest: succeed to open /dev/ttytiny0 ! 01-01 08:07:11.85524622462 I TinySerialTest: we can write something to tiny serial ! 01-01 08:07:11.85924622462 W TinySerialTest: succeed to write ttytiny0 01-01 08:07:13.02324622462 I TinySerialTest: we have something to read ! 01-01 08:07:13.02324622462 I TinySerialTest: read form tiny serial: hello, tiny serial driver !, len: 27

 
kernel打印:
...... 01-01 08:07:11.809 < 1> [180.247772] c0 tiny_serial: tiny_startup() 01-01 08:07:11.809 < 1> [180.251800] c0 tiny_serial: tiny_set_termios() 01-01 08:07:11.822 < 1> [180.256622] c0 tiny_serial:- data bits = 8 01-01 08:07:11.822 < 1> [180.260833] c0 tiny_serial:- parity = none 01-01 08:07:11.822 < 1> [180.265075] c0 tiny_serial:- stop bits = 1 01-01 08:07:11.831 < 1> [180.269531] c0 tiny_serial:- RTS/CTS is disabled 01-01 08:07:11.831 < 1> [180.274261] c0 tiny_serial: tiny_set_mctrl() 01-01 08:07:11.840 < 1> [180.279144] c0 tiny_serial: tiny_set_termios() 01-01 08:07:11.840 < 1> [180.283538] c0 tiny_serial:- data bits = 8 01-01 08:07:11.850 < 1> [180.288452] c0 tiny_serial:- parity = even 01-01 08:07:11.850 < 1> [180.292663] c0 tiny_serial:- stop bits = 1 01-01 08:07:11.859 < 1> [180.297332] c0 tiny_serial:- RTS/CTS is disabled 01-01 08:07:11.859 < 1> [180.302215] c0 tiny_serial: tiny_start_tx() ...... 01-01 08:07:13.022 < 1> [181.246063] c0 tiny_serial: tiny_timer() 01-01 08:07:13.022 < 1> [181.249908] c0 tiny_serial: tiny_tx_chars() 01-01 08:07:13.022 < 1> [181.254089] c0 tiny_serial: wrote 0x68 01-01 08:07:13.022 < 1> [181.257934] c0 tiny_serial: wrote 0x65 01-01 08:07:13.022 < 1> [181.261718] c0 tiny_serial: wrote 0x6c 01-01 08:07:13.022 < 1> [181.265563] c0 tiny_serial: wrote 0x6c 01-01 08:07:13.022 < 1> [181.269409] c0 tiny_serial: wrote 0x6f 01-01 08:07:13.022 < 1> [181.273193] c0 tiny_serial: wrote 0x2c 01-01 08:07:13.022 < 1> [181.277038] c0 tiny_serial: wrote 0x20 01-01 08:07:13.022 < 1> [181.280853] c0 tiny_serial: wrote 0x74 01-01 08:07:13.022 < 1> [181.284667] c0 tiny_serial: wrote 0x69 01-01 08:07:13.022 < 1> [181.288513] c0 tiny_serial: wrote 0x6e 01-01 08:07:13.022 < 1> [181.292327] c0 tiny_serial: wrote 0x79 01-01 08:07:13.022 < 1> [181.296173] c0 tiny_serial: wrote 0x20 01-01 08:07:13.022 < 1> [181.299987] c0 tiny_serial: wrote 0x73 01-01 08:07:13.022 < 1> [181.303802] c0 tiny_serial: wrote 0x65 01-01 08:07:13.022 < 1> [181.307647] c0 tiny_serial: wrote 0x72 01-01 08:07:13.022 < 1> [181.311462] c0 tiny_serial: wrote 0x69 01-01 08:07:13.022 < 1> [181.315277] c0 tiny_serial: wrote 0x61 01-01 08:07:13.022 < 1> [181.319122] c0 tiny_serial: wrote 0x6c 01-01 08:07:13.022 < 1> [181.322937] c0 tiny_serial: wrote 0x20 01-01 08:07:13.022 < 1> [181.326782] c0 tiny_serial: wrote 0x64 01-01 08:07:13.022 < 1> [181.330566] c0 tiny_serial: wrote 0x72 01-01 08:07:13.022 < 1> [181.334411] c0 tiny_serial: wrote 0x69 01-01 08:07:13.022 < 1> [181.338256] c0 tiny_serial: wrote 0x76 01-01 08:07:13.022 < 1> [181.342041] c0 tiny_serial: wrote 0x65 01-01 08:07:13.022 < 1> [181.345886] c0 tiny_serial: wrote 0x72 01-01 08:07:13.022 < 1> [181.349731] c0 tiny_serial: wrote 0x20 01-01 08:07:13.022 < 1> [181.353515] c0 tiny_serial: wrote 0x21 01-01 08:07:13.022 < 1> [181.357360] c0 tiny_serial: tiny_stop_tx() 01-01 08:07:13.022 < 1> [181.361419] c0 tiny_serial: read: 0x68 01-01 08:07:13.022 < 1> [181.365173] c0 tiny_serial: read: 0x65 01-01 08:07:13.022 < 1> [181.368927] c0 tiny_serial: read: 0x6c 01-01 08:07:13.022 < 1> [181.372650] c0 tiny_serial: read: 0x6c 01-01 08:07:13.022 < 1> [181.376403] c0 tiny_serial: read: 0x6f 01-01 08:07:13.022 < 1> [181.380126] c0 tiny_serial: read: 0x2c 01-01 08:07:13.022 < 1> [181.383850] c0 tiny_serial: read: 0x20 01-01 08:07:13.022 < 1> [181.387634] c0 tiny_serial: read: 0x74 01-01 08:07:13.022 < 1> [181.391326] c0 tiny_serial: read: 0x69 01-01 08:07:13.022 < 1> [181.395080] c0 tiny_serial: read: 0x6e 01-01 08:07:13.022 < 1> [181.398834] c0 tiny_serial: read: 0x79 01-01 08:07:13.022 < 1> [181.402557] c0 tiny_serial: read: 0x20 01-01 08:07:13.022 < 1> [181.406311] c0 tiny_serial: read: 0x73 01-01 08:07:13.022 < 1> [181.410034] c0 tiny_serial: read: 0x65 01-01 08:07:13.022 < 1> [181.413757] c0 tiny_serial: read: 0x72 01-01 08:07:13.022 < 1> [181.417572] c0 tiny_serial: read: 0x69 01-01 08:07:13.022 < 1> [181.421234] c0 tiny_serial: read: 0x61 01-01 08:07:13.022 < 1> [181.424987] c0 tiny_serial: read: 0x6c 01-01 08:07:13.022 < 1> [181.428741] c0 tiny_serial: read: 0x20 01-01 08:07:13.022 < 1> [181.432464] c0 tiny_serial: read: 0x64 01-01 08:07:13.022 < 1> [181.436218] c0 tiny_serial: read: 0x72 01-01 08:07:13.022 < 1> [181.439941] c0 tiny_serial: read: 0x69 01-01 08:07:13.022 < 1> [181.443664] c0 tiny_serial: read: 0x76 01-01 08:07:13.022 < 1> [181.447448] c0 tiny_serial: read: 0x65 01-01 08:07:13.022 < 1> [181.451141] c0 tiny_serial: read: 0x72 01-01 08:07:13.022 < 1> [181.454864] c0 tiny_serial: read: 0x20 01-01 08:07:13.022 < 1> [181.458648] c0 tiny_serial: read: 0x21 01-01 08:07:13.022 < 1> [181.462371] c0 tiny_serial: push to user space ! ...... 01-01 08:07:13.031 < 1> [181.470153] c0 tiny_serial: tiny_set_termios() 01-01 08:07:13.031 < 1> [181.474517] c0 tiny_serial:- data bits = 8 01-01 08:07:13.043 < 1> [181.479492] c0 tiny_serial:- parity = none 01-01 08:07:13.043 < 1> [181.483673] c0 tiny_serial:- stop bits = 1 ...... 01-01 08:07:13.052 < 1> [181.490936] c0 tiny_serial:- RTS/CTS is disabled 01-01 08:07:13.052 < 1> [181.495758] c0 tiny_serial: tiny_tx_empty() ...... 01-01 08:07:23.081 < 1> [191.520050] c0 tiny_serial: tiny_stop_rx() 01-01 08:07:23.081 < 1> [191.524078] c0 tiny_serial: tiny_tx_empty()01-01 08:07:23.090 < 1> [191.528594] c0 tiny_serial: tiny_set_mctrl() 01-01 08:07:23.090 < 1> [191.532806] c0 tiny_serial: tiny_shutdown() ......

【Android 串口驱动和应用测试】 
















    推荐阅读