/* Initialize UART driver */
int init_uart(char *dev, struct uart_t *u, int send_break)
{
struct termios ti;
int fd, i;
fd = open(dev, O_RDWR | O_NOCTTY);//打开串口设备,其中标志
//O_RDWR,可以对此设备进行读写操作;
//O_NOCTTY,我不是很理解?
//但是不要以控制 tty 的模式,因为我们并不希望在发送 Ctrl-C
后结束此进程
if (fd < 0) {
perror(“Can’t open serial port”);
return -1;
}
//drop fd’s data;
tcflush(fd, TCIOFLUSH);//清空数据线
if (tcgetattr(fd, &ti) < 0) {
perror(“Can’t get port settings”);
return -1;
}
cfmakeraw(&ti);
cfmakeraw sets the terminal attributes as follows://此函数设置串口终端的以下这些属性,
termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
termios_p->c_oflag &= ~OPOST;
termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
termios_p->c_cflag &= ~(CSIZE|PARENB) ;
termios_p->c_cflag |=CS8;
ti.c_cflag |= CLOCAL;//本地连接,无调制解调器控制
if (u->flags & FLOW_CTL)
ti.c_cflag |= CRTSCTS;//输出硬件流控(只能在具完整线路的缆线下工作,参
//考 Serial-HOWTO 第七节)
else
ti.c_cflag &= ~CRTSCTS;
if (tcsetattr(fd, TCSANOW, &ti) < 0) {//启动新的串口设置
perror(“Can’t set port settings”);
return -1;
}
/* Set initial baudrate */
if (set_speed(fd, &ti, u->init_speed) < 0) {//设置串口的传输速率bps, 也可以使
//用 cfsetispeed 和 cfsetospeed 来设置
perror(“Can’t set initial baud rate”);
return -1;
}
tcflush(fd, TCIOFLUSH);//清空数据线
if (send_break)
tcsendbreak(fd, 0);
//int tcsendbreak ( int fd, int duration );Sends a break for
//the given time.在串口线上发送0值,至少维持0.25秒。
//If duration is 0, it transmits zero-valued bits for at least 0.25 seconds, and
//not more than 0.5seconds.
//where place register u’s init function;
if (u->init && u->init(fd, u, &ti) < 0)
//所有bluez支持的蓝牙串口设备类型构成了一个uart结构数组,通过
//查找对应的uart类型,这个uart的init成员显示了它的init调用方法;
struct uart_t uart[] = {
{ “any”, 0×0000, 0×0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, NULL },
{ “ericsson”, 0×0000, 0×0000, HCI_UART_H4, 57600, 115200, FLOW_CTL, ericsson },
{ “digi”, 0×0000, 0×0000, HCI_UART_H4, 9600, 115200, FLOW_CTL, digi },
{ “texas”, 0×0000, 0×0000, HCI_UART_H4, 115200, 115200, FLOW_CTL, texas},
{ “bcsp”, 0×0000, 0×0000, HCI_UART_BCSP, 115200, 115200, 0, bcsp },//bcsp的init函数名为bcsp,定义在本文件中**;
return -1;
tcflush(fd, TCIOFLUSH);//清空数据线
/* Set actual baudrate */
if (set_speed(fd, &ti, u->speed) < 0) {
perror(“Can’t set baud rate”);
return -1;
}
/* Set TTY to N_HCI line discipline */
i = N_HCI;
if (ioctl(fd, TIOCSETD, &i) < 0) {//
TIOCSETD int *ldisc//改变到 i 行规,即hci行规
Change to the new line discipline pointed to by ldisc. The available line disciplines are listed in
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
/* line disciplines */
#define N_TTY 0
……
#define N_HCI 15 /* Bluetooth HCI UART */
perror(“Can’t set line discipline”);
return -1;
}
if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {
//设置hci设备的proto操作函数集为hci_uart操作集;
perror(“Can’t set device”);
return -1;
}
return fd;
}
来源:http://blog.donews.com/zhuyong/archive/2004/10/20/141127.aspx