Ubuntu系统(bluez)蓝牙调试

http://blog.csdn.net/zjli321/article/details/52122447

前言

现在调试的Ubuntu、debian系统,蓝牙上层的协议使用bluez,蓝牙的移植与bluedroid略有不同。本文主要介绍Ubuntu(蓝牙移植上debian与Ubuntu是一样的)系统下蓝牙移植的相关知识,并给出移植指导。涉及的知识点有bluez下蓝牙的驱动、hciattach的作用、蓝牙电源的控制、蓝牙移植修改点。

1 Bluez下内核蓝牙框架简介

使用Bluez时,需要内核提供一系列的socket接口来操作蓝牙,内核中蓝牙的框架如图1所示。蓝牙框架分成两部分:蓝牙socket部分及蓝牙驱动部分。蓝牙socket部分负责管理提供给bluez的socket,并包含L2cap层的功能;蓝牙驱动包含hci层协议及蓝牙硬件接口的管理。蓝牙socket部分与蓝牙驱动通过hci_core来连接。从Bluez下移植蓝牙方面看,只关心两个地方,一个是蓝牙驱动的移植,另一个是bluez的工具集中的hciattach工具(使用uart接口的蓝牙才需要这部分), 
这里写图片描述

图1 内核中蓝牙框图 
对比bluedroid与bluez在蓝牙移植方面的差异,最大的不同就是hci和L2cap层所处的位置,在bluedroid中,hci和L2cap层放在bluedroid中,是在内核之上。而bluez中,hci和L2cap层不属于bluez中的代码,而是放到内核里。

2 内核中的蓝牙

在Ubuntu系统下,Bluez的蓝牙驱动负责hci协议的处理、与蓝牙硬件交互数据、注册hci接口供蓝牙socket部分使用。

2.1 注册hci_core接口

不管是uart接口还是usb接口的蓝牙,都是通过hci_register_dev函数向hci_core层注册接口,下面为uart接口及usb接口蓝牙向hci_core层注册例子:

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">kernel<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>drivers<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>bluetooth<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>hci_ldisc<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>c
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>bus <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> HCI_UART;
    hci_set_drvdata(hdev, hu);

    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>open  <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_uart_open;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>close <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_uart_close;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>flush <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_uart_flush;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>send  <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_uart_send_frame;
    SET_HCIDEV_DEV(hdev, hu<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>tty<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>dev);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (test_bit(HCI_UART_RAW_DEVICE, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hu<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>hdev_flags))
        set_bit(HCI_QUIRK_RAW_DEVICE, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>quirks);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>test_bit(HCI_UART_RESET_ON_INIT, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hu<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>hdev_flags))
        set_bit(HCI_QUIRK_RESET_ON_CLOSE, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>quirks);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (test_bit(HCI_UART_CREATE_AMP, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hu<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>hdev_flags))
        hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>dev_type <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> HCI_AMP;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>
        hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>dev_type <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> HCI_BREDR;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (test_bit(HCI_UART_INIT_PENDING, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>hu<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>hdev_flags))
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (hci_register_dev(hdev) <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;"><</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)       <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//uart接口蓝牙注册</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>
<code class="hljs haskell has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-title" style="box-sizing: border-box;">kernel</span>\drivers\bluetooth\rtk_btusb_8723bu.c
    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">HDEV_BUS</span> = <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">HCI_USB</span>;

    <span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span>->hdev = hdev;</span>

    <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">SET_HCIDEV_DEV</span>(hdev, &intf->dev);

    hdev->open     = btusb_open;
    hdev->close    = btusb_close;
    hdev->flush    = btusb_flush;
    hdev->send     = btusb_send_frame;
    hdev->notify   = btusb_notify;

<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0)</span>
    hci_set_drvdata(hdev, <span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span>);</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#else</span>
    hdev->driver_data = <span class="hljs-typedef" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">data</span>;</span>
    hdev->destruct = btusb_destruct;
    hdev->owner = <span class="hljs-type" style="box-sizing: border-box; color: rgb(102, 0, 102);">THIS_MODULE</span>;
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>

……

    err = hci_register_dev(hdev);        // usb接口蓝牙注册</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li></ul>

Hci_core向蓝牙驱动传递数据通过hdev->send接口,而蓝牙驱动接收到数据后直接调用hci_core Export的hci_recv_frame、hci_recv_fragment接口提交数据。 
在使用hci_register_dev注册接口的时候,hci_core会在rfkill下注册一个RFKILL_TYPE_BLUETOOTH类型的设备,名称为hciX。在Ubuntu系统中,只要发现rfkill下有注册RFKILL_TYPE_BLUETOOTH类型设备,就认为存在蓝牙设备,桌面上就会显示蓝牙图标,后面对蓝牙的开关操作就是通过rfkill下的接口。

