系统启动以后, 调用tmc_define_tasks()创建AMSS所需要的各个Task,其中包括ui_task,它起到了一个中间层的作用,即所有AMSS底层服务组件的消息,都将经由ui_task而转到AEE,并最终转到具体的App(Applet)的执行代码里面(HandleEvent())。在UI_init中会调用ui_key_init()注册上层UI对于底层按键(包括一些自定义的事件,比如耳机插拔,充电器插拔,HOOK检测等等)的回调函数。
void ui_key_init( void )
{
(void) kpd_sub_srvc(ui_kpd_sub_cb);
if (ui_kpd_handle.status == HS_SUBSCRIBED)
{
//这里注册keypad的回调函数
(void) kpd_reg_key_event(ui_kpd_handle, ui_key_event_cb);
}
}
这里注册回调函数的过程其实很简单,就是把处理按键事件(或自定义事件)的回调函数ui_key_event_cb的指针赋值给一个全局变量keypad_event_cb :
if ( keypad_event_cb ) return(FALSE);
keypad_event_cb = cb; //cb 为ui_key_event_cb的函数指针
之后系统在扫描键盘发现有键按下,或则检测到自定义的事件发生(耳机,充电器,USB插拔等)就会调用 keypad_pass_key_code( )来向上层UI报告,在这里就实现了函数的回调。
void keypad_pass_key_code( byte key_code, byte key_parm )
{
if ( keypad_event_cb )
{
keypad_key_event_type key_event; //记录按键或自定义事件的键值
key_event.key_code = key_code;
key_event.key_parm = key_parm;
keypad_event_cb ( key_event ); //利用保存回调函数地址的全局变量,实现函数回调
}
}
最后,我们回头来看看回调函数里面做了什么:
void ui_key_event_cb( keypad_key_event_type key_event )
{
word isave;
INTLOCK_SAV( isave ); /* Disable interrupts and save PSW */
if (((ui_key_buffer.wr_idx + 1) & UI_KEY_BUF_MASK) != ui_key_buffer.rd_idx)
{
//把key放在buffer里,等待被读取
ui_key_buffer.data[ui_key_buffer.wr_idx] = key_event.key_code;
ui_key_buffer.key_parm[ui_key_buffer.wr_idx] = key_event.key_parm;
ui_key_buffer.wr_idx = (ui_key_buffer.wr_idx+1) & UI_KEY_BUF_MASK;
}
INTFREE_SAV( isave ); /* Restore interrupts (PSW) */
(void) rex_set_sigs( &ui_tcb, UI_KEY_SIG ); //向ui_task发送消息
}
ui_task在接收到回调函数发送的UI_KEY_SIG消息后就会,就会调用handle_keys把buffer中的物理键值转化成逻辑键值传递给App。
AEE_Event( EVT_KEY_PRESS, last_vcode, dwparam );
AEE_Event( EVT_KEY, last_vcode, dwparam );
AEE_Event( EVT_KEY_RELEASE, last_vcode, dwparam );