关键词:bluedroid  initNative enableNative BTIF_TASK  BTU_TASKbt_hc_work_thread set_power  preload  GKI
作者:xubin341719(欢迎转载。请注明作者,请尊重版权。谢谢。)
欢迎指正错误,共同学习、共同进步!!

一、   蓝牙开启流程概述,例如以下图所看到的:init、enable

和一般的函数调用同样。android上层通过APP-->Native-->JNI-->bluetoothinterface-->bluetooth HCIinterface。

HCI interface中实现了init、set_power、preload对应函数
init、enable函数主要实现的功能:
(1)、创建:btif_task/BTIF_TASK
(2)、初始化BTE
(3)、创建:btu_task/BTU_TASK
(4)、初始化HCI、串口相关,启动HCI工作主线程:bt_hc_callback。芯片上电、RF參数初始化、蓝牙地址名称相关设定;
(5)、创建:bt_hc_worker_thread蓝牙工作主线程,发送接收命令;
(6)、初始化蓝牙协议栈;
二、initNative函数的的实现
        这部分主要启动对应sock、协议栈初始化、启动btif_task,监听处理蓝牙接口相关的状态消息。实现流程例如以下所看到的。

 1、应用部分函数调用(从adatper開始)
packages\apps\Bluetooth\src\com\android\bluetooth\btservice\ AdapterService.java

    public void onCreate() {
super.onCreate();
if (DBG) debugLog("onCreate");
mBinder = new AdapterServiceBinder(this);
mAdapterProperties = new AdapterProperties(this);
mAdapterStateMachine = AdapterState.make(this, mAdapterProperties);
mJniCallbacks = new JniCallbacks(mAdapterStateMachine, mAdapterProperties);
initNative();//调用initNative函数;
mNativeAvailable=true;
mCallbacks = new RemoteCallbackList<IBluetoothCallback>();
//Load the name and address
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDADDR);
getAdapterPropertyNative(AbstractionLayer.BT_PROPERTY_BDNAME);
}
private native boolean initNative();

2、JNI函数的实现,这部分跟其它JNI实现同样。
packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp

static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void *) classInitNative},
{"initNative", "()Z", (void *) initNative},//Native函数实现
…………
}

packages\apps\Bluetooth\jni\com_android_bluetooth_btservice_AdapterService.cpp
initNative函数的详细实现。通过bt_interface_t结构体,调用到C中的init函数实现。同一时候传入sBluetoothCallbacks回调函数结构体。这个函数结构体比較重要,底层的状态变化都是通过这个回调函数结构体中的函数实现。

static const bt_interface_t *sBluetoothInterface = NULL;
static bool initNative(JNIEnv* env, jobject obj) {
sJniCallbacksObj = env->NewGlobalRef(env->GetObjectField(obj, sJniCallbacksField));
if (sBluetoothInterface) {
int ret = sBluetoothInterface->init(&sBluetoothCallbacks);//调用到C的对应接口函数
if (ret != BT_STATUS_SUCCESS) {//假设出错,错误处理;
ALOGE("Error while setting the callbacks \n");
sBluetoothInterface = NULL;
return JNI_FALSE;
}
if ( (sBluetoothSocketInterface = (btsock_interface_t *)
sBluetoothInterface->get_profile_interface(BT_PROFILE_SOCKETS_ID)) == NULL) {
ALOGE("Error getting socket interface");
}
return JNI_TRUE;
}
return JNI_FALSE;
}

3、JNI调用C中函数实现
C语言实现了上层调用的函数。终于实现了JAVA调用C函数的动作。

这是android系统对kernel操作的详细步骤。

假设是刚開始学习的人,建议把这部分内容搞清楚,整个android系统对底层的操作都是通过这样的方法实现。
external\bluetooth\bluedroid\btif\src\bluetooth.c

static const bt_interface_t bluetoothInterface = {//蓝牙接口函数对应的函数
sizeof(bluetoothInterface),
init,//C函数中对init函数的实现;
enable,
disable,
cleanup,
get_adapter_properties,
get_adapter_property,
set_adapter_property,
get_remote_device_properties,
get_remote_device_property,
set_remote_device_property,
get_remote_service_record,
get_remote_services,
start_discovery,
cancel_discovery,
create_bond,
remove_bond,
cancel_bond,
pin_reply,
ssp_reply,
get_profile_interface,
dut_mode_configure,
dut_mode_send,
#if BLE_INCLUDED == TRUE
le_test_mode,
#else
NULL,
#endif
config_hci_snoop_log
};

4、蓝牙接口函数中Init函数实现过程
external\bluetooth\bluedroid\btif\src\bluetooth.c

static int init(bt_callbacks_t* callbacks )
{
ALOGI("init");
/* sanity check */
if (interface_ready() == TRUE)//检查接口函数是否准备好;
return BT_STATUS_DONE;
/* store reference to user callbacks */
bt_hal_cbacks = callbacks;//把对应的回调函数,保存。这个很重要,刚開始看代码是忽略这部分。我们单独一节解说这部分回调函数的实现和作用;
/* add checks for individual callbacks ? */
bt_utils_init();//工具集初始化,初始化一个相互排斥锁。
/* init btif */
btif_init_bluetooth();//初始化蓝牙接口bluetoothinterface
return BT_STATUS_SUCCESS;
}

