Tech, 2010-1-11
Page 10 of 46
Hci_uart层做的事情其实很简单。
3.3.1.1 ldisc注册
注册了一个ldisc,这是通过把新的ldisc放在一个ldisc的数组里面实现的,tty_ldiscs是一个全局的
ldisc数组里面会根据序号对应一个ldisc,这个序号就是上层通过ioctl来指定的,比如我们在前面已
经看到的:
i = N_HCI;
ioctl(fd, TIOCSETD, &i) < 0
可以看到这里指定的N_HCI刚好就是这里注册的这个号码15;
这里需要看看其对应的处理函数,关键的几个列出如下:
hci_uart_ldisc.open = hci_uart_tty_open;
hci_uart_ldisc.close = hci_uart_tty_close;
hci_uart_ldisc.read = hci_uart_tty_read;
hci_uart_ldisc.write = hci_uart_tty_write;
hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
hci_uart_ldisc.poll = hci_uart_tty_poll;
hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
3.3.1.2 bcsp协议的注册
这是通过hci_uart_register_proto(&bcsp)来完成的,
这个函数非常简单,本质如下:
hup[p->id] = p;
其中static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
也就是说把对应于协议p的id和协议p连接起来,这样设计的好处是hci uart层本身可以支持不同的协
议,包括bcsp,h4等,通过这个数组连接这些协议,等以后有数据的时候调用对应的协议来处理,
这里比较关键的是bcsp里面的这些函数,关键列举如下:
static struct hci_uart_proto bcsp = {
.id = HCI_UART_BCSP,
.open = bcsp_open,
.close = bcsp_close,
.enqueue = bcsp_enqueue,
.dequeue = bcsp_dequeue,
.recv = bcsp_recv,
.flush = bcsp_flush
};
3.3.2 hci
层的加入
hci的加入是通过hci_register_dev函数来做的,这时候用户通过hciconfig就可以看到有一个接
口了,通过这个接口用户可以访问底层的信息了;至于它在何时被加入的,我们再看看hciattach在内核里面
的处理过程;