2.2 蓝牙驱动的移植

现在调试过的蓝牙有uart接口和usb接口的,这两种接口的驱动是完全不同的,下面分别介绍。

2.2.1 USB接口蓝牙

对于usb接口的蓝牙,只要给蓝牙上电,usb枚举到蓝牙设备后,就会调用蓝牙驱动的probe函数,在该函数中就会向hci_core注册接口。

<code class="hljs lasso has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">kernel<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>drivers<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>bluetooth<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">\</span>rtk_btusb_8723bu<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">.</span>c
    static int btusb_probe(struct usb_interface <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>intf, const struct usb_device_id <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">*</span>id)
{

……

    hdev <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_alloc_dev();
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">!</span>hdev) {
        rtk_free(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span>);
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span> <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NULL</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-attribute" style="box-sizing: border-box;">-ENOMEM</span>;
    }

    HDEV_BUS <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> HCI_USB;

    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">data</span><span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>hdev <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hdev;

    SET_HCIDEV_DEV(hdev, <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">&</span>intf<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>dev);

    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>open     <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> btusb_open;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>close    <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> btusb_close;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>flush    <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> btusb_flush;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>send     <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> btusb_send_frame;
    hdev<span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">-></span>notify   <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> btusb_notify;

……

    err <span class="hljs-subst" style="color: rgb(0, 0, 0); box-sizing: border-box;">=</span> hci_register_dev(hdev);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li></ul>

然后在hdev->open 的时候,在btusb_open中进行fw下载和参数配置的工作,这时蓝牙就可以正常工作了。下载的fw和配置文件通过内核的int request_firmware(const struct firmware **fw, const char *name, struct device *device)函数获取,对于需要获取的文件,只需要提供文件名,该函数会自动搜索系统部分路径,其中就包含“/lib/firmware/”,所以只要把fw及配置文件放到“/lib/firmware/”目录下即可。同时usb保证了传输的可靠性,所以也不需要什么h4、h5协议了。 
从上面可以看出,对于usb接口蓝牙的移植,只需要保证两步工作就可以了: 
1、 蓝牙usb功能驱动的移植; 
如rtl8723bu的蓝牙,bluez与bluedroid下使用的驱动是一样的,但有一个定义是区分用于bluez还是bluedroid的。在rtk_btusb_8723bu.h文件如下代码中:

<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifndef CONFIG_PLATFORM_UBUNTU</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define CONFIG_BLUEDROID        1 /* bleuz 0, bluedroid 1 */</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#else</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#define CONFIG_BLUEDROID        0</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>

只要定义了CONFIG_PLATFORM_UBUNTU即可。 
该定义在kernel\arch\arm\configs\下config文件中配置, 
CONFIG_PLATFORM_UBUNTU=y

2、 把fw及配置文件打包到“/lib/firmware/”目录下; 
如gb5_wxga板子的rtl8723bu模组,只需要把rtl8723b_fw、rtl8723bu_config文件放到“\ rootfs\lib\firmware\”目录下即可。

2.2.2 UART接口蓝牙

不像usb接口蓝牙,可以直接向usb驱动注册蓝牙的功能驱动,后面就等着probe被调用就可以了。Uart接口蓝牙,使用那个uart口依赖硬件,同时也没办法像usb一样向串口驱动注册一个功能驱动等待probe,uart是没有枚举的过程的。所以uart接口蓝牙就需要应用层把使用的串口通知hci_core层,同时uart接口蓝牙的fw download及config配置工作也放到了应用层,这些工作都是由hciattach来实现。Hciattach的流程下一节介绍,这里介绍uart接口蓝牙驱动移植需要做的工作。相比图1,图2描述的uart驱动更接近代码结构。

这里写图片描述 
图2 uart接口蓝牙驱动框图 
从图2可以看到,串口的使用有一个切换的过程,在初始化的时候,由hciattach使用串口,初始化完成后,把串口切换给hci使用,hci负责与串口交互蓝牙数据,中间还经过了h4/h5协议层,驱动层跟移植相关只有h4/h5协议,若h4/h5使用的是内核自带的协议,那驱动层就不需要做任何的工作。 
以rtl8723bs为例,需要使用rtk修改过的h5协议,就需要在kernel\drivers\bluetooth\目录下增加hci_rtk_h5.c文件,hci_ldisc.c增加对hci_rtk_h5.c的init及deinit,由于内核中注册hci协议会使用一个id号,相同id的协议不能再注册,内核中已经有的hci_h5.c与 hci_rtk_h5.c使用的是相同的id号,所以内核中需要屏蔽hci_h5.c的注册。

<code class="hljs vala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">    kernel\drivers\bluetooth\hci_ldisc.c
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> __init hci_uart_init(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)

……

<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_H4</span>
    h4_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_BCSP</span>
    bcsp_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_LL</span>
    ll_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_ATH3K</span>
    ath_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_3WIRE</span>
    h5_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Realtek_add_start </span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//add realtek h5 support    </span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_RTKH5</span>
    rtk_h5_init();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Realtek_add_end   </span>


……

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> __exit hci_uart_exit(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)

……

    #ifdef CONFIG_BT_HCIUART_RTKH5
    rtk_h5_deinit();
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
kernel\drivers\bluetooth\ hci_uart.h
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Realtek_add_start</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#ifdef CONFIG_BT_HCIUART_RTKH5</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rtk_h5_init(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rtk_h5_deinit(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>);
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#endif</span>
kernel\drivers\bluetooth\ hci_rtk_h5.c
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> hci_uart_proto h5 = {
    .id     = HCI_UART_3WIRE,  <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 与h5_init注册是相同的id</span>
    .open       = h5_open,
    .close      = h5_close,
    .enqueue    = h5_enqueue,
    .dequeue    = h5_dequeue,
    .recv       = h5_recv,
    .flush      = h5_flush
};

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> rtk_h5_init(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> err = hci_uart_register_proto(&h5);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li></ul>
屏蔽内核中现有的hci_h5.c修改方式为:
kernel\arch\arm\configs\目录下config文件修改下面两行。
# CONFIG_BT_HCIUART_ATH3K is not set   //屏蔽BT_HCIUART_ATH3K

CONFIG_BT_HCIUART_RTKH5=y // 打开BT_HCIUART_RTKH5

Hci_ldisc通过tty_register_ldisc(N_HCI, &hci_uart_ldisc)向串口注册HCI line discipline,当hciattach通过ioctl把串口切换到HCI line discipline时,hci_ldisc就可以与串口通信了。
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">kernel\drivers\bluetooth\ hci_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.c</span>
static int __init hci_uart_init(void)
{
    static struct tty_ldisc_ops hci_uart_ldisc<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    int err<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    BT_INFO(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HCI UART driver ver %s"</span>, VERSION)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* Register the tty discipline */</span>

    memset(&hci_uart_ldisc, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, sizeof (hci_uart_ldisc))<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.magic</span>        = TTY_LDISC_MAGIC<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.name</span>     = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"n_hci"</span><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.open</span>     = hci_uart_tty_open<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.close</span>        = hci_uart_tty_close<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.read</span>     = hci_uart_tty_read<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.write</span>        = hci_uart_tty_write<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.ioctl</span>        = hci_uart_tty_ioctl<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.poll</span>     = hci_uart_tty_poll<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.receive</span>_buf  = hci_uart_tty_receive<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.write</span>_wakeup = hci_uart_tty_wakeup<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    hci_uart_ldisc<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.owner</span>        = THIS_MODULE<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>

    if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
        BT_ERR(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"HCI line discipline registration failed. (%d)"</span>, err)<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
        return err<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">;</span>
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li></ul>

3 Hciattach的处理流程

只有uart接口的蓝牙才需要hciattach工具,hciattach的作用为配置串口,下载fw及config文件,把串口切换给hci_ldisc使用。 
Bluez带有hciattach的源码,框架也比较清晰,对很多厂家都有支持,但实际调试realtek及boardcom的模组时,Bluez自带的hciattach都是不能使用的,realtek及boardcom对hciattach有特殊的修改,主要是针对fw和config的下载部分。但hciattach的作用及流程与Bluez自带的hciattach是一样的。Hciattach的流程如图3所示。

这里写图片描述 
图3 hciattach初始化流程 
Hciattach的流程比较简单,从现在Ubuntu及debian系统的设计看,hciattach都是开机时就运行,一直到关机时才结束。 
Hciattach的移植涉及下面几个地方: 
1、 把hciattach可执行文件放到bin目录下; 
以lemaker板子为例: 
把hciattach_rtk放到\rootfs\usr\sbin\目录下; 
2、 把fw及config文件打包进系统,放置的路径由hciattach open fw确定 
以使用rtl8723bs模组: 
把rtl8723b_fw、rtk8723_bt_config放到 
\rootfs\lib\firmware\rtl8723bs\目录下; 
3、 加入hciattach的启动与退出控制: 
把 bluetooth.conf文件放到\rootfs\etc\init\目录下。

<code class="hljs bash has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">bluetooth.conf文件内容
description     <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"bluetooth daemon"</span>

start on started dbus
stop on stopping dbus

env UART_CONF=/etc/bluetooth/uart
env RFCOMM_CONF=/etc/bluetooth/rfcomm.conf

expect fork
respawn

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">exec</span> /usr/sbin/bluetoothd

post-start script
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#[ "$VERBOSE" = no ] && redirect='>/dev/null 2>&1' || redirect=</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># start_uarts()</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#if [ -x /usr/sbin/hciattach ] && [ -f $UART_CONF ];</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#then</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#   grep -v '^#' $UART_CONF | while read i; do</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#     eval "/usr/sbin/hciattach $i $redirect" || :</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#   done</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">#fi</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">exec</span> hciattach_rtk -n <span class="hljs-operator" style="box-sizing: border-box;">-s</span> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">115200</span> /dev/ttyS2 rtk_h5 &

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># start_rfcomm()</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> [ -x /usr/bin/rfcomm ] && [ <span class="hljs-operator" style="box-sizing: border-box;">-f</span> <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$RFCOMM_CONF</span> ] ;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">then</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># rfcomm must always succeed for now: users</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># may not yet have an rfcomm-enabled kernel</span>
        <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">eval</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/usr/bin/rfcomm -f <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$RFCOMM_CONF</span> bind all <span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">$redirect</span>"</span> || :
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">fi</span>
end script

post-stop script
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># stop_uarts()</span>
    logger -t bluez <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Stopping uarts"</span>
    kill</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li></ul>

bluetooth.conf中有脚本,在开机、关机时运行,这里: 
开机运行:exec hciattach_rtk -n -s 115200 /dev/ttyS2 rtk_h5 & 
关机运行:killall hciattach_rtk >/dev/null 2>&1 || :

4 蓝牙电源的管理

前面的文档中一直没有提到蓝牙的电源是怎么控制的。在蓝牙的电源控制方面,Ubuntu及debian系统都没有做很好的处理,从现在的蓝牙图形界面应用看,这两个系统中,默认蓝牙是一直有电的并且开机时就打开,并没有考虑关闭蓝牙的时候把蓝牙断电。 
现在我们使用usb接口蓝牙,对于插拨的usb蓝牙,不需要考虑电源,只要插上就有电了,对于焊在板子上的蓝牙,由于没有增加对蓝牙上电的操作,所以要在wifi打开的情况下(wifi上电了,蓝牙也就上电了)才能使用蓝牙。 
对于sdio接口的蓝牙,以rtl8723bs为例,修改了kernel\net\rfkill\目录下的rfkill-actions_8723bs.c文件,在这个文件里不再注册rfkill接口,而是修改为在加载驱动是给蓝牙上电,卸载驱动时断开蓝牙电源。 
至于为什么不保留rfkill-actions_8723bs.c在rfkill中的接口,通过rfkill来控制电源,是由于rfkill-actions_8723bs.c注册进rfkill的类型也是RFKILL_TYPE_BLUETOOTH,与hci注册的类型是一样的,这并没有冲突,但由于Ubuntu的蓝牙图形界面操作蓝牙打开、关闭时,同时都会把RFKILL_TYPE_BLUETOOTH类型的节点打开、关闭,这里上电的延时就没法保证,而且并没有调用hciattach进行蓝牙的初始化,对于串口蓝牙就没法使用了。

若重写蓝牙图形操作界面时,可以采用下面的方案进行电源的管理。 
1、 usb接口蓝牙: 
在rfkill中增加一个节点用于控制蓝牙上、掉电,类型为 
RFKILL_TYPE_BLUETOOTH,但名称修改为bt_power; 
蓝牙打开的操作: 
A) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为bt_power的节点,给蓝牙上电; 
B) 延时(根据实际调整); 
C) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为hciX的节点,打开蓝牙; 
蓝牙关闭的操作: 
A) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为hciX的节点,关闭蓝牙; 
B) 延时(根据实际调整); 
C) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为bt_power的节点,给蓝牙断电;

2、 Uart接口蓝牙 
在rfkill中增加一个节点用于控制蓝牙上、掉电,类型为 
RFKILL_TYPE_BLUETOOTH,但名称修改为bt_power; 
蓝牙打开的操作: 
A) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为bt_power的节点,给蓝牙上电; 
B) 延时(根据实际调整); 
C) 启动hciattach完成蓝牙的初始化并切换串口给hci使用; 
D) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为hciX的节点,打开蓝牙; 
蓝牙关闭的操作: 
A) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为hciX的节点,关闭蓝牙; 
B) 关闭hciattach; 
C) 延时(根据实际调整); 
D) 找到rfkill下类型为RFKILL_TYPE_BLUETOOTH名称为bt_power的节点,给蓝牙断电;

上面方案要求图形界面对不同接口蓝牙进行不同的操作,统一性不是很好,可以把操作部分放到脚本中实现,脚本根据实际硬件修改,而图形界面只需要调用脚本,不需要关心脚本的操作内容,这样实现会更好一些。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值