蓝牙40协议栈按键流程分析Word文档下载推荐.docx
《蓝牙40协议栈按键流程分析Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《蓝牙40协议栈按键流程分析Word文档下载推荐.docx(13页珍藏版)》请在冰点文库上搜索。
![蓝牙40协议栈按键流程分析Word文档下载推荐.docx](https://file1.bingdoc.com/fileroot1/2023-5/9/d50d3f55-e028-4211-ada9-a77b5abf37f4/d50d3f55-e028-4211-ada9-a77b5abf37f41.gif)
*
*Thekeyboardhandlerissetuptosendallkeyboardchangesto
*onetask(ifataskisregistered).
*Ifataskregisters,itwillgetallthekeys.Youcanchangethis
*toregisterforindividualkeys.
*********************************************************************/
uint8RegisterForKeys(uint8task_id)
{
//Allowonlythefirsttask
if(registeredKeysTaskID==NO_TASK_ID)
registeredKeysTaskID=task_id;
return(true);
}
else
return(false);
向一个全局变量registeredKeysTaskID中赋值自己的任务ID,调用了这个函数就能成功注册按键服务,那这个全局变量在何时使用呢?
分析到这里,感觉有点迷糊了,我们可以从顶到下分析。
任何一个程序都是从main函数开始的,这点我们要坚信。
所以我们首先找到这个main函数
打开SimpleBLEPeripheral_Main.c文件可以看到/**************************************************************************************************
*@fn
main
*@brief
Startofapplication.
*@param
none
*@return
none
**************************************************************************************************
*/
intmain(void)
/*Initializehardware*/
HAL_BOARD_INIT();
//InitializeboardI/O
InitBoard(OB_COLD);
/*InitialzetheHALdriver*/
HalDriverInit();
/*InitializeNVsystem*/
osal_snv_init();
/*InitializeLL*/
/*Initializetheoperatingsystem*/
osal_init_system();
/*Enableinterrupts*/
HAL_ENABLE_INTERRUPTS();
//Finalboardinitialization
InitBoard(OB_READY);
#ifdefined(POWER_SAVING)
osal_pwrmgr_device(PWRMGR_BATTERY);
#endif
/*StartOSAL*/
osal_start_system();
//NoReturnfromhere
return0;
我们打开InitBoard(OB_READY);
可以看到如下代码
InitBoard()
InitializetheCC2540DBBoardPeripherals
level:
COLD,WARM,READY
None
voidInitBoard(uint8level)
if(level==OB_COLD)
//Interruptsoff
osal_int_disable(INTS_ALL);
//TurnallLEDsoff
HalLedSet(HAL_LED_ALL,HAL_LED_MODE_OFF);
//CheckforBrown-Outreset
//
ChkReset();
else
//!
OB_COLD
/*InitializeKeystuff*/
OnboardKeyIntEnable=HAL_KEY_INTERRUPT_ENABLE;
//OnboardKeyIntEnable=HAL_KEY_INTERRUPT_DISABLE;
HalKeyConfig(OnboardKeyIntEnable,OnBoard_KeyCallback);
看到我上面标注的函数了吧?
那个是一个按键回调服务注册函数,注册了一个OnBoard_KeyCallback函数
HalKeyConfig函数的实现:
将上述的回调函数的地址复制给了函数指针变量。
通过跟踪发现该函数的指针变量在按键的轮询函数中调用了,如下图:
/**************************************************************************************************
HalKeyPoll
Calledbyhal_drivertopollthekeys
**************************************************************************************************/
voidHalKeyPoll(void)
uint8keys=0;
uint8notify=0;
#ifdefined(CC2540_MINIDK)
if(!
(HAL_KEY_SW_1_PORT&
HAL_KEY_SW_1_BIT))
/*Keyisactivelow*/
keys|=HAL_KEY_SW_1;
(HAL_KEY_SW_2_PORT&
HAL_KEY_SW_2_BIT))
keys|=HAL_KEY_SW_2;
#else
(HAL_KEY_SW_6_PORT&
HAL_KEY_SW_6_BIT))
keys|=HAL_KEY_SW_6;
if((HAL_KEY_JOY_MOVE_PORT&
HAL_KEY_JOY_MOVE_BIT))
/*KeyisactiveHIGH*/
keys=halGetJoyKeyInput();
/*Ifinterruptsarenotenabled,previouskeystatusandcurrentkeystatus
*arecomparedtofindoutifakeyhaschangedstatus.
Hal_KeyIntEnable)
if(keys==halKeySavedKeys)
{
/*Exit-sincenokeyshavechanged*/
return;
}
else
notify=1;
/*Keyinterrupthandledhere*/
if(keys)
/*Storethecurrentkeysforcomparationnexttime*/
halKeySavedKeys=keys;
/*InvokeCallbackifnewkeysweredepressed*/
if(notify&
&
(pHalKeyProcessFunction))
(pHalKeyProcessFunction)(keys,HAL_KEY_STATE_NORMAL);
在这里底层的按键查询函数调用一个函数指针,而非具体的函数,这样就将处理按键的接口留给了上层,上层应用中,叧需解析的函数指针传入的参数1:
keys就知道是哪个按键被按下了。
我们再回到刚才的OnBoard_KeyCallback回调函数处,该回调函数代码如下:
OnBoard_KeyCallback
Callbackserviceforkeys
keys
-keysthatwerepressed
*
state-shifted
void
voidOnBoard_KeyCallback(uint8keys,uint8state)
uint8shift;
(void)state;
//shiftkey(S1)isusedtogeneratekeyinterrupt
//applicationsshouldnotuseS1whenkeyinterruptisenabled
shift=(OnboardKeyIntEnable==HAL_KEY_INTERRUPT_ENABLE)?
false:
((keys&
HAL_KEY_SW_6)?
true:
false);
if(
OnBoard_SendKeys(keys,shift)!
=SUCCESS
)
//就是这句话将按键消息上传到应用层去处理的
//ProcessSW1here
if(keys&
HAL_KEY_SW_1)
//Switch1
//ProcessSW2here
HAL_KEY_SW_2)
//Switch2
//ProcessSW3here
HAL_KEY_SW_3)
//Switch3
//ProcessSW4here
HAL_KEY_SW_4)
//Switch4
//ProcessSW5here
HAL_KEY_SW_5)
//Switch5
//ProcessSW6here
HAL_KEY_SW_6)
//Switch6
/*Ifanykeyiscurrentlypresseddownandinterrupt
isstillenabled,disableinterruptandswitchtopolling*/
if(keys!
=0)
if(OnboardKeyIntEnable==HAL_KEY_INTERRUPT_ENABLE)
OnboardKeyIntEnable=HAL_KEY_INTERRUPT_DISABLE;
/*Ifnokeyiscurrentlypresseddownandinterrupt
isdisabled,enableinterruptandturnoffpolling*/
if(OnboardKeyIntEnable==HAL_KEY_INTERRUPT_DISABLE)
OnboardKeyIntEnable=HAL_KEY_INTERRUPT_ENABLE;
进入按键消息发送函数中可以看到
OnBoard_SendKeys
Send"
KeyPressed"
messagetoapplication.
status
uint8OnBoard_SendKeys(uint8keys,uint8state)
keyChange_t*msgPtr;
if(registeredKeysTaskID!
=NO_TASK_ID)
//Sendtheaddresstothetask
msgPtr=(keyChange_t*)osal_msg_allocate(sizeof(keyChange_t));
if(msgPtr)
msgPtr->
hdr.event=KEY_CHANGE;
state=state;
keys=keys;
osal_msg_send(registeredKeysTaskID,(uint8*)msgPtr);
return(SUCCESS);
return(FAILURE);
主要是将按键时间,状态和按键值打包到信息中最后通过
发送到注册了按键服务的应用层去
,最终用户按了哪个按键,如何响应该按键在系统事件SYS_EVENT_MSG中处理。
疑问又来了,为什么通过osal_msg_send收发的消息会出现在SYS_EVENT_MSG中呢?
这个疑问,就是刚才我说过的osal_msg_send(registeredKeysTaskID,(uint8*)msgPtr)会产生一个
amessage
readyeventinthedestinationtaskseventlist.
osal_msg_send
*@brief
Thisfunctioniscalledbyatasktosendacommandmessageto
anothertaskorprocessingelement.
Thesending_taskfieldmust
refertoavalidtask,sincethetaskIDwillbeused
fortheresponsemessage.
Thisfunctionwillalsosetamessage
readyeventinthedestinationtaskseventlist.
uint8destination_task-SendmsgtoTaskID
uint8*msg_ptr-pointertonewmessagebuffer
SUCCESS,INVALID_TASK,INVALID_MSG_POINTER
uint8osal_msg_send(uint8destination_task,uint8*msg_ptr)
return(osal_msg_enqueue_push(destination_task,msg_ptr,FALSE));
simpleBLEPeripheral_ProcessOSALMsg
Processanincomingtaskmessage.
pMsg-messagetoprocess
staticvoidsimpleBLEPeripheral_ProcessOSALMsg(osal_event_hdr_t*pMsg)
switch(pMsg->
event)
#ifdefined(CC2540_MINIDK)
caseKEY_CHANGE:
//按键处理事件,用户产生的按键都是在这里处理
simpleBLEPeripheral_HandleKeys(((keyChange_t*)pMsg)->
state,((keyChange_t*)pMsg)->
keys);
break;
#endif//#ifdefined(CC2540_MINIDK)
default:
//donothing
break;
在SimpleBLEPeripheral中,对按键的响应如下:
joystickright(SW2)收发广播的开启和关闭
simpleBL