5、蓝牙接口初始化详细实现,btif_init_bluetooth创建BTIF任务。准备蓝牙开启相关调度程序。
详细实现流程例如以下所看到的。我们以下对代码做详解。主要完毕了:
(1)、bt_config.xml文件里的蓝牙名称等处理;
(2)、GKI初始化,这部分后面单一节做详细分析。
(3)、BlueHCLibInterface初始化。实现power\preload\等函数,BlueDreoid  log等级设定;
(4)、BTIF_TASK线程创建。这个部分也比較重要。

external\bluetooth\bluedroid\btif\src\btif_core.c

bt_status_t btif_init_bluetooth()
{
UINT8 status;
btif_config_init();//创建sock线程。初始化初始化/data/misc/bluedroid/
bt_config.xml中相关数据。
bte_main_boot_entry();//(1)、BTE芯片协议栈入口API,蓝牙协议栈/芯片初始化,GKI init;
/* As part of the init, fetch the local BD ADDR */
memset(&btif_local_bd_addr, 0, sizeof(bt_bdaddr_t));//取蓝牙地址写入相关文件。
btif_fetch_local_bdaddr(&btif_local_bd_addr);
/* start btif task */
status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));
//(2)、Creates BTIF task and prepares BT scheduler for startup 创建蓝牙任务接口,为开启做调度准备
if (status != GKI_SUCCESS)
return BT_STATUS_FAIL;
return BT_STATUS_SUCCESS;
}

(1)、BTE芯片协议栈入口API。蓝牙协议栈/芯片初始化。GKI init。
external\bluetooth\bluedroid\main\bte_main.c

void bte_main_boot_entry(void)
{
/* initialize OS */
GKI_init();//1)、GKI初始化。仅仅在初始化的时候调用一次。 bte_main_in_hw_init();//2)、初始化结构体static bt_hc_interface_t *bt_hc_if=NULL; bte_load_conf(BTE_STACK_CONF_FILE);//3)、初始化bluedroid调试信息等级; #if (BTTRC_INCLUDED == TRUE)//相关信息打印初始化。
/* Initialize trace feature */
BTTRC_TraceInit(MAX_TRACE_RAM_SIZE, &BTE_TraceLogBuf[0], BTTRC_METHOD_RAM);
#endif
}

1)、GKI初始化。仅仅在初始化的时候调用一次
參考相互排斥锁:http://blog.csdn.net/kingmax26/article/details/5338065  。
external\bluetooth\bluedroid\gki\ulinux\gki_ulinux.c

void GKI_init(void)
{
pthread_mutexattr_t attr;
tGKI_OS *p_os; memset (&gki_cb, 0, sizeof (gki_cb)); gki_buffer_init();//1))、GKI 缓冲、缓冲池初始化;
gki_timers_init();//2))、GKI定时器初始化。
gki_cb.com.OSTicks = (UINT32) times(0); pthread_mutexattr_init(&attr);//3))、初始化pthread_mutexattr_t结构; #ifndef __CYGWIN__
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);//4))、设置相互排斥锁类型
#endif
p_os = &gki_cb.os;
pthread_mutex_init(&p_os->GKI_mutex, &attr);//5))、初始化相互排斥量GKI_mutex;
/* pthread_mutex_init(&GKI_sched_mutex, NULL); */
#if (GKI_DEBUG == TRUE)
pthread_mutex_init(&p_os->GKI_trace_mutex, NULL);// 6))、初始化相互排斥量GKI_trace_mutex;
#endif
/* pthread_mutex_init(&thread_delay_mutex, NULL); */ /* used in GKI_delay */
/* pthread_cond_init (&thread_delay_cond, NULL); */ /* Initialiase GKI_timer_update suspend variables & mutexes to be in running state.
* this works too even if GKI_NO_TICK_STOP is defined in btld.txt */
p_os->no_timer_suspend = GKI_TIMER_TICK_RUN_COND;
pthread_mutex_init(&p_os->gki_timer_mutex, NULL);7))、初始化相互排斥量gki_timer_mutex。
#ifndef NO_GKI_RUN_RETURN
pthread_cond_init(&p_os->gki_timer_cond, NULL);
#endif
}

2)、初始化结构体static bt_hc_interface_t *bt_hc_if=NULL;
bte_main_in_hw_init();
给bt_hc_if赋值:

static const bt_hc_interface_t bluetoothHCLibInterface = {
sizeof(bt_hc_interface_t),
init,//HCI LIB中init函数的实现;
set_power,
lpm,
preload,
postload,
transmit_buf,
set_rxflow,
logging,
cleanup
};

3)、初始化bluedroid调试信息等级
    bte_load_conf(BTE_STACK_CONF_FILE);
解析bt_stack.conf文件里的配置信息。
(2)、创建蓝牙任务接口。为开启做调度准备Creates BTIF task and prepares BT scheduler for startup  

  status = GKI_create_task(btif_task, BTIF_TASK, BTIF_TASK_STR,
(UINT16 *) ((UINT8 *)btif_task_stack + BTIF_TASK_STACK_SIZE),
sizeof(btif_task_stack));

