启动过程完成后立即进入main_func函数。该函数在进入主循环while(1)之前,只调用了system_init()函数。system_init()函数里面包含了对看门狗、时钟、外设、检查和读取蓝牙物理地址、BLE的初始化等等。BLE初始化部分具体包含init_pwr_and_clk_ble()、rwip_clear_interrupts ()、rwip_init()等。这些函数是固化代码,不对开发者开放。从官方SDK看,尽管BLE协议栈非常庞大,但是BLE的main函数却是非常简单的,不算注释,代码总共只有短短30来行。
int main_func(void)
{
sleep_mode_t sleep_mode;//睡眠模式变量,枚举型
//global initialise
system_init();
/*
************************************************************************************
* Platform initialization
************************************************************************************
*/
while(1)
{
do {
// schedule all pending events
schedule_while_ble_on();
}
while (app_asynch_proc() != GOTO_SLEEP); //grant control to the application, try to go to power down
//if the application returns GOTO_SLEEP
//((STREAMDATA_QUEUE)&& stream_queue_more_data())); //grant control to the streamer, try to go to power down
//if the application returns GOTO_SLEEP
//wait for interrupt and go to sleep if this is allowed
if (((!BLE_APP_PRESENT) && (check_gtl_state())) || (BLE_APP_PRESENT))
{
//Disable the interrupts
GLOBAL_INT_STOP();
app_asynch_sleep_proc();
// get the allowed sleep mode
// time from rwip_power_down() to WFI() must be kept as short as possible!!
sleep_mode = rwip_power_down();
if ((sleep_mode == mode_ext_sleep) || (sleep_mode == mode_deep_sleep))
{
//power down the radio and whatever is allowed
arch_goto_sleep(sleep_mode);
// In extended or deep sleep mode the watchdog timer is disabled
// (power domain PD_SYS is automatically OFF). Although, if the debugger
// is attached the watchdog timer remains enabled and must be explicitly
// disabled.
if ((GetWord16(SYS_STAT_REG) & DBG_IS_UP) == DBG_IS_UP)
{
wdg_freeze(); // Stop watchdog timer
}
//wait for an interrupt to resume operation
WFI();
//resume operation
arch_resume_from_sleep();
}
else if (sleep_mode == mode_idle)
{
if (((!BLE_APP_PRESENT) && check_gtl_state()) || (BLE_APP_PRESENT))
{
//wait for an interrupt to resume operation
WFI();
}
}
// restore interrupts
GLOBAL_INT_START();
}
wdg_reload(WATCHDOG_DEFAULT_PERIOD);
}
}
GAP(Generic Access Profile)通用访问规范层算是BLE协议栈中最顶部的一层,它定义了设备如何广播、扫描、发现和建立连接,以及配置工作角色(Role)、可发现性、广播数据内容和安全相关的参数。
GAP 就绪后,会产生GAP_READY_EVT 消息,该消息会回调gapm_device_ready_ind_handler函数。函数原型如下:
/**
****************************************************************************************
* @brief Handles ready indication from the GAP. - Reset the stack.
* @param[in] msgid Id of the message received.
* @param[in] param Pointer to the parameters of the message.
* @param[in] dest_id ID of the receiving task instance (TASK_GAP).
* @param[in] src_id ID of the sending task instance.
* @return If the message was consumed or not.
****************************************************************************************
*/
static int gapm_device_ready_ind_handler(ke_msg_id_t const msgid,
void const *param,
ke_task_id_t const dest_id,
ke_task_id_t const src_id)
{
if (ke_state_get(dest_id) == APP_DISABLED)//如果TASK_GAP处于APP_DISABLED状态,与if(APP_DISABLED == ke_state_get(TASK_APP)等效
{
// reset the lower layers.
app_gapm_reset_op();//创建并发送一个重置GAP的消息
}
else
{
// APP_DISABLED state is used to wait the GAP_READY_EVT message
ASSERT_ERR(0);//如果不是APP_DISABLED状态,将会触发重启
}
return (KE_MSG_CONSUMED);//返回该消息已经处理
}
该函数判断TASK_GAP如果处于APP_DISABLED状态,就会产生和发送一个GAP 重置堆栈的消息。如果不是APP_DISABLED状态,将会触发重启。判断状态使用了内核提供的ke_state_get()函数。APP task的状态是枚举型,APP_DISABLED是初始的重置状态。APP_DISABLED 状态用于等待 GAP_READY_EVT消息。
APP task有6种状态,具体定义如下:
/*
* ENUMERATIONS
****************************************************************************************
*/
/// States of APP task
enum APP_STATE
{
/// Disabled State
APP_DISABLED,
/// Database Initialization State
APP_DB_INIT,
/// Connectable state
APP_CONNECTABLE,
/**
* CONNECTED STATES
*/
/// Security state,
APP_SECURITY,
/// Connection Parameter Update State
APP_PARAM_UPD,
/// Connected state
APP_CONNECTED,
/// Number of defined states.
APP_STATE_MAX
};
app_gapm_reset_op()函数创建并发送一个重置GAP的消息,其原型如下:
**************

最低0.47元/天 解锁文章
4349

被折叠的 条评论
为什么被折叠?



