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_TIME        100// HZ * 2    /* 2 seconds per character */
 30 #define TINY_DATA_CHARACTER    ‘t‘
 31
 32 #define TINY_SERIAL_MAJOR    4 //240    /* experimental range */
 33 #define TINY_SERIAL_MINORS    68 //1    /* only have one minor */
 34 #define UART_NR            1    /* only use one port */
 35
 36 #define TINY_SERIAL_NAME    "ttytiny"
 37
 38 #define MY_NAME            TINY_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;
 52     write_ptr++;
 53     if (write_ptr >= buf + BUF_SIZE)
 54         write_ptr = buf;
 55 }
 56
 57 static void serial_in(char *data)
 58 {
 59     if (read_ptr == NULL) {
 60         DBG("pointer is null !\n");
 61     }
 62
 63     if (read_ptr && (read_ptr != write_ptr)) {
 64         *data = *read_ptr;
 65         read_ptr++;
 66         if(read_ptr >= buf + BUF_SIZE)
 67             read_ptr = buf;
 68     }
 69 }
 70
 71
 72 static void tiny_stop_tx(struct uart_port *port)
 73 {
 74     DBG("tiny_stop_tx()\n");
 75 }
 76
 77 static void tiny_stop_rx(struct uart_port *port)
 78 {
 79     DBG("tiny_stop_rx()\n");
 80 }
 81
 82 static void tiny_enable_ms(struct uart_port *port)
 83 {
 84     DBG("tiny_enable_ms()\n");
 85 }
 86
 87 static void tiny_rx_chars(struct uart_port *port, int size)
 88 {
 89     int i = 0;
 90     char byte;
 91     char flag;
 92     struct tty_port *tty = &port->state->port;
 93
 94     if (size <= 0) {
 95         return;
 96     }
 97
 98     while (size--) {
 99         serial_in(&byte);
100         DBG("read: 0x%2x\n", byte);
101         flag = TTY_NORMAL;
102         port->icount.rx++;
103
104         if (uart_handle_sysrq_char(port, byte)) {
105             DBG("found ignore char !\n");
106             goto ignore_char;
107         }
108
109         uart_insert_char(port, 0, 0, byte, flag);
110 ignore_char:
111         i ++;
112     }
113     tty_flip_buffer_push(tty);
114     DBG("push to user space !\n");
115 }
116
117 static int tiny_tx_chars(struct uart_port *port)
118 {
119     struct circ_buf *xmit = &port->state->xmit;
120     int count;
121
122     DBG("tiny_tx_chars()\n");
123
124     if (port->x_char) {
125         DBG("wrote 0x%2x\r\n", port->x_char);
126         port->icount.tx++;
127         port->x_char = 0;
128         return;
129     }
130     if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
131         tiny_stop_tx(port);
132         return;
133     }
134
135     count = port->fifosize >> 1;
136
137     do {
138         DBG("wrote 0x%2x\r\n", xmit->buf[xmit->tail]);
139         serial_out(xmit->buf[xmit->tail]);
140         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
141         port->icount.tx++;
142         if (uart_circ_empty(xmit))
143             break;
144     } while (--count > 0);
145
146     if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
147         uart_write_wakeup(port);
148
149     if (uart_circ_empty(xmit))
150         tiny_stop_tx(port);
151
152     return ((port->fifosize >> 1) - count + 1);
153 }
154
155 static void tiny_start_tx(struct uart_port *port)
156 {
157     DBG("tiny_start_tx()\n");
158 }
159
160 static void tiny_timer(unsigned long data)
161 {
162     struct uart_port *port;
163     struct tty_port *tport;
164     int ret = 0;
165
166     DBG("tiny_timer()\n");
167     port = (struct uart_port *)data;
168     if (!port)
169         return;
170     if (!port->state)
171         return;
172     tport = &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 */
177     tty_insert_flip_char(tport, TINY_DATA_CHARACTER, 0);
178
179     tty_flip_buffer_push(tport);
180 #endif
181
182     /* resubmit the timer again */
183     timer->expires = jiffies + DELAY_TIME;
184     add_timer(timer);
185
186     /* see if we have any data to transmit */
187     ret = tiny_tx_chars(port);
188     tiny_rx_chars(port, ret);
189 }
190
191 static unsigned int tiny_tx_empty(struct uart_port *port)
192 {
193     DBG("tiny_tx_empty()\n");
194     return 0;
195 }
196
197 static unsigned int tiny_get_mctrl(struct uart_port *port)
198 {
199     DBG("tiny_get_mctrl()\n");
200     return 0;
201 }
202
203 static void tiny_set_mctrl(struct uart_port *port, unsigned int mctrl)
204 {
205     DBG("tiny_set_mctrl()\n");
206 }
207
208 static void tiny_break_ctl(struct uart_port *port, int break_state)
209 {
210     DBG("tiny_set_mctrl()\n");
211 }
212
213 static void tiny_set_termios(struct uart_port *port,
214                  struct ktermios *new, struct ktermios *old)
215 {
216     int baud, quot, cflag = new->c_cflag;
217
218     DBG("tiny_set_termios()\n");
219
220     /* get the byte size */
221     switch (cflag & CSIZE) {
222     case CS5:
223         DBG(" - data bits = 5\n");
224         break;
225     case CS6:
226         DBG(" - data bits = 6\n");
227         break;
228     case CS7:
229         DBG(" - data bits = 7\n");
230         break;
231     default: // CS8
232         DBG(" - data bits = 8\n");
233         break;
234     }
235
236     /* determine the parity */
237     if (cflag & PARENB)
238         if (cflag & PARODD)
239             DBG(" - parity = odd\n");
240         else
241             DBG(" - parity = even\n");
242     else
243         DBG(" - parity = none\n");
244
245     /* figure out the stop bits requested */
246     if (cflag & CSTOPB)
247         DBG(" - stop bits = 2\n");
248     else
249         DBG(" - stop bits = 1\n");
250
251     /* figure out the flow control settings */
252     if (cflag & CRTSCTS)
253         DBG(" - RTS/CTS is enabled\n");
254     else
255         DBG(" - RTS/CTS is disabled\n");
256
257     /* Set baud rate */
258     //baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
259     baud = uart_get_baud_rate(port, new, old, 9600, 115200);
260     quot = 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
271     DBG("tiny_startup()\n");
272
273     /* create our timer and submit it */
274     if (!timer) {
275         timer = kmalloc(sizeof(*timer), GFP_KERNEL);
276         if (!timer)
277             return -ENOMEM;
278         init_timer(timer);
279     }
280     timer->data = (unsigned long)port;
281     timer->expires = jiffies + DELAY_TIME;
282     timer->function = tiny_timer;
283     add_timer(timer);
284     return 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
292     DBG("tiny_shutdown()\n");
293
294     /* shut down our timer */
295     del_timer(timer);
296 }
297
298 static const char *tiny_type(struct uart_port *port)
299 {
300     DBG("tiny_type()\n");
301     return "tinytty";
302 }
303
304 static void tiny_release_port(struct uart_port *port)
305 {
306     DBG("tiny_release_port()\n");
307 }
308
309 static int tiny_request_port(struct uart_port *port)
310 {
311     DBG("tiny_request_port()\n");
312     return 0;
313 }
314
315 static void tiny_config_port(struct uart_port *port, int flags)
316 {
317     DBG("tiny_config_port()\n");
318 }
319
320 static int tiny_verify_port(struct uart_port *port, struct serial_struct *ser)
321 {
322     DBG("tiny_verify_port()\n");
323     return 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 {
366     int result;
367
368     DBG(KERN_INFO "Tiny serial driver loaded\n");
369
370     result = uart_register_driver(&tiny_reg);
371     if (result) {
372         DBG("tiny_init() error!\n");
373         return result;
374     }
375
376     result = uart_add_one_port(&tiny_reg, &tiny_port);
377     if (result) {
378         DBG("uart_add_one_port() error!\n");
379         uart_unregister_driver(&tiny_reg);
380     }
381
382     read_ptr = buf;
383     write_ptr = buf;
384
385     return 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
3     tristate "Tiny UART support"
4     select SERIAL_CORE
5     help
6       This driver supports the virtual UART port.  

device/.../common/rootdir/root/ueventd.xxx.rc

1 ......
2 /dev/ttytiny0             0660     system  system

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

frameworks/base/tests/TinySerialTest/Android.mk

 1 LOCAL_PATH:= $(call my-dir)
 2 include $(CLEAR_VARS)
 3
 4 LOCAL_SRC_FILES:=  5     tiny_serial_test.c
 6
 7 LOCAL_SHARED_LIBRARIES :=  8     libutils   9     libcutils
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.832  2462  2462 W TinySerialTest: succeed to open /dev/ttytiny0 ! 

01-01 08:07:11.855  2462  2462 I TinySerialTest: we can write something to tiny serial ! 

01-01 08:07:11.859  2462  2462 W TinySerialTest: succeed to write ttytiny0 

01-01 08:07:13.023  2462  2462 I TinySerialTest: we have something to read ! 

01-01 08:07:13.023  2462  2462 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()
......
时间: 2024-10-19 11:40:26

Android 串口驱动和应用测试的相关文章

android下调试3G之USB串口驱动集成配置

一.修改Android内核的编译配置 vi ~/myandroid/kernel_imx/.config文件中,确保下面的的配置项已经被选定. (假如源码在~/myandroid目录下) 1. USB电源管理特性的相关配置项: CONFIG_USB_SUSPEND=y 2. USB串口驱动相关的配置项: CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_OPTION=y CONFIG_USB_SERIAL_WWAN=y 3. PPP拨号的相关配置项: CONFIG_PP

tiny4412 串口驱动分析四 --- 修改默认的串口输出

作者:彭东林 邮箱:[email protected] 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 tiny4412默认是从uart0来输出和读取信息的,而tiny4412上留了两个串口,分别对应的是uart0和uart3,下面我们修改配置,使控制终端从uart0变成ua

Android串口通讯

今天在整一个项目,需要利用串口通讯在网上看了好多人的帖子才稍微整出了一点头绪. 首先串口代码就是利用谷歌自己的api,将java代码放在java/android_serialport_api目录下,如果你想改变这个报名需要用jni重新生成so文件,在这里我是直接使用这个包名来简化工作. androidStudio的结构如下: so文件: 在gradle添加依赖: 这样就可以 虽然SerialPort是有报错的但可以不用管他 这样就可以使用串口通信了 使用串口需要手机或者模拟器有对应的口然后还需要

Smart210学习记录------linux串口驱动

转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27025492&id=327609 一.核心数据结构 串口驱动有3个核心数据结构,它们都定义在<#include linux/serial_core.h> 1.uart_driver uart_driver包含了串口设备名.串口驱动名.主次设备号.串口控制台(可选)等信息,还封装了tty_driver(底层串口驱动无需关心tty_driver). struct

Android底层驱动开发(一)

1   Android为什么要加入硬件抽象层HAL A    统一硬件调用接口,所以利用HAL屏蔽linux驱动的复杂不统一的接口 B   解决GPL版权问题,由于linux内核基于GPL协议,这个GPL协议需要开源,而Android遵守Apache License2.0协议,这个协议不要求开源,因此google玩了个穿越,将原本位于Linux驱动中的敏感代码(业务逻辑代码)向上移动了一层,这样这些敏感代码就拜托了GPL协议的束缚,那些不想开源的linux驱动作者不想开源现在就可以不用开源了.

tiny4412 串口驱动分析 --- u-boot中的串口驱动

作者:彭东林 邮箱:[email protected] 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 我们以tiny4412为例分析串口驱动,下面我们从u-boot开始分析,然后再分析到Linux. 串口初始化 关于这部分代码流程参考件:tiny4412 u-boot 启动

12.2440串口驱动程序设计

12.2440串口驱动程序设计 串口的功能就是接受数据跟发送数据的,在上一节已经了解串口的引脚信号.但是数据的收发需要一定的条件,也就是串口的初始化.所以所以今天的内容就会被划分为三个部分: 1.串口的初始化: 创建一个uart.c来对串口进行处理,然后把它加入到Makefile工程文件里: 接着就是串口处理程序的实现了. 程序的刚开始是对串口进行初始化,初始化的步骤: 配置引脚功能 设置数据模式 设置工作模式 设置波特率. 1)配置引脚功能: 在2440里的串口底板原理图: 上面的11 TXD

tiny4412 串口驱动分析七 --- log打印的几个阶段之内核启动阶段(earlyprintk)

作者:彭东林 邮箱:[email protected] 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 u-boot:U-Boot 2010.12 Linux内核版本:linux-3.0.31 Android版本:android-4.1.2 下面要分析的是内核Log打印的几个阶段 自解压阶段 内核启动阶段 内核启动完全以后 shell终端下 在这个阶段内核log打印可以调用printk和printascii,同

BM77SPPS3蓝牙模块串口驱动研究(笔记本通过串口软件调试蓝牙模块)

最近接收一个项目,需要使用microchip公司出品的蓝牙模块,该模块自带陶瓷天线,蓝牙通信有效距离达到20米,支持串口.I2C驱动.本人主要是研究串口驱动,因为是第一次接触蓝牙,那么首先需要对一些概念进行熟悉. 该蓝牙模块的技术资料可以从网址下载:http://download.csdn.net/detail/camelbrand/8957967,首选需要了解该模块的硬件连接图,根据前面下载的资料手册<BM77_Data_Sheet_v2.0r>该模块的封装图如下图所示 本人只使用蓝牙模块的