现在的位置: 首页 > 综合 > 正文

Kernel中uart接口的bluetooth driver初始化分析

2013年12月06日 ⁄ 综合 ⁄ 共 1906字 ⁄ 字号 评论关闭

在前面几篇文章中,我们把kernelbluetooth 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中)。

 

抱歉!评论已关闭.