篇博客主要是通过一个简单的例子来了解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

 #include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
#include <linux/serial_core.h>
#include <linux/module.h> #define TINY_SERIAL_DEBUG
#define pr_fmt(fmt) "tiny_serial: " fmt #if defined(TINY_SERIAL_DEBUG)
#define DBG(fmt, ...) printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
#else
#define DBG(fmt, ...) no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
#endif #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "Tiny serial driver" /* Module information */
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL"); #define DELAY_TIME 100// HZ * 2 /* 2 seconds per character */
#define TINY_DATA_CHARACTER 't' #define TINY_SERIAL_MAJOR 4 //240 /* experimental range */
#define TINY_SERIAL_MINORS 68 //1 /* only have one minor */
#define UART_NR 1 /* only use one port */ #define TINY_SERIAL_NAME "ttytiny" #define MY_NAME TINY_SERIAL_NAME #define BUF_SIZE 200 static char buf[BUF_SIZE];
static char *read_ptr;
static char *write_ptr; static struct timer_list *timer; static void serial_out(char data)
{
*write_ptr = data;
write_ptr++;
if (write_ptr >= buf + BUF_SIZE)
write_ptr = buf;
} static void serial_in(char *data)
{
if (read_ptr == NULL) {
DBG("pointer is null !\n");
} if (read_ptr && (read_ptr != write_ptr)) {
*data = *read_ptr;
read_ptr++;
if(read_ptr >= buf + BUF_SIZE)
read_ptr = buf;
}
} static void tiny_stop_tx(struct uart_port *port)
{
DBG("tiny_stop_tx()\n");
} static void tiny_stop_rx(struct uart_port *port)
{
DBG("tiny_stop_rx()\n");
} static void tiny_enable_ms(struct uart_port *port)
{
DBG("tiny_enable_ms()\n");
} static void tiny_rx_chars(struct uart_port *port, int size)
{
int i = ;
char byte;
char flag;
struct tty_port *tty = &port->state->port; if (size <= ) {
return;
} while (size--) {
serial_in(&byte);
DBG("read: 0x%2x\n", byte);
flag = TTY_NORMAL;
port->icount.rx++; if (uart_handle_sysrq_char(port, byte)) {
DBG("found ignore char !\n");
goto ignore_char;
} uart_insert_char(port, , , byte, flag);
ignore_char:
i ++;
}
tty_flip_buffer_push(tty);
DBG("push to user space !\n");
} static int tiny_tx_chars(struct uart_port *port)
{
struct circ_buf *xmit = &port->state->xmit;
int count; DBG("tiny_tx_chars()\n"); if (port->x_char) {
DBG("wrote 0x%2x\r\n", port->x_char);
port->icount.tx++;
port->x_char = ;
return;
}
if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
tiny_stop_tx(port);
return;
} count = port->fifosize >> ; do {
DBG("wrote 0x%2x\r\n", xmit->buf[xmit->tail]);
serial_out(xmit->buf[xmit->tail]);
xmit->tail = (xmit->tail + ) & (UART_XMIT_SIZE - );
port->icount.tx++;
if (uart_circ_empty(xmit))
break;
} while (--count > ); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
uart_write_wakeup(port); if (uart_circ_empty(xmit))
tiny_stop_tx(port); return ((port->fifosize >> ) - count + );
} static void tiny_start_tx(struct uart_port *port)
{
DBG("tiny_start_tx()\n");
} static void tiny_timer(unsigned long data)
{
struct uart_port *port;
struct tty_port *tport;
int ret = ; DBG("tiny_timer()\n");
port = (struct uart_port *)data;
if (!port)
return;
if (!port->state)
return;
tport = &port->state->port; #if 0 /* [cgw]: but it really push the data through */
/* add one character to the tty port */
/* this doesn't actually push the data through unless tty->low_latency is set */
tty_insert_flip_char(tport, TINY_DATA_CHARACTER, ); tty_flip_buffer_push(tport);
#endif /* resubmit the timer again */
timer->expires = jiffies + DELAY_TIME;
add_timer(timer); /* see if we have any data to transmit */
ret = tiny_tx_chars(port);
tiny_rx_chars(port, ret);
} static unsigned int tiny_tx_empty(struct uart_port *port)
{
DBG("tiny_tx_empty()\n");
return ;
} static unsigned int tiny_get_mctrl(struct uart_port *port)
{
DBG("tiny_get_mctrl()\n");
return ;
} static void tiny_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
DBG("tiny_set_mctrl()\n");
} static void tiny_break_ctl(struct uart_port *port, int break_state)
{
DBG("tiny_set_mctrl()\n");
} static void tiny_set_termios(struct uart_port *port,
struct ktermios *new, struct ktermios *old)
{
int baud, quot, cflag = new->c_cflag; DBG("tiny_set_termios()\n"); /* get the byte size */
switch (cflag & CSIZE) {
case CS5:
DBG(" - data bits = 5\n");
break;
case CS6:
DBG(" - data bits = 6\n");
break;
case CS7:
DBG(" - data bits = 7\n");
break;
default: // CS8
DBG(" - data bits = 8\n");
break;
} /* determine the parity */
if (cflag & PARENB)
if (cflag & PARODD)
DBG(" - parity = odd\n");
else
DBG(" - parity = even\n");
else
DBG(" - parity = none\n"); /* figure out the stop bits requested */
if (cflag & CSTOPB)
DBG(" - stop bits = 2\n");
else
DBG(" - stop bits = 1\n"); /* figure out the flow control settings */
if (cflag & CRTSCTS)
DBG(" - RTS/CTS is enabled\n");
else
DBG(" - RTS/CTS is disabled\n"); /* Set baud rate */
//baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
baud = uart_get_baud_rate(port, new, old, , );
quot = uart_get_divisor(port, baud); //UART_PUT_DIV_LO(port, (quot & 0xff));
//UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
} static int tiny_startup(struct uart_port *port)
{
/* this is the first time this port is opened */
/* do any hardware initialization needed here */ DBG("tiny_startup()\n"); /* create our timer and submit it */
if (!timer) {
timer = kmalloc(sizeof(*timer), GFP_KERNEL);
if (!timer)
return -ENOMEM;
init_timer(timer);
}
timer->data = (unsigned long)port;
timer->expires = jiffies + DELAY_TIME;
timer->function = tiny_timer;
add_timer(timer);
return ;
} static void tiny_shutdown(struct uart_port *port)
{
/* The port is being closed by the last user. */
/* Do any hardware specific stuff here */ DBG("tiny_shutdown()\n"); /* shut down our timer */
del_timer(timer);
} static const char *tiny_type(struct uart_port *port)
{
DBG("tiny_type()\n");
return "tinytty";
} static void tiny_release_port(struct uart_port *port)
{
DBG("tiny_release_port()\n");
} static int tiny_request_port(struct uart_port *port)
{
DBG("tiny_request_port()\n");
return ;
} static void tiny_config_port(struct uart_port *port, int flags)
{
DBG("tiny_config_port()\n");
} static int tiny_verify_port(struct uart_port *port, struct serial_struct *ser)
{
DBG("tiny_verify_port()\n");
return ;
} static struct uart_ops tiny_ops = {
.tx_empty = tiny_tx_empty,
.set_mctrl = tiny_set_mctrl,
.get_mctrl = tiny_get_mctrl,
.stop_tx = tiny_stop_tx,
.start_tx = tiny_start_tx,
.stop_rx = tiny_stop_rx,
.enable_ms = tiny_enable_ms,
.break_ctl = tiny_break_ctl,
.startup = tiny_startup,
.shutdown = tiny_shutdown,
.set_termios = tiny_set_termios,
.type = tiny_type,
.release_port = tiny_release_port,
.request_port = tiny_request_port,
.config_port = tiny_config_port,
.verify_port = tiny_verify_port,
}; static struct uart_port tiny_port = {
.ops = &tiny_ops,
.line = ,
.type = ,
.iotype = SERIAL_IO_PORT,
.fifosize = ,
.flags = ASYNC_BOOT_AUTOCONF,
.irq = ,
}; static struct uart_driver tiny_reg = {
.owner = THIS_MODULE,
.driver_name = TINY_SERIAL_NAME,
.dev_name = TINY_SERIAL_NAME,
.major = TINY_SERIAL_MAJOR,
.minor = TINY_SERIAL_MINORS,
.nr = UART_NR,
}; static int __init tiny_init(void)
{
int result; DBG(KERN_INFO "Tiny serial driver loaded\n"); result = uart_register_driver(&tiny_reg);
if (result) {
DBG("tiny_init() error!\n");
return result;
} result = uart_add_one_port(&tiny_reg, &tiny_port);
if (result) {
DBG("uart_add_one_port() error!\n");
uart_unregister_driver(&tiny_reg);
} read_ptr = buf;
write_ptr = buf; return result;
} module_init(tiny_init);

