在前面几篇文章中,我们把kernel中bluetooth stack相关的初始化分析完成,今天晓东带大家来一起分析uart接口的bluetooth
driver的初始化。首先,我们来到kernel/drivers/bluetooth目录,看hci_ldisc.c文件。又见到我们熟悉的module_init:
module_init(hci_uart_init);好吧,动手来看吧:
static int __init hci_uart_init(void) { static struct tty_ldisc_ops hci_uart_ldisc; int err; BT_INFO("HCI UART driver ver %s", VERSION); /* Register the tty discipline */ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc)); hci_uart_ldisc.magic = TTY_LDISC_MAGIC; hci_uart_ldisc.name = "n_hci"; 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; hci_uart_ldisc.write_wakeup = hci_uart_tty_wakeup; hci_uart_ldisc.owner = THIS_MODULE; //注册了一个tty的新的线路规程,为N_HCI,并定义了他的一系列的操作 /*线路规程有什么作用呢,我们可以这样理解,tty向应用层注册了一系列的通用接口,这些接口(比如写数据)被调用后会根据对应的线路规程去找对应的driver,然后driver会对数据做一些处理发送到硬件中去。 这个通路反过来也是成立。 大概的模型如下: -----tty层---------- -----线路规程----- -----driver层------- -----硬件层--------- */ if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) { BT_ERR("HCI line discipline registration failed. (%d)", err); return err; } //以h4为例来进行讲解 h4_init(); …… return 0; } int __init h4_init(void) { //就是向uart protol中注册对应的driver,详细分析见下面。 int err = hci_uart_register_proto(&h4p); if (!err) BT_INFO("HCI H4 protocol initialized"); else BT_ERR("HCI H4 protocol registration failed"); return err; } static struct hci_uart_proto h4p = { .id = HCI_UART_H4, .open = h4_open, .close = h4_close, .recv = h4_recv, .enqueue = h4_enqueue, .dequeue = h4_dequeue, .flush = h4_flush, }; int hci_uart_register_proto(struct hci_uart_proto *p) { if (p->id >= HCI_UART_MAX_PROTO) return -EINVAL; if (hup[p->id]) return -EEXIST; //其实说白了就是初始化hup数组(hci uart proto) //在这之后的open,write,read什么的就可以通过这个数组找到对应proto的相应的调用接口中去 hup[p->id] = p; return 0; }
所以,总的来说,uart这边的脉络还是很清楚的,就是首先注册线路规程,所有和蓝牙相关的数据将会选择HCI这个线路规程,然后根据各家的方案设计不同,注册对应的proto,数据最终会根据proto选择对应的driver去做处理后发送到对应的硬件(蓝牙controller中)。