1. Overview
Gki to Library libbt-brcm_gki.so (Static Lib?) In the form provided to bluedroid use
This layer is an adaptation layer that is adaptable to OS-related processes, memory-related management, and can also be used to pass messages between threads
The unified management of process is realized mainly through variable GKI_CB
<span style= "font-family: ' Courier New ';" >typedef <span class= "KWRD" >struct</span>{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]; <span class= "KWRD" >int</span> no_timer_suspend; <span class= "rem" >/* 1:no suspend, 0 stop calling Gki_timer_update () */</span> pthread_mutex_t Gki_tim Er_mutex; pthread_cond_t gki_timer_cond;<span class= "Preproc" > #if </span> (gki_debug = TRUE) pthread_mutex_t Gki_trace_mutex;<span class= "Preproc" > #endif </span>} tgki_os;typedef <span class= "KWRD" >struct </span>{... UINT8 *osstack[gki_max_tasks]; <span class= "REM" >/* pointer to beginning of stack */</span&Gt UINT16 Osstacksize[gki_max_tasks]; <span class= "rem" >/* stack size available to each task */</span> INT8 *ostname[gki_max_tasks]; <span class= "rem" >/* name of the task */</span> UINT8 Osrdytbl[gki_max_tasks]; <span class= "REM" >/* current state of the task */</span> UINT16 Oswaitevt[gki_max_tasks]; <span class= "REM" >/* events that there is processed by the task */</span> UINT16 Oswaitforevt[gki_max_ta SKS]; <span class= "REM" >/* events the task is waiting for*/</span> UINT32 osticks; <span class= "REM" >/* system ticks from start */</span> UINT32 osidlecnt; <span class= "REM" >/* idle counter */</span> INT16 osdisablenesting; <span class= "REM" >/* counter to keep track of interrupt disable nesting */</span> INT16 oslocknesting; <span class= "REM" >/* Counter to keep track of sched lock nesting */</span> INT16 osintnesting; <span class= "REM" >/* counter to keep track of interrupt nesting */</span> <span class= "rem" >/* Timer Related Variables</span><span class= "rem" > */</span> INT32 ostickstilexp; <span class= "REM" >/* number of ticks till next timer expires */</span><span class= "Preproc" > #if </ span> (defined (gki_delay_stop_sys_tick) && (Gki_delay_stop_sys_tick > 0)) UINT32 ostickstilstop; <span class= "REM" >/* inactivity delay timer; OS Ticks till stopping system tick */</span><span class= "Preproc" > #endif </span> INT32 osnumorigtick S <span class= "REM" >/* number of ticks between last timer expiration to the next one */</span> INT32 oswait TMR [Gki_max_tasks]; <span class= "REM" >/* ticks the task have to wait, for specific events */</span> ... <Span class= "REM" >/* Buffer related Variables</span><span class= "rem" > */</span> buffer_hdr_t *ostaskqfirst[gki_max_tasks][num_task_mbox]; <span class= "rem" >/* array of pointers to the first event in the task mailbox */</span> buffer_hdr_t *os Taskqlast [Gki_max_tasks][num_task_mbox]; <span class= "rem" >/* array of pointers to the last event in the task mailbox */</span> <span class= "REM" >/* Define the buffer pool management Variables</span><span class= "REM" > */</span> 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]; <span class= "rem" >/* Define the buffer pool start Addresses</span><span class= "rem" > */</span> UINT8 *pool_start[gki_num_total_buf_pools]; <span class= "rem" >/* array of pointers to the StArt of each buffer pool */</span> UINT8 *pool_end[gki_num_total_buf_pools]; <span class= "rem" >/* array of pointers to the end of each buffer pool */</span> UINT16 pool_size[gki_num_ Total_buf_pools]; <span class= "rem" >/* actual size of the buffers in a pool */</span> <span class= "rem" >/* Define the B Uffer Pool access Control variables */</span> <span class= "KWRD" >void</span> *p_user_mempool; <span class= "rem" >/* User o/s memory pool */</span> UINT16 Pool_access_mask; <span class= "rem" >/* Bits is set if the corresponding buffer pool is a restricted pool */</span> UINT8 Pool_list[gki_num_total_buf_pools]; <span class= "rem" >/* buffer pools arranged in the order of size */</span> UINT8 Curr_total_no_of_pool S <span class= "REM" >/* number of fixed buf pools + current number of dynamic pools */≪/span> BOOLEAN timer_nesting; <span class= "REM" >/* flag to prevent timer interrupt nesting */</span> <span class= "rem" >/* time Queu E arrays */</span> timer_list_q *timer_queues[gki_max_timer_queues]; <span class= "rem" >/* System Tick callback */</span> system_tick_cback *P_TICK_CB; BOOLEAN system_tick_running; <span class= "rem" >/* TRUE if system tick is running. Valid only if P_TICK_CB are not NULL */</span><span class= "Preproc" > #if </span> (gki_debug = TRUE) UIN T16 exceptioncnt; <span class= "REM" >/* number of Gki exceptions that has happened */</span> exception_t exception[gki_max_ex Ception];<span class= "Preproc" > #endif </span>} tgki_com_cb;typedef <span class= "KWRD" >struct</ span>{Tgki_os OS; TGKI_COM_CB COM;} TGKI_CB;TGKI_CB gki_cb</span>
2. Thread 2.1 Main function
-Gki_init () Initialize variable GKI_CB
-Gki_create_task () Create thread
-Gki_destroy_task () Destroy thread
-Gki_run () Time-dependent execution function, not currently known what effect
2.2 Features
Threading-related features using the Pthread library
Gki Management of three threads
<span class= "Preproc" > #define </span> btu_task 0<span class= "Preproc" > #define </span> Btif_task 1<span class= "Preproc" > #define </span> a2dp_media_task 2
3. Event 3.1 Main function
-gki_wait () wait for the event to occur
-Gki_send_event () sends an event to the specified process
-GKI_SEND_MSG () sends buffer to the specified process
-Gki_read_mbox () read buffer from mailbox
3.2 Features
<span style= "font-family: ' Courier New ';" >tgki_cb.os.thread_evt_mutex[] Event's mutex tgki_cb.os.thread_evt_cond[] event's condition variable tgki_cb.com.oswaitevt[] Represents the event of the current process tgki_cb.com.ostaskqfirst[][] The first event in the mailbox of a process tgki_cb.com.ostaskqlast[][] Point to the last event in the mailbox of a process </span>
First we want to understand the use of POSIX mutexes and condition variables
Tip: It is worth mentioning that the pthread_cond_wait () function unlocks the mutex in the parameter after it has been invoked until it is awakened and re-locks the mutex
The principle of the Gki event
The event/mbox event is sent through the gki_send_event ()/gki_send_msg (), and the receiving thread can detect the occurrence of events through gki_wait () and handle different events differently
For mbox events, you need to loop the call Gki_read_mbox () to get the mbox Buffer
Tip: Events can be sent to this thread in addition to other threads
Each thread has four mailbox
There are 16 events (EVT:0~15)
-4 retention events for receiving evt:0~3 of mailbox messages
-4 Retention events for timeout evt:4~7
-8 common events for all apps using evt:8~15
can be obtained by Event_mask (EVT) in turn
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Gki framework of Bluedroid