kernel/drivers/tty/serial/Makefile 

 ......
obj-$(CONFIG_SERIAL_TINY_SERIAL) += tiny_serial.o

kernel/drivers/tty/serial/Kconfig

 ......
config SERIAL_TINY_SERIAL
tristate "Tiny UART support"
select SERIAL_CORE
help
This driver supports the virtual UART port.

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

 ......
/dev/ttytiny0 system system

(B) 添加应用测试

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

frameworks/base/tests/TinySerialTest/tiny_serial_test.c 

 #define LOG_TAG "TinySerialTest"

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <utils/Log.h>
#include <termios.h> #include <sys/select.h>
#include <sys/time.h> #define PAR_NONE 0
#define PAR_EVEN 1
#define PAR_ODD 2 #define DATA_8BIT 1
#define DATA_7BIT 2 #define STOP_1BIT 1
#define STOP_2BIT 2 struct tiny_op {
int max_fd;
int fd;
fd_set rfds;
fd_set wfds;
fd_set efds;
struct timeval r_timeout;
struct timeval w_timeout;
}; static struct tiny_op tops; static void set_termios(struct termios *termios, int baudrate, int parity, int bits, int stop)
{
termios->c_cflag |= CLOCAL | CREAD; termios->c_cflag &= ~CSIZE;
switch (bits) {
case DATA_7BIT:
termios->c_cflag |= CS7;
break; case DATA_8BIT:
termios->c_cflag |= CS8;
break; default:
termios->c_cflag |= CS8;
break;
} switch (parity) {
case PAR_NONE:
termios->c_cflag &= ~PARENB;
termios->c_cflag &= ~PARODD;
break; case PAR_EVEN:
termios->c_cflag |= PARENB;
termios->c_cflag &= ~PARODD;
break; case PAR_ODD:
termios->c_cflag |= PARENB;
termios->c_cflag |= PARODD;
break; default:
termios->c_cflag &= ~PARENB;
termios->c_cflag &= ~PARODD;
break;
} switch (stop) {
case STOP_1BIT:
termios->c_cflag &= ~CSTOPB;
break; case STOP_2BIT:
termios->c_cflag |= CSTOPB;
break; default:
termios->c_cflag &= ~CSTOPB;
break;
} termios->c_iflag |= INPCK | ISTRIP;
termios->c_lflag = ;
termios->c_oflag = ; termios->c_cc[VTIME] = ;
termios->c_cc[VMIN] = ;
#if 1
cfsetspeed(termios, baudrate);
#else
cfsetispeed(termios, baudrate);
cfsetospeed(termios, baudrate);
#endif
} static int tiny_write(struct tiny_op *op, char *buff, int size)
{
int ret = -;
int len = ; op->w_timeout.tv_sec = ;
op->w_timeout.tv_usec = ; ret = select(op->max_fd, NULL, &op->wfds, &op->efds, &op->w_timeout);
if (ret < ) {
ALOGE("select failed !");
return -;
} if ( == ret) {
ALOGW("select times out !");
} else {
if (FD_ISSET(op->fd, &op->wfds)) {
ALOGI("we can write something to tiny serial !");
len = write(op->fd, (const void *)buff, size);
if (len == size) {
ALOGW("succeed to write ttytiny0");
} else {
ALOGI("len = %d", len);
}
} if (FD_ISSET(op->fd, &op->efds)) {
ALOGW("oops, exception occur !");
return -;
}
} return ;
} static int tiny_read(struct tiny_op *op, char *buff, int size)
{
int ret = -;
int len = ; op->r_timeout.tv_sec = ;
op->r_timeout.tv_usec = ; ret = select(op->max_fd, &op->rfds, NULL, &op->efds, &op->r_timeout);
if (ret < ) {
ALOGE("select failed !");
return -;
} if ( == ret) {
ALOGW("select times out !");
} else {
if (FD_ISSET(op->fd, &op->rfds)) {
ALOGI("we have something to read !");
len = read(op->fd, (void *)buff, size);
ALOGI("read form tiny serial: %s, len: %d", buff, len);
} if (FD_ISSET(op->fd, &op->efds)) {
ALOGW("oops, exception occur !");
return -;
}
} return ;
} int main(int argc, char **argv)
{
int fd = -, ret = -;
struct termios oldtio, newtio; char *str = {"hello, tiny serial driver !\0"};
char buff[strlen(str)]; bzero((void *)&oldtio, sizeof(oldtio));
bzero((void *)&newtio, sizeof(newtio)); fd = open("/dev/ttytiny0", O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -) {
ALOGW("failed to open /dev/ttytiny0 !");
return -;
} ALOGW("succeed to open /dev/ttytiny0 !"); ret = tcgetattr(fd, &oldtio);
if (ret != ) {
ALOGW("failed to get attr !");
close(fd);
return -;
} set_termios(&newtio, B38400, PAR_EVEN, DATA_8BIT, STOP_1BIT);
tcflush(fd, TCIOFLUSH); ret = tcsetattr(fd, TCSANOW, &newtio);
if (ret != ) {
ALOGW("failed to set termios !");
close(fd);
return -;
} tops.fd = fd;
tops.max_fd = tops.fd + ; FD_ZERO(&tops.rfds);
FD_ZERO(&tops.wfds);
FD_ZERO(&tops.efds);
FD_SET(tops.fd, &tops.rfds);
FD_SET(tops.fd, &tops.wfds);
FD_SET(tops.fd, &tops.efds); if (tiny_write(&tops, str, strlen(str)) != ) {
close(fd);
return -;
} if (tiny_read(&tops, buff, sizeof(buff)) != ) {
close(fd);
return -;
} ret = tcsetattr(fd, TCSANOW, &oldtio);
if (ret != ) {
ALOGW("failed to restore attr !");
} tcflush(fd, TCIOFLUSH); if (close(fd) != ) {
ALOGW("failed to close ttytiny0 !");
return -;
} return ;
}