6、btif_task进程相关处理函数
external\bluetooth\bluedroid\btif\src\btif_dm.c
btif_task 等待接收bta_sys_sendmsg发送的对应的状态做对应处理。

static void btif_task(UINT32 params)
{
………………
for(;;)
{
/* wait for specified events */
event = GKI_wait(0xFFFF, 0);//GKI进程间通信后面单开一节介绍;
if (event == BT_EVT_TRIGGER_STACK_INIT)//协议栈初始化完毕;
…………
if (event == BT_EVT_HARDWARE_INIT_FAIL)//硬件初始化错误
…………
if (event & EVENT_MASK(GKI_SHUTDOWN_EVT))//收到关闭信息。
…………
if(event & TASK_MBOX_1_EVT_MASK)
…………
}
}

Android BlueDroid(二):BlueDroid蓝牙开启过程init的更多相关文章

  1. Android BlueDroid(三):BlueDroid蓝牙开启过程enable

    关键词:bluedroid  enableNative BTIF_TASK  BTU_TASK bt_hc_work_thread set_power  preload GKI作者:xubin3417 ...

  2. ZT Android 4.2 BT系统之蓝牙关闭过程全跟踪

    Android 4.2 BT系统之蓝牙关闭过程全跟踪 分类: android 2013-08-03 00:34 2252人阅读 评论(10) 收藏 举报 代码位置:       frameworks/ ...

  3. 基于Android Classic Bluetooth的蓝牙聊天软件

    代码地址如下:http://www.demodashi.com/demo/12133.html BluetoothChat 基于Android Classic Bluetooth的蓝牙聊天软件,目前仅 ...

  4. Android世界第一个activity启动过程

    Android世界第一个activity启动过程 第一次使用Markdown,感觉不错. Android系统从按下开机键一直到launcher的出现,是一个如何的过程,中间都做出了什么操作呢.带着这些 ...

  5. Android应用程序内部启动Activity过程(startActivity)的源代码分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...

  6. 【转】android camera(二):摄像头工作原理、s5PV310 摄像头接口(CAMIF)

    关键词:android  camera CMM 模组 camera参数  CAMIF平台信息:内核:linux系统:android 平台:S5PV310(samsung exynos 4210) 作者 ...

  7. Android进阶(二十)AndroidAPP开发问题汇总(四)

    · Android进阶(二十)AndroidAPP开发问题汇总(四) android:layout_width和android:width的区别 基中的android:layout_width和and ...

  8. Android 6.0 Kotlin 蓝牙BLE扫描(改为指定时间没有发现新设备后停止扫描使用interface)

    package com.arci.myapplication import android.os.Bundleimport android.support.design.widget.Snackbar ...

  9. Android 6.0 Kotlin 蓝牙扫描

    package com.arci.myapplication import android.app.Activityimport android.os.Bundleimport android.sup ...

随机推荐

  1. JavaScript 的对象继承方式,有几种写法?

    JavaScript 的对象继承方式,有几种写法? 一.对象冒充 其原理如下:构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式).因为构造函数只是一个函数,所以可使 Pa ...

  2. apche本地测试,无法访问此网站

  3. RabbitMQ学习总结(2)——安装、配置与监控

    一.安装 1.安装Erlang 1)系统编译环境(这里采用linux/unix 环境) ① 安装环境 虚拟机:VMware® Workstation 10.0.1 build Linux系统:Cent ...

  4. 监控SQLserver计数器

  5. LaTeX 基本的公式符号命令

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50240237 下面列出一些基本的LaT ...

  6. HDU 4334 Contest 4

    本来以为是一道水题,好吧,做了才知道,出题的人有多牛.二分搜索是不可能的了,因为会超内存... 看到别人的搜索两个集合的提示,我就自己一边去想了.终于想出来了: 可以这样做,先把每两个集合的和值枚举出 ...

  7. 字符串中连续出现最多的子串 &amp; 字符串中最长反复子串

    字符串中连续出现最多的子串 & 字符串中最长反复子串 字符串中连续出现最多的子串 & 字符串中最长反复子串,这两个问题都能够用后缀数组来表示,至于后缀数组能够參考编程珠玑P156:后缀 ...

  8. ubuntu系统AndroidStudio改动内存大小

    位于android-studio/bin文件夹下的studio64.vmoptions和studio.vmoptions文件. 把Xms,Xmx,-XX:MaxPermSize.-XX:Reserve ...

  9. Remove Duplicates from Sorted List II 解答(有个比較特殊的case leetcode OJ没有覆盖)

    昨天被考了一道数据结构题,当时的实现比較一般.回来翻看leetcode,果然是上面的题.遂解之. accept之后翻看discuss别人的解法.发现非常多能够accept的代码都过不了我设计的一个ca ...

  10. UnrealEngine4初始化流程

    自古以来全部的游戏引擎都分为三个大阶段:Init,Loop,Exit.UE4也不例外. 首先找到带有入口函数的文件:Runtime/Launch/Private/XXXX/LaunchXXXX.cpp ...