• 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)得到

  • 相关阅读:
    Python之异常篇 [待更新]
    python脚本工具 - 4 获取系统当前时间
    python脚本工具 - 3 目录遍历
    数字签名和数字证书到底是个神马玩意?
    CSRF攻击[转]
    Python之数据结构篇
    Python之模块篇
    Python之函数篇
    python脚本工具-2 去除扩展名后提取目录下所有文件名并保存
    python脚本工具-1 制作爬虫下载网页图片
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7102145.html
Copyright © 2020-2023  润新知