![藍(lán)牙4.0協(xié)議棧按鍵流程分析_第1頁](http://file2.renrendoc.com/fileroot_temp3/2021-11/18/c959589c-ed5e-417b-9682-3cce4dee7ca6/c959589c-ed5e-417b-9682-3cce4dee7ca61.gif)
![藍(lán)牙4.0協(xié)議棧按鍵流程分析_第2頁](http://file2.renrendoc.com/fileroot_temp3/2021-11/18/c959589c-ed5e-417b-9682-3cce4dee7ca6/c959589c-ed5e-417b-9682-3cce4dee7ca62.gif)
![藍(lán)牙4.0協(xié)議棧按鍵流程分析_第3頁](http://file2.renrendoc.com/fileroot_temp3/2021-11/18/c959589c-ed5e-417b-9682-3cce4dee7ca6/c959589c-ed5e-417b-9682-3cce4dee7ca63.gif)
![藍(lán)牙4.0協(xié)議棧按鍵流程分析_第4頁](http://file2.renrendoc.com/fileroot_temp3/2021-11/18/c959589c-ed5e-417b-9682-3cce4dee7ca6/c959589c-ed5e-417b-9682-3cce4dee7ca64.gif)
![藍(lán)牙4.0協(xié)議棧按鍵流程分析_第5頁](http://file2.renrendoc.com/fileroot_temp3/2021-11/18/c959589c-ed5e-417b-9682-3cce4dee7ca6/c959589c-ed5e-417b-9682-3cce4dee7ca65.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、在介紹藍(lán)牙按鍵流程分析之前,我們需要了解一個(gè)概念,那就是就是OSAL。什么是OSAL呢?可能大伙對(duì)于OS是比較了解的,學(xué)了計(jì)算機(jī)的搞過OS的也基本接觸過,簡單來說就是一個(gè)操作系統(tǒng)抽象層,可以理解為運(yùn)行在 CC2540 上的操作系統(tǒng),說操作系統(tǒng)還不能算,TI的OSAL只實(shí)現(xiàn)了任務(wù)切換和消息機(jī)制。并且把協(xié)議棧的代碼、硬件處理的代碼,用戶程序的代碼等分別放到了 OSAL 層的不同任務(wù)處理函數(shù)中去了,各任務(wù)函數(shù)之間通過消息機(jī)制、同一個(gè)任務(wù)之間通過事件的的方式來通信。什么是 EVENT 事件?OSAL 為每個(gè)任務(wù)函數(shù)分配了一個(gè) 16 位的事件變量,每一位代表一個(gè)事件,最高位為 0x8000表示為系統(tǒng)事件
2、 SYS_EVENT_MSG。其余的15 位留給用戶自定義需要的事件。通常事件由定時(shí)器啟動(dòng),比如一秒后我要點(diǎn)亮 LED2,這就需要發(fā)送一個(gè)點(diǎn)亮 LED2 的事件,然后等待定時(shí)器1s后溢出,于是啟動(dòng)點(diǎn)亮 LED2事件,事件會(huì)調(diào)用相應(yīng)的hal 層API點(diǎn)亮LED2。什么是 MSG 消息MSG 是比 EVENT 事件更具體并且可以攜帶數(shù)據(jù)的一種通信方式,MSG 的標(biāo)記是按數(shù)值,而不是按位。比如 0x01 和 0x02 是兩個(gè)不同的消息,但對(duì)于事件 0x03 則是 0x01 事件和 0x02 事件的組合。MSG 收發(fā)使用 osal_msg_send()和 osal_msg_receive();當(dāng)調(diào)用
3、osal_msg_send()發(fā)送一個(gè) msg 的同時(shí)會(huì)在 EVENT 列表中觸發(fā)一個(gè) message ready event。(請(qǐng)注意最后一句話,這句話點(diǎn)出了為什么按鍵時(shí)間的觸發(fā)為何會(huì)導(dǎo)致系統(tǒng)事件也接受到了)現(xiàn)在以 SimpleBLEPeripheral 為例說明按鍵流程在 SimpleBLEPeripheral 任務(wù)初始化函數(shù)中有這樣一條代碼: / Register for all key events - This app will handle all key events RegisterForKeys( simpleBLEPeripher
4、al_TaskID );這個(gè)函數(shù)來自 OnBoard.c 源文件中/* Keyboard Register function* The keyboard handler is setup to send all keyboard changes to* one task (if a task is registered).* If a task registers, it will get all the keys. You can change this* to register for individual keys.*/uint8 RegisterForKeys( uint8 task_
5、id ) / Allow only the first task if ( registeredKeysTaskID = NO_TASK_ID ) registeredKeysTaskID = task_id; return ( true ); else return ( false );向一個(gè)全局變量 registeredKeysTaskID中賦值自己的任務(wù) ID,調(diào)用了這個(gè)函數(shù)就能成功注冊(cè)按鍵服務(wù),那
6、這個(gè)全局變量在何時(shí)使用呢?分析到這里,感覺有點(diǎn)迷糊了,我們可以從頂?shù)较路治?。任何一個(gè)程序都是從main函數(shù)開始的,這點(diǎn)我們要堅(jiān)信。所以我們首先找到這個(gè)main函數(shù)打開SimpleBLEPeripheral_Main.c文件可以看到/* fn main* brief Start of application.* param none* return none*/int
7、 main(void) /* Initialize hardware */ HAL_BOARD_INIT(); / Initialize board I/O InitBoard( OB_COLD ); /* Initialze the HAL driver */ HalDriverInit(); /* Initialize NV system */ osal_snv_init(); &
8、#160;/* Initialize LL */ /* Initialize the operating system */ osal_init_system(); /* Enable interrupts */ HAL_ENABLE_INTERRUPTS(); / Final board initialization InitBoard( OB_READY ); #if defined ( POWER_SAVING )
9、0; osal_pwrmgr_device( PWRMGR_BATTERY ); #endif /* Start OSAL */ osal_start_system(); / No Return from here return 0;我們打開 InitBoard( OB_READY );可以看到如下代碼/* fn InitBoard()* brief Initialize the CC2540DB Board Peripherals*
10、 param level: COLD,WARM,READY* return None*/void InitBoard( uint8 level ) if ( level = OB_COLD ) / Interrupts off osal_int_disable( INTS_ALL ); / Turn all LEDs off HalLedSet( HAL_LED_ALL, HAL_LED_MODE_O
11、FF ); / Check for Brown-Out reset/ ChkReset(); else / !OB_COLD /* Initialize Key stuff */ OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE; /OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
12、160; HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); 看到我上面標(biāo)注的函數(shù)了吧?那個(gè)是一個(gè)按鍵回調(diào)服務(wù)注冊(cè)函數(shù),注冊(cè)了一個(gè)OnBoard_KeyCallback函數(shù)HalKeyConfig 函數(shù)的實(shí)現(xiàn):將上述的回調(diào)函數(shù)的地址復(fù)制給了函數(shù)指針變量。通過跟蹤發(fā)現(xiàn)該函數(shù)的指針變量在按鍵的輪詢函數(shù)中調(diào)用了,如下圖:/* fn HalKeyPoll* brief Called by hal_driver t
13、o poll the keys* param None* return None*/void HalKeyPoll (void) uint8 keys = 0; uint8 notify = 0;#if defined (CC2540_MINIDK) if (!(HAL_KEY_SW_1_PORT & HAL_KEY_SW_1_BIT) /* Key is active low */ keys |=
14、HAL_KEY_SW_1; if (!(HAL_KEY_SW_2_PORT & HAL_KEY_SW_2_BIT) /* Key is active low */ keys |= HAL_KEY_SW_2; #else if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT) /* Key is active low */
15、 keys |= HAL_KEY_SW_6; if (HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT) /* Key is active HIGH */ keys = halGetJoyKeyInput(); #endif /* If interrupts are not enabled, previous key status and current key status
16、 * are compared to find out if a key has changed status. */ if (!Hal_KeyIntEnable) if (keys = halKeySavedKeys) /* Exit - since no keys have changed */ return;
17、0; else notify = 1; else /* Key interrupt handled here */ if (keys) notify = 1; /* Store the current ke
18、ys for comparation next time */ halKeySavedKeys = keys; /* Invoke Callback if new keys were depressed */ if (notify && (pHalKeyProcessFunction) (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); 在這里底層的按鍵查詢函數(shù)調(diào)用
19、一個(gè)函數(shù)指針,而非具體的函數(shù),這樣就將處理按鍵的接口留給了上層,上層應(yīng)用中,叧需解析的函數(shù)指針傳入的參數(shù) 1:keys 就知道是哪個(gè)按鍵被按下了。我們?cè)倩氐絼偛诺?OnBoard_KeyCallback 回調(diào)函數(shù)處,該回調(diào)函數(shù)代碼如下:/* fn OnBoard_KeyCallback* brief Callback service for keys* param keys - keys that were pressed*
20、 state - shifted* return void*/void OnBoard_KeyCallback ( uint8 keys, uint8 state ) uint8 shift; (void)state; / shift key (S1) is used to generate key interrupt / applications should not use S1 when key interrupt is enabled
21、60;shift = (OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE) ? false : (keys & HAL_KEY_SW_6) ? true : false); if ( OnBoard_SendKeys( keys, shift ) != SUCCESS ) /就是這句話將按鍵消息上傳到應(yīng)用層去處理的 / Process SW1 here if ( keys & HAL_KEY_SW
22、_1 ) / Switch 1 / Process SW2 here if ( keys & HAL_KEY_SW_2 ) / Switch 2 / Process SW3 here if ( keys & HAL_KEY_SW_3 ) / Switch 3 &
23、#160; / Process SW4 here if ( keys & HAL_KEY_SW_4 ) / Switch 4 / Process SW5 here if ( keys & HAL_KEY_SW_5 ) / Switch 5 / Process SW6 here
24、60; if ( keys & HAL_KEY_SW_6 ) / Switch 6 /* If any key is currently pressed down and interrupt is still enabled, disable interrupt and switch to polling */ if( keys != 0 ) i
25、f( OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE ) OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE; HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); /* If no key is currently pressed down an
26、d interrupt is disabled, enable interrupt and turn off polling */ else if( OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE ) OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE; Hal
27、KeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); 進(jìn)入按鍵消息發(fā)送函數(shù)中可以看到/* fn OnBoard_SendKeys* brief Send "Key Pressed" message to application.* param keys - keys that were pressed*
28、 state - shifted* return status*/uint8 OnBoard_SendKeys( uint8 keys, uint8 state ) keyChange_t *msgPtr; if ( registeredKeysTaskID != NO_TASK_ID ) / Send the address to the task msgPtr = (keyChange_t *)osal_msg_alloca
29、te( sizeof(keyChange_t) ); if ( msgPtr ) msgPtr->hdr.event = KEY_CHANGE; msgPtr->state = state; msgPtr->keys = keys; osal_msg_send( registeredKeysTaskID, (uint
30、8 *)msgPtr ); return ( SUCCESS ); else return ( FAILURE );主要是將按鍵時(shí)間,狀態(tài)和按鍵值打包到信息中最后通過 osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );發(fā)送到注冊(cè)了按鍵服務(wù)的應(yīng)用層去 ,最終用戶按了哪個(gè)按鍵,如何響應(yīng)該按鍵在系統(tǒng)事件 SYS_EVENT_MSG 中處理。疑問又來了,為什么通過 osal_msg_send 收發(fā)的
31、消息會(huì)出現(xiàn)在 SYS_EVENT_MSG 中呢?這個(gè)疑問,就是剛才我說過的osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr )會(huì)產(chǎn)生一個(gè) a message ready event in the destination tasks event list./* fn osal_msg_send* brief* This function is called by a task to send a command message to*
32、 another task or processing element. The sending_task field must* refer to a valid task, since the task ID will be used* for the response message. This function will also set a message* ready event in the destination tasks eve
33、nt list.* param uint8 destination_task - Send msg to Task ID* param uint8 *msg_ptr - pointer to new message buffer* return SUCCESS, INVALID_TASK, INVALID_MSG_POINTER*/uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ) return ( osal_msg_enqueue
34、_push( destination_task, msg_ptr, FALSE ) );/* fn simpleBLEPeripheral_ProcessOSALMsg* brief Process an incoming task message.* param pMsg - message to process* return none*/static void simpleBLEPeripheral_ProcessOSALMsg( osal_event_hdr_t *p
35、Msg ) switch ( pMsg->event ) #if defined( CC2540_MINIDK ) case KEY_CHANGE: /按鍵處理事件,用戶產(chǎn)生的按鍵都是在這里處理 simpleBLEPeripheral_Handle
36、Keys( (keyChange_t *)pMsg)->state, (keyChange_t *)pMsg)->keys ); break; #endif / #if defined( CC2540_MINIDK ) default: / do nothing break; 在 SimpleBLEPeripheral 中,對(duì)按鍵的響應(yīng)如下:joystick right(SW2)收發(fā)廣播的開啟和關(guān)閉/* fn
37、0; simpleBLEPeripheral_HandleKeys* brief Handles all key events for this device.* param shift - true if in shift/alt.* param keys - bit field for key events. Valid entries:* &
38、#160;HAL_KEY_SW_2* HAL_KEY_SW_1* return none*/static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys ) uint8 SK_Keys = 0; VOID shift; / Intentionally unreferenced para
39、meter if ( keys & HAL_KEY_SW_1 ) SK_Keys |= SK_KEY_LEFT; if ( keys & HAL_KEY_SW_2 ) SK_Keys |= SK_KEY_RIGHT; / if device is not in a connection, pressing the right key should toggle / advertising on
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030全球電動(dòng)汽車高壓直流繼電器行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025年全球及中國IO-Link信號(hào)燈行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2025年全球及中國堆棧式CMOS圖像傳感器行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 經(jīng)典居間合同
- 農(nóng)機(jī)作業(yè)服務(wù)合同
- 環(huán)保設(shè)施運(yùn)營管理合同
- 熱長期供貨合同
- 安全監(jiān)控系統(tǒng)集成服務(wù)合同
- 政府與企業(yè)合作協(xié)議
- 循環(huán)借款合同標(biāo)準(zhǔn)范本
- 普通話培訓(xùn)班合作協(xié)議書
- 《西方思想經(jīng)典》課件
- 中醫(yī)診療設(shè)備種類目錄
- 戰(zhàn)略管理與倫理
- 如何構(gòu)建高效課堂課件
- 徐金桂行政法與行政訴訟法新講義
- 瀝青拌合設(shè)備結(jié)構(gòu)認(rèn)知
- GB/T 13234-2018用能單位節(jié)能量計(jì)算方法
- (課件)肝性腦病
- 北師大版五年級(jí)上冊(cè)數(shù)學(xué)教學(xué)課件第5課時(shí) 人民幣兌換
- 工程回訪記錄單
評(píng)論
0/150
提交評(píng)論