RK3588 USB蓝牙调试

一.蓝牙基本概念

蓝牙技术是一种无线通信的方式,利用特定频率的波段(2.4GHz-2.485GHz左右),进行电磁波传输。蓝牙传输原理是主从关系,一个主设备可以与7个蓝牙从设备配对。

RK3588 USB蓝牙调试_第1张图片

二.蓝牙标准

蓝牙标准版本发展如下:

RK3588 USB蓝牙调试_第2张图片

三.安卓蓝牙框架

RK3588 USB蓝牙调试_第3张图片

libbt-vendor.so 完成对蓝牙模块硬件初始化与控制(物理通讯接口初始化,固件下载,供电控制)RK平台通过判断wifi+Bt模块的type,在libbuetooth_jni层选择加载不同适配厂商协议栈;并在libbt-hci中根据模块类型加载不同厂家模块的libbt-vendor.so,完成动态适配模块。

libbluetooth主要是bluedroid的蓝牙协议栈的具体实现,向下调用libbt-hci的接口加载**libbt-vendor;**向上供libblueooth_jni的回调;

bluetooth.apk 作 为 蓝 牙 服 务 进 程 , 通 过 libblueooth_jni 层 获 取bluetooth*.default.so 提 供 的bt_interface_t 控 制 接 口 并 状 态 与 数 据 回 调 注 册 到bluetooth*.default.so;完成对蓝牙模块的控制与数据接收;

四.USB 蓝牙模块的调试

kernel部分

首先,将Realtek提供的蓝牙驱动文件rtk_btusb.h和rtk_btusb.c拷贝到kernel的drivers/bluetooth/目录下:

kernel-5.10/drivers/bluetooth/rtk_btusb.c
kernel-5.10/drivers/bluetooth/rtk_btusb.h

修改kernel的drivers/bluetooth/目录下的文件“Kconfig” 和“Makefile”

config BT_RTKBTUSB
    tristate "RTK HCI USB driver"
    depends on USB
    help
       RTK Bluetooth HCI USB driver
obj-$(CONFIG_BT_RTKBTUSB)	+= rtk_btusb.o

平台对应的defconfig文件添加Realtek BT Chip支持的宏定义,或者在 kernel 中make menuconfig选中rtk_btusb driver相关的宏。

CONFIG_BT_RTKBTUSB=y
libbt-vendor.so的配置

在hardware/realtek目录:HAL层添加蓝牙协议栈的代码和对应的libbt-vendor.so的源代码,libbt-vendor完成对蓝牙模块硬件初始化与控制(物理通讯接口初始化,固件下载,供电控制)

@sw-eng:RK3588S$ cd hardware/realtek/rtkbt/vendor/firmware
@sw-eng:firmware$ 
@sw-eng:firmware$ ls
BT_Firmware.mk        rtl8723a_fw              rtl8723c_fw          rtl8723f_config     rtl8761at_config        rtl8761cs_fw      rtl8822bs_config
fw_info.txt           rtl8723as_config         rtl8723cs_cg_config  rtl8723f_fw         rtl8761at_fw            rtl8821a_config   rtl8822bs_fw
readme.txt            rtl8723as_fw             rtl8723cs_cg_fw      rtl8723fs_config    rtl8761au8192ee_fw      rtl8821a_fw       rtl8822c_config
rtl8703as_config      rtl8723b_config          rtl8723cs_vf_config  rtl8723fs_fw        rtl8761au8812ae_fw      rtl8821as_config  rtl8822c_fw
rtl8703as_fw          rtl8723b_config_2Ant_S0  rtl8723cs_vf_fw      rtl8725a_config     rtl8761au_fw            rtl8821as_fw      rtl8822cs_config
rtl8703bs_config      rtl8723b_fw              rtl8723cs_xx_config  rtl8725a_fw         rtl8761aw8192eu_config  rtl8821c_config   rtl8822cs_fw
rtl8703bs_fw          rtl8723bs_config         rtl8723cs_xx_fw      rtl8725as_config    rtl8761aw8192eu_fw      rtl8821c_fw       rtl8852as_config
rtl8703cs_config      rtl8723bs_fw             rtl8723d_config      rtl8725as_fw        rtl8761b_config         rtl8821cs_config  rtl8852as_fw
rtl8703cs_fw          rtl8723bs_VQ0_config     rtl8723d_fw          rtl8761a_config     rtl8761b_fw             rtl8821cs_fw      rtl8852au_config
rtl8723a_config       rtl8723bs_VQ0_fw         rtl8723ds_config     rtl8761at8192ee_fw  rtl8761bt_config        rtl8822b_config   rtl8852au_fw
rtl8723a_config_addr  rtl8723bu_config         rtl8723ds_fw         rtl8761at8812ae_fw  rtl8761bt_fw            rtl8822b_fw
cfliu@sw-eng:firmware$ 

