BlueDroid代码分析之GKI
1. 概述
GKI以库libbt-brcm_gki.so(Static Lib?)的形式提供给BlueDroid使用
该层是一个适配层,适配了OS相关的进程、内存相关的管理,还可以用于线程间传递消息
主要通过变量gki_cb实现对进程的统一管理
typedef struct
{
pthread_mutex_t GKI_mutex;
pthread_t thread_id[GKI_MAX_TASKS];
pthread_mutex_t thread_evt_mutex[GKI_MAX_TASKS];
pthread_cond_t thread_evt_cond[GKI_MAX_TASKS];
pthread_mutex_t thread_timeout_mutex[GKI_MAX_TASKS];
pthread_cond_t thread_timeout_cond[GKI_MAX_TASKS];
int no_timer_suspend; /* 1: no suspend, 0 stop calling GKI_timer_update() */
pthread_mutex_t gki_timer_mutex;
pthread_cond_t gki_timer_cond;
#if (GKI_DEBUG == TRUE)
pthread_mutex_t GKI_trace_mutex;
#endif
} tGKI_OS;
typedef struct
{
...
UINT8 *OSStack[GKI_MAX_TASKS]; /* pointer to beginning of stack */
UINT16 OSStackSize[GKI_MAX_TASKS]; /* stack size available to each task */
INT8 *OSTName[GKI_MAX_TASKS]; /* name of the task */
UINT8 OSRdyTbl[GKI_MAX_TASKS]; /* current state of the task */
UINT16 OSWaitEvt[GKI_MAX_TASKS]; /* events that have to be processed by the task */
UINT16 OSWaitForEvt[GKI_MAX_TASKS]; /* events the task is waiting for*/
UINT32 OSTicks; /* system ticks from start */
UINT32 OSIdleCnt; /* idle counter */
INT16 OSDisableNesting; /* counter to keep track of interrupt disable nesting */
INT16 OSLockNesting; /* counter to keep track of sched lock nesting */
INT16 OSIntNesting; /* counter to keep track of interrupt nesting */
/* Timer related variables
*/
INT32 OSTicksTilExp; /* Number of ticks till next timer expires */
#if (defined(GKI_DELAY_STOP_SYS_TICK) && (GKI_DELAY_STOP_SYS_TICK > 0))
UINT32 OSTicksTilStop; /* inactivity delay timer; OS Ticks till stopping system tick */
#endif
INT32 OSNumOrigTicks; /* Number of ticks between last timer expiration to the next one */
INT32 OSWaitTmr [GKI_MAX_TASKS]; /* ticks the task has to wait, for specific events */
...
/* Buffer related variables
*/
BUFFER_HDR_T *OSTaskQFirst[GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the first event in the task mailbox */
BUFFER_HDR_T *OSTaskQLast [GKI_MAX_TASKS][NUM_TASK_MBOX]; /* array of pointers to the last event in the task mailbox */
/* Define the buffer pool management variables
*/
FREE_QUEUE_T freeq[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_buf_size[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_max_count[GKI_NUM_TOTAL_BUF_POOLS];
UINT16 pool_additions[GKI_NUM_TOTAL_BUF_POOLS];
/* Define the buffer pool start addresses
*/
UINT8 *pool_start[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the start of each buffer pool */
UINT8 *pool_end[GKI_NUM_TOTAL_BUF_POOLS]; /* array of pointers to the end of each buffer pool */
UINT16 pool_size[GKI_NUM_TOTAL_BUF_POOLS]; /* actual size of the buffers in a pool */
/* Define the buffer pool access control variables */
void *p_user_mempool; /* User O/S memory pool */
UINT16 pool_access_mask; /* Bits are set if the corresponding buffer pool is a restricted pool */
UINT8 pool_list[GKI_NUM_TOTAL_BUF_POOLS]; /* buffer pools arranged in the order of size */
UINT8 curr_total_no_of_pools; /* number of fixed buf pools + current number of dynamic pools */
BOOLEAN timer_nesting; /* flag to prevent timer interrupt nesting */
/* Time queue arrays */
TIMER_LIST_Q *timer_queues[GKI_MAX_TIMER_QUEUES];
/* System tick callback */
SYSTEM_TICK_CBACK *p_tick_cb;
BOOLEAN system_tick_running; /* TRUE if system tick is running. Valid only if p_tick_cb is not NULL */
#if (GKI_DEBUG == TRUE)
UINT16 ExceptionCnt; /* number of GKI exceptions that have happened */
EXCEPTION_T Exception[GKI_MAX_EXCEPTION];
#endif
} tGKI_COM_CB;
typedef struct
{
tGKI_OS os;
tGKI_COM_CB com;
} tGKI_CB;
tGKI_CB gki_cb
2. 线程
2.1 主要函数
- GKI_init() 初始化变量gki_cb
- GKI_create_task() 创建线程
- GKI_destroy_task() 销毁线程
- GKI_run() 时间相关执行函数,目前不知道有何效果
2.2 功能
使用pthread库实现线程相关功能
GKI管理三个线程
#define BTU_TASK 0 #define BTIF_TASK 1 #define A2DP_MEDIA_TASK 2
3. 事件
3.1 主要函数
- GKI_wait() 等待事件的发生
- GKI_send_event()向指定进程发送事件
- GKI_send_msg() 向指定进程发送buffer
- GKI_read_mbox() 从mailbox中读取buffer
3.2 功能
tGKI_CB.os.thread_evt_mutex[] 事件的互斥锁 tGKI_CB.os.thread_evt_cond[] 事件的条件变量 tGKI_CB.com.OSWaitEvt[] 表示当前进程的事件 tGKI_CB.com.OSTaskQFirst[][] 指向进程的mailbox中第一个事件 tGKI_CB.com.OSTaskQLast[][] 指向进程的mailbox中最后一个事件
首先我们要了解Posix互斥锁和条件变量的使用
tip: 值得一提的是pthread_cond_wait()函数在调用后解锁参数中的互斥锁,直至被唤醒后重新对该互斥锁加锁
GKI事件的原理
通过GKI_send_event()/GKI_send_msg()发送事件/MBox事件,接收线程通过GKI_wait()可检测事件的发生,并对不同的事件进行不同的处理
对于MBox事件,需要再循环调用GKI_read_mbox()来得到MBOX Buffer
tip: 事件可以除了可以发往其他线程,也可以发往本线程
每个线程都有四个Mailbox
事件有16个(evt: 0~15)
- 4个保留事件用于Mailbox消息的接收 evt: 0~3
- 4个保留事件用于超时 evt: 4~7
- 8个通用事件共APP使用 evt: 8~15
可依次由EVENT_MASK(evt)得到
BlueDroid代码分析之GKI的更多相关文章
- Android代码分析工具lint学习
1 lint简介 1.1 概述 lint是随Android SDK自带的一个静态代码分析工具.它用来对Android工程的源文件进行检查,找出在正确性.安全.性能.可使用性.可访问性及国际化等方面可能 ...
- pmd静态代码分析
在正式进入测试之前,进行一定的静态代码分析及code review对代码质量及系统提高是有帮助的,以上为数据证明 Pmd 它是一个基于静态规则集的Java源码分析器,它可以识别出潜在的如下问题:– 可 ...
- [Asp.net 5] DependencyInjection项目代码分析-目录
微软DI文章系列如下所示: [Asp.net 5] DependencyInjection项目代码分析 [Asp.net 5] DependencyInjection项目代码分析2-Autofac [ ...
- [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(5)(IEnumerable<>补充)
Asp.net 5的依赖注入注入系列可以参考链接: [Asp.net 5] DependencyInjection项目代码分析-目录 我们在之前讲微软的实现时,对于OpenIEnumerableSer ...
- 完整全面的Java资源库(包括构建、操作、代码分析、编译器、数据库、社区等等)
构建 这里搜集了用来构建应用程序的工具. Apache Maven:Maven使用声明进行构建并进行依赖管理,偏向于使用约定而不是配置进行构建.Maven优于Apache Ant.后者采用了一种过程化 ...
- STM32启动代码分析 IAR 比较好
stm32启动代码分析 (2012-06-12 09:43:31) 转载▼ 最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...
- 常用 Java 静态代码分析工具的分析与比较
常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...
- SonarQube-5.6.3 代码分析平台搭建使用
python代码分析 官网主页: http://docs.sonarqube.org/display/PLUG/Python+Plugin Windows下安装使用: 快速使用: 1.下载jdk ht ...
- angular代码分析之异常日志设计
angular代码分析之异常日志设计 错误异常是面向对象开发中的记录提示程序执行问题的一种重要机制,在程序执行发生问题的条件下,异常会在中断程序执行,同时会沿着代码的执行路径一步一步的向上抛出异常,最 ...
随机推荐
- PHP API 框架开发的学习
基于互联网的应用正变得越来越普及,在这个过程中,有更多的站点将自身的资源开放给开发者来调用.对外提供的API 调用使得站点之间的内容关联性更强,同时这些开放的平台也为用户.开发者和中小网站带来了更大的 ...
- StringUtils中 isNotEmpty 和isNotBlank的区别【java字符串判空】
isNotEmpty(str)等价于 str != null && str.length > 0 isNotBlank(str) 等价于 str != null &&am ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
- HDU3996 Gold Mine(最大权闭合子图)
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> using ...
- BZOJ1769 : [Ceoi2009]tri
将所有点极角排序,建立线段树,线段树每个节点维护该区间内所有点组成的上下凸壳. 对于一个查询,二分查找出相应区间的左右端点,在线段树上得到$O(\log n)$个节点,在相应凸壳上三分查找出与斜边叉积 ...
- BZOJ3867 : Nice boat
每个点最多被修改$O(\log n)$次,线段树记录区间最值暴力更新. #include<cstdio> #define N 262145 int T,n,m,i,op,c,d,p,s[N ...
- HDU 3966(树链剖分+点修改+点查询)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题目大意:营地的分布成树型.每个营地都有一些人,每次修改修改一条链上的所有营地的人数,每次查询单 ...
- JAVA中堆栈和内存分配
(一).栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或 ...
- 【POJ】2234 Matches Game(博弈论)
http://poj.org/problem?id=2234 博弈论真是博大精深orz 首先我们仔细分析很容易分析出来,当只有一堆的时候,先手必胜:两堆并且相同的时候,先手必败,反之必胜. 根据博弈论 ...
- php利用wsh突破函数禁用执行命令(安全模式同理)
php利用wsh突破函数禁用执行命令(安全模式同理) 前提.需要服务器支持wsh.并知道php安装目录 但是php利用wsh执行命令是没有asp的权限高的. 突破代码 <?php $cmd= ...