frameworks/base/tests/TinySerialTest/Android.mk

 LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) LOCAL_SRC_FILES:= \
tiny_serial_test.c LOCAL_SHARED_LIBRARIES := \
libutils \
libcutils #LOCAL_C_INCLUDES := \ LOCAL_MODULE:= tiny_serial_test include $(BUILD_EXECUTABLE)

(C) 测试

mmm编译生成tiny_serial_test.bin文件,push到目标板/system/bin目录,在执行:
用户空间打印:

......
- ::11.832 W TinySerialTest: succeed to open /dev/ttytiny0 ! - ::11.855 I TinySerialTest: we can write something to tiny serial ! - ::11.859 W TinySerialTest: succeed to write ttytiny0 - ::13.023 I TinySerialTest: we have something to read ! - ::13.023 I TinySerialTest: read form tiny serial: hello, tiny serial driver !, len:

kernel打印:

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

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

  1. Android串口通讯

    今天在整一个项目,需要利用串口通讯在网上看了好多人的帖子才稍微整出了一点头绪. 首先串口代码就是利用谷歌自己的api,将java代码放在java/android_serialport_api目录下,如 ...

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

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

  3. Yocto开发笔记之《串口驱动调试》(QQ交流群:519230208)

    QQ群:519230208,为避免广告骚扰,申请时请注明 “开发者” 字样 ======================================================== 串口驱动各 ...

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

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=27025492&id=327609 一.核心数据结构 串口驱动有 ...

  5. Android 串口设置校验位、速率、停止位等参数

    Android 串口通讯设置校验位.速率.停止位等参数 最近业余时间有个android项目需要和硬件进行通信,通讯方式都是通过串口,android串口通讯google有个开源的demo 和很多人一样我 ...

  6. android 串口开发第二篇:利用jni实现android和串口通信

    一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...

  7. linux串口驱动分析【转】

    转自:http://blog.csdn.net/hanmengaidudu/article/details/11946591 硬件资源及描述 s3c2440A 通用异步接收器和发送器(UART)提供了 ...

  8. Android 串口蓝牙通信开发Java版本

    Android串口BLE蓝牙通信Java版 0. 导语 Qt on Android 蓝牙通信开发 我们都知道,在物联网中,BLE蓝牙是通信设备的关键设备.在传统的物联网应用中,无线WIFI.蓝牙和Zi ...

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

    作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...