最终会通过mk文件hardware/realtek/rtkbt/rtkbt.mk拷贝到机器的以下目录,打开蓝牙的时候会去加载fw:

ifeq ($(strip $(TARGET_BOARD_PLATFORM_PRODUCT)), tablet)
BT_FIRMWARE_FILES := $(shell ls $(CUR_PATH)/vendor/firmware)
PRODUCT_COPY_FILES += \
	$(foreach file, $(BT_FIRMWARE_FILES), $(CUR_PATH)/vendor/firmware/$(file):$(TARGET_COPY_OUT_VENDOR)/etc/firmware/$(file))

最终拷贝到设备上为:/vendor/etc/firmware

pro:/vendor/etc/firmware # ls
4343A0.hcd                       bcm4329.hcd                  fw_awnb108_ap.bin           fw_bcm43438a0.bin                fw_cyw43438.bin       nvram_ap6212a.txt    rtl8703bs_config         rtl8723ds_config        rtl8821a_fw
AP6275P_NVRAM_V1.1_20200702.txt  bcm43341b0.hcd               fw_bcm40181a2.bin           fw_bcm43438a0_apsta.bin          fw_cyw43455.bin       nvram_ap6214.txt     rtl8703bs_fw             rtl8723ds_fw            rtl8821as_config
BCM20710A1.hcd                   bcm4339a0.hcd                fw_bcm40181a2_apsta.bin     fw_bcm43438a0_p2p.bin            fw_info.txt           nvram_ap6214a.txt    rtl8703cs_config         rtl8723f_config         rtl8821as_fw
BCM4330B1.hcd                    bcm43438a0.hcd               fw_bcm40183b2.bin           fw_bcm43438a1.bin                mali_csffw.bin        nvram_ap6216.txt     rtl8703cs_fw             rtl8723f_fw             rtl8821c_config
BCM4343A0.hcd                    bcm43438a1.hcd               fw_bcm40183b2_ag.bin        fw_bcm43438a1_apsta.bin          nh660.hcd             nvram_ap6233f.txt    rtl8723a_config          rtl8723fs_config        rtl8821c_fw
BCM4343A1.hcd                    bcm4354a1.hcd                fw_bcm40183b2_ag_apsta.bin  fw_bcm43438a1_p2p.bin            nvram.txt             nvram_ap6236.txt     rtl8723a_config_addr     rtl8723fs_fw            rtl8821cs_config
BCM4343B0.hcd                    clm_bcm43752a2_ag.blob       fw_bcm40183b2_ag_p2p.bin    fw_bcm43455c0_ag.bin             nvram_4330.txt        nvram_ap6255.txt     rtl8723a_fw              rtl8725a_config         rtl8821cs_fw
BCM4345C0.hcd                    clm_bcm43752a2_pcie_ag.blob  fw_bcm40183b2_apsta.bin     fw_bcm43455c0_ag_apsta.bin       nvram_4330_oob.txt    nvram_ap6256.txt     rtl8723as_config         rtl8725a_fw             rtl8822b_config
BCM4345C5.hcd                    clm_bcm4375b4_pcie_ag.blob   fw_bcm40183b2_p2p.bin       fw_bcm43455c0_ag_p2p.bin         nvram_AP6181.txt      nvram_ap6275hh3.txt  rtl8723as_fw             rtl8725as_config        rtl8822b_fw
BCM4354A2.hcd                    config.txt                   fw_bcm43241b4_ag.bin        fw_bcm43456c5_ag.bin             nvram_AP6210.txt      nvram_ap6275s.txt    rtl8723b_config          rtl8725as_fw            rtl8822bs_config
BCM4356A2.hcd                    esp32                        fw_bcm43241b4_ag_apsta.bin  fw_bcm43456c5_ag_apsta.bin       nvram_AP6210_24M.txt  nvram_ap62x2.txt     rtl8723b_config_2Ant_S0  rtl8761a_config         rtl8822bs_fw
BCM4359C0.hcd                    fw_RK901.bin                 fw_bcm43241b4_ag_p2p.bin    fw_bcm4354a1_ag.bin              nvram_AP6234.txt      nvram_ap6354.txt     rtl8723b_fw              rtl8761at8192ee_fw      rtl8822c_config
BCM4362A2.hcd                    fw_RK901a0.bin               fw_bcm4330.bin              fw_bcm4354a1_ag_apsta.bin        nvram_AP6275P.txt     nvram_ap6356.txt     rtl8723bs_VQ0_config     rtl8761at8812ae_fw      rtl8822c_fw
BCM4375B1.hcd                    fw_RK901a0_apsta.bin         fw_bcm4330_apsta.bin        fw_bcm4354a1_ag_p2p.bin          nvram_AP6330.txt      nvram_ap6356s.txt    rtl8723bs_VQ0_fw         rtl8761at_config        rtl8822cs_config
BT_Firmware.mk                   fw_RK901a2.bin               fw_bcm43341b0_ag.bin        fw_bcm4356a2_ag.bin              nvram_AP6335.txt      nvram_ap6398s.txt    rtl8723bs_config         rtl8761at_fw            rtl8822cs_fw
RT2870AP.dat                     fw_RK901a2_apsta.bin         fw_bcm43341b0_ag_apsta.bin  fw_bcm4356a2_ag_apsta.bin        nvram_AP6441.txt      nvram_ap6398sa.txt   rtl8723bs_fw             rtl8761au8192ee_fw      rtl8852as_config
RT2870APCard.dat                 fw_RK901a2_p2p.bin           fw_bcm43341b0_ag_p2p.bin    fw_bcm4356a2_ag_p2p.bin          nvram_AP6476.txt      nvram_ap6452.txt     rtl8723bu_config         rtl8761au8812ae_fw      rtl8852as_fw
RT2870STA.dat                    fw_RK903.bin                 fw_bcm4334b1_ag.bin         fw_bcm4359c0_ag.bin              nvram_AP6493.txt      nvram_awnb108.txt    rtl8723c_fw              rtl8761au_fw            rtl8852au_config
RT2870STACard.dat                fw_RK903_ag.bin              fw_bcm4334b1_ag_apsta.bin   fw_bcm4359c0_ag_apsta.bin        nvram_B23.txt         nvram_azw256.txt     rtl8723cs_cg_config      rtl8761aw8192eu_config  rtl8852au_fw
awnb108.hcd                      fw_RK903_ag_apsta.bin        fw_bcm4334b1_ag_p2p.bin     fw_bcm4359c0_ag_p2p.bin          nvram_GB86302I.txt    nvram_azw372.txt     rtl8723cs_cg_fw          rtl8761aw8192eu_fw      ssv6051-sw.bin
bcm20710a1.hcd                   fw_RK903_ag_p2p.bin          fw_bcm4339a0_ag.bin         fw_bcm43752a2_ag.bin             nvram_RK901.txt       otp.bin.z77          rtl8723cs_vf_config      rtl8761b_config         ssv6051-wifi.cfg
bcm20710a1_24M.hcd               fw_RK903_p2p.bin             fw_bcm4339a0_ag_apsta.bin   fw_bcm43752a2_ag_apsta.bin       nvram_RK903.cal       readme.txt           rtl8723cs_vf_fw          rtl8761b_fw             wifi_efuse_8189e.map
bcm20710a1_26M.hcd               fw_RK903b2.bin               fw_bcm4339a0_ag_p2p.bin     fw_bcm43752a2_pcie_ag.bin        nvram_RK903.txt       rk903.hcd            rtl8723cs_xx_config      rtl8761bt_config        wifi_efuse_8723bs-vq0.map
bcm2076b1.hcd                    fw_RK903b2_apsta.bin         fw_bcm43436b0.bin           fw_bcm43752a2_pcie_ag_apsta.bin  nvram_RK903_26M.cal   rk903_26M.hcd        rtl8723cs_xx_fw          rtl8761bt_fw            wifi_efuse_8723cs.map
bcm40183b2.hcd                   fw_RK903b2_p2p.bin           fw_bcm43436b0_apsta.bin     fw_bcm4375b4_pcie_ag.bin         nvram_WL211.txt       rtl8703as_config     rtl8723d_config          rtl8761cs_fw            wifi_efuse_8723ds.map
bcm43241b4.hcd                   fw_awnb108.bin               fw_bcm43436b0_p2p.bin       fw_bcm4375b4_pcie_ag_apsta.bin   nvram_ap6212.txt      rtl8703as_fw         rtl8723d_fw              rtl8821a_config         wifi_efuse_8821cs.map

根据type选择具体的vendor库

部分HAL层对应的libbt-vendor.so的源代码浅析:
首先是bluedroid 蓝牙协议栈libbt-hci【原生蓝牙协议栈】通过system/bt/hci/src/hci_layer_android.cc的hci_initialize函数,调用interfaces/bluetooth/1.0/default/vendor_interface.cc中的initialize函数,进而调用open函数打开对应so库。
 

//interfaces/bluetooth/1.0/default/vendor_interface.cc
static const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
static const char* VENDOR_REALTEK_LIBRARY_NAME = "libbt-vendor-realtek.so";

static char wifi_type[64] = {0};
extern "C" int check_wifi_chip_type_string(char *type);
bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
                           PacketReadCallback event_cb,
                           PacketReadCallback acl_cb,
                           PacketReadCallback sco_cb,
                           PacketReadCallback iso_cb) {
  initialize_complete_cb_ = initialize_complete_cb;
  char vendor_lib_name[32];

  // Initialize vendor interface
  if (wifi_type[0] == 0)
      //获取当前wifi芯片的type加载不同的so库,目前这个接口有权限问题,待进一步分析
	  check_wifi_chip_type_string(wifi_type);
  if ((0 == strncmp(wifi_type, "RTL", 3)) ||
      (0 == strncmp(wifi_type, "SSV", 3))) { // for ssv6051 wifi + rtl8761 bt
      //此时加载的是libbt-vendor-realtek.so
    strcpy(vendor_lib_name, VENDOR_REALTEK_LIBRARY_NAME);
  } else {
      //此时加载的是libbt-vendor.so
    strcpy(vendor_lib_name, VENDOR_LIBRARY_NAME);
  }

  ALOGD("%s: %s", __func__, vendor_lib_name);
  lib_handle_ = dlopen(vendor_lib_name, RTLD_NOW);
  if (!lib_handle_) {
    ALOGE("%s unable to open %s (%s)", __func__, vendor_lib_name,
          dlerror());
    return false;
  }

  lib_interface_ = reinterpret_cast(
      dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
  if (!lib_interface_) {
    ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
          VENDOR_LIBRARY_SYMBOL_NAME, vendor_lib_name, dlerror());
    return false;
  }

  // Get the local BD address
  uint8_t local_bda[BluetoothAddress::kBytes];
  //获取本地的蓝牙地址
  if (!BluetoothAddress::get_local_address(local_bda)) {
    LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
  }
  //接口的初始化
  int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
  if (status) {
    ALOGE("%s unable to initialize vendor library: %d", __func__, status);
    return false;
  }

  ALOGD("%s vendor library loaded", __func__);

  // Power on the controller
  int power_state = BT_VND_PWR_ON;
  lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);

  // Get the UART socket(s)
  int fd_list[CH_MAX] = {0};
  int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);

  if (fd_count < 1 || fd_count > CH_MAX - 1) {
    ALOGE("%s: fd_count %d is invalid!", __func__, fd_count);
    return false;
  }

  for (int i = 0; i < fd_count; i++) {
    if (fd_list[i] == INVALID_FD) {
      ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
      return false;
    }
  }

  event_cb_ = event_cb;
  PacketReadCallback intercept_events = [this](const hidl_vec& event) {
    HandleIncomingEvent(event);
  };

  if (fd_count == 1) {
    hci::H4Protocol* h4_hci =
        new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb, iso_cb);
    fd_watcher_.WatchFdForNonBlockingReads(
        fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
    hci_ = h4_hci;
  } else {
    hci::MctProtocol* mct_hci =
        new hci::MctProtocol(fd_list, intercept_events, acl_cb);
    fd_watcher_.WatchFdForNonBlockingReads(
        fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
    fd_watcher_.WatchFdForNonBlockingReads(
        fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
    hci_ = mct_hci;
  }

  // Initially, the power management is off.
  lpm_wake_deasserted = true;

  // Start configuring the firmware
  //配置和加载Firmware
  firmware_startup_timer_ = new FirmwareStartupTimer();
  lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);

  return true;
}
协议栈的选择
//packages/apps/Bluetooth/jni/com_android_bluetooth_btservice_AdapterService.cpp
static void classInitNative(JNIEnv* env, jclass clazz) {
    ......
    char type[64];
    check_wifi_chip_type_string(type);
    if (!strncmp(type, "RTL", 3)) { //加载rtl厂商对应的蓝牙协议栈的库:bluetooth_rtk.default.so
        ALOGD("%s, load %s.default.so", __func__, BT_STACK_RTK_MODULE_ID); 
        err = hw_get_module(BT_STACK_RTK_MODULE_ID, (hw_module_t const**)&module);
    } else { //加载原生的蓝牙协议栈的库:bluetooth.default.so
        ALOGD("%s, load %s.default.so", __func__, id);
        err = hw_get_module(id, (hw_module_t const**)&module);
    }
}

//处理一些回调
const bt_vendor_callbacks_t lib_callbacks = {
    sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
    low_power_mode_cb,     sco_audiostate_cb,  buffer_alloc_cb,
    buffer_free_cb,        transmit_cb,        epilog_cb,
    a2dp_offload_cb};

}  // namespace
//BT_STACK_RTK_MODULE_ID在./hardware/libhardware/include/hardware/bluetooth.h定义

五.在RK安装蓝牙调试工具验证

直接在浏览器搜索下载即可:

到BUMBLE这个设备,点击连接;

连上之后,就会看到4个蓝牙服务,实时日志里也会看到连接状态的提示;

RK3588 USB蓝牙调试_第4张图片

你可能感兴趣的:(瑞芯微,驱动开发,算法)