随机推荐

  1. HDU 2082 母函数法

    #include <cstdio> #include <cstring> using namespace std; ] , dp[][]; int main() { // fr ...

  2. [K/3Cloud]如何解决kdpkg无法部署到业务站点的问题

    自从下载了sp1后,就迫不急待的试用下,看看反馈的几个关键bug是否修复,可惜sp1安装后发现业务站点下的组件一个都没有被更新,这指定是有问题了,这真是让哥百思不得其解,真后悔在研发时没仔细研究下部署 ...

  3. 【Java基础】Java基本数据类型与位运算

    1.赋值运算符 赋值使用操作符“=”.它的意思是“取右边的值(即右值),把它复制给左边(即左值)”.右值可以是任何 常数.变量或者表达式 (只要它能 生成 一个值就行).但左值必须是一个明确的,已命名 ...

  4. Calculate S(n)

    Problem Description Calculate S(n). S(n)=13+23 +33 +......+n3 .   Input Each line will contain one i ...

  5. 一个简单的js队列,逻辑很清晰

    function Queue(type) { //type 是否是一个接着一个执行 function QueueConst() {} QueueConst.execute_ing=[], QueueC ...

  6. 在psql客户端中修改函数

    \ef 创建一个新的函数. \df 显示已经创建的函数. \df+    somefunc 显示这个函数的详细定义 \ef   somefunc 编辑这个函数, 编辑保存退出之后,要执行 \g ,刚才 ...

  7. DIY.NETORM框架——总体分析

    一.故事 近些年一直开发MIS系统,用过PB,VB,C#  .如今学了半年的java,早先听人说,.NET和 java一直就是互相借鉴.一起升级.都是为了让程序开发趋于简单,高校,而这不可避免就肯定用 ...

  8. Linux配置hugepage

    对于内存较大的Oracle数据库server,配置HugePage是非常有必要的,以下是配置Huge的步骤: 我的环境: OS:CentOS release 6.4 (Final) Oracle:11 ...

  9. Java中四大代码块的运行顺序(附code)

    验证证的方法是写code.例如以下: public class test { static class A { public static String name = "hello" ...

  10. 关于EditText的android:maxLength属性的注意事项

    一直以为在xml布局文件中对EditText添加 android:maxLength="30";属性是控制EditText字符数的.想当然的以为一个中文占2个字符,一个英文占1个字 ...