DA14580 --- 基本流程分析

1.目的

     识别什么是主动扫描 什么是被动扫描

2.分析


3.平台:

协议栈版本:DA1458x_SDK

编译软件:keil 4.72

硬件平台:开发板

例子:DA1458x_SDK5.0.3\DA1458x_SDK5.0.3\DA1458x_SDK\5.0.3\projects\target_apps\ble_examples\prox_reporter\Keil_4

4.步骤

  先看主函数 


int main_func(void)
{
    sleep_mode_t sleep_mode;
    bool flag = 0; 
    //global initialise
    system_init(); //系统初始化函数

    /*
     ************************************************************************************
     * Platform initialization
     ************************************************************************************
     */
	// start_custom_task();
  	//app_proxr_alert_start(100);	
    while(1)  { 	
   				app_batt_set_level(0x55);
			do {
            // schedule all pending events
            schedule_while_ble_on();
        }
        while ((app_asynch_proc()));    //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);

            	//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();
        }
        
     if (USE_WDOG)
    	 wdg_reload(WATCHDOG_DEFAULT_PERIOD);
    }
}




 ****************************************************************************************
 * @brief  Global System Init
 * @return void
 ****************************************************************************************
 */
void system_init(void)
{
    sys_startup_flag = true;
    /*
     ************************************************************************************
     * Platform initialization
     ************************************************************************************
     */
    //initialise the Watchdog unit
    wdg_init(0);

    //confirm XTAL 16 MHz calibration
    xtal16_calibration_check ();

    //set the system clocks
    set_system_clocks();
    //Initiliaze the GPIOs
    GPIO_init();

    // Initialize NVDS module
    nvds_init((uint8_t *)NVDS_FLASH_ADDRESS, NVDS_FLASH_SIZE);

    // Check and read BD address
    nvds_read_bdaddr();

    //Peripherals initilization
    periph_init();

    // Initialize random process
    srand(1);

    //Trim the radio from the otp
    iq_trim_from_otp();

    /*
     ************************************************************************************
     * BLE initialization
     ************************************************************************************
     */   init_pwr_and_clk_ble();

    // Initialize BLE stack
    rwip_clear_interrupts ();

    // Initialize rw
    rwip_init(error);

    //Patch llm task
    patch_llm_task();

    //Patch gtl task    if (BLE_GTL_PATCH)
        patch_gtl_task();

    //Patch llc task
    if (BLE_MEM_LEAK_PATCH)
        patch_llc_task();

    //Enable the BLE core
    SetBits32(BLE_RWBTLECNTL_REG, RWBLE_EN, 1);

    // Initialise random number generator seed using random bits acquired from TRNG
    if (USE_TRNG)
        init_rand_seed_from_trng();

    //send a message to the host if an error occured
    if (BLE_HCIC_ITF)
        hcic_reset_message();

    rcx20_calibrate ();

    arch_disable_sleep();  
    /*
     ************************************************************************************
     * Application initializations
     ************************************************************************************
     */
    // Initialise APP
    
#if (BLE_APP_PRESENT)
        app_init();         // Initialize APP
#endif   
     if (user_app_main_loop_callbacks.app_on_init !=NULL)
          user_app_main_loop_callbacks.app_on_init();

    //Initialise lld_sleep
    lld_sleep_init_func();

    /*
     ************************************************************************************
     * XTAL16M trimming settings
     ************************************************************************************
     */
    //set trim and bias of xtal16
    xtal16__trim_init();    
     // Enable the TX_EN/RX_EN interrupts, depending on the RF mode of operation (PLL-LUT and MGC_KMODALPHA combinations)
    enable_rf_diag_irq(RF_DIAG_IRQ_MODE_RXTX); 

    /*
     ************************************************************************************
     * Watchdog
     ************************************************************************************
     */
    if(USE_WDOG)
    {
        wdg_reload(WATCHDOG_DEFAULT_PERIOD);
        wdg_resume ();
    }

#ifndef __DA14581__        
# if (BLE_CONNECTION_MAX_USER > 4)
    cs_table[0] = cs_table[0];
# endif

#else //DA14581

# if (BLE_CONNECTION_MAX_USER > 1)
    cs_table[0] = cs_table[0];
# endif
#endif //__DA14581__
    
}

这里看 app_init(void)

void app_init(void)
{
    // Reset the environment
    memset(&app_env[0], 0, sizeof(app_env));

    bool security_default_val = true;

    uint8_t length = NVDS_LEN_SECURITY_ENABLE;
    // Get the security enable from the storage
    if (nvds_get(NVDS_TAG_SECURITY_ENABLE, &length, (uint8_t *)&security_default_val) != NVDS_OK)
    {
        // Set true by default (several profiles requires security)
        security_default_val = true;
    }

    for (uint8_t i = 0; i< APP_EASY_MAX_ACTIVE_CONNECTION; i++)
    {
        // Set true by default (several profiles requires security)
        app_env[i].sec_en = true;
    }

    // Create APP task
    ke_task_create(TASK_APP, &TASK_DESC_APP);  //创建任务

    // Initialize Task state
    ke_state_set(TASK_APP, APP_DISABLED);
}

看TASK_SESC_APP的定义:

/// Application Task Descriptor
static const struct ke_task_desc TASK_DESC_APP = {NULL,
                                                  &app_default_handler,
                                                  app_state,
                                                  APP_STATE_MAX,
                                                  APP_IDX_MAX};

app_default_handler 的定义:

/* Default State handlers definition. */
const struct ke_msg_handler app_default_state[] =
{
    {KE_MSG_DEFAULT_HANDLER,                (ke_msg_func_t)app_entry_point_handler},
};

/* Specifies the message handlers that are common to all states. */
const struct ke_state_handler app_default_handler = KE_STATE_HANDLER(app_default_state);

app_entry_point_handler 的定义  有下面代码可以看到。这里是注册 app_process_handle[]数组里面定义的是 函数指针

                                        
const process_event_func_t app_process_handlers[] = {

#if (!EXCLUDE_DLG_GAP)
     (process_event_func_t) app_gap_process_handler,
#endif

#if (!EXCLUDE_DLG_TIMER)
    (process_event_func_t) app_timer_api_process_handler,
#endif

#if (!EXCLUDE_DLG_MSG)
    (process_event_func_t) app_msg_utils_api_process_handler,
#endif

#if ((BLE_APP_SEC) && (!EXCLUDE_DLG_SEC))
    (process_event_func_t) app_sec_process_handler,
#endif
#if ((BLE_DIS_SERVER) && (!EXCLUDE_DLG_DISS))
    (process_event_func_t) app_dis_process_handler,
#endif

#if ((BLE_PROX_REPORTER) && (!EXCLUDE_DLG_PROXR))
   (process_event_func_t) app_proxr_process_handler,
#endif
#if ((BLE_BAS_SERVER) && (!EXCLUDE_DLG_BASS))
    (process_event_func_t) app_bass_process_handler,
#endif

#if (((BLE_FINDME_TARGET)&& (!EXCLUDE_DLG_FINDT)) || ((BLE_FINDME_LOCATOR)&& (!EXCLUDE_FINDL)))  
    (process_event_func_t) app_findme_process_handler,
#endif //BLE_FINDME_LOCATOR

#if ((BLE_SPOTA_RECEIVER) && (!EXCLUDE_DLG_SPOTAR))
    (process_event_func_t) app_spota_process_handler,
#endif

//#if ((BLE_CUSTOM1_SERVER) && (!EXCLUDE_DLG_CUSTS1))
//    (process_event_func_t) app_custs1_process_handler,
//#endif  (process_event_func_t) app_custs1_process_handler,

};

int app_entry_point_handler (ke_msg_id_t const msgid,
                                         void const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id){
    int i=0;
    enum ke_msg_status_tag process_msg_handling_result;
    
    while (i<sizeof(app_process_handlers)/sizeof(process_event_func_t))
    {
        ASSERT_ERR(app_process_handlers[i]);
         if (app_process_handlers[i](msgid,param,dest_id,src_id, &process_msg_handling_result)==PR_EVENT_HANDLED)
               return (process_msg_handling_result);
         i++;
    }
    //user cannot do anything else than consume the message
    if (app_process_catch_rest_cb!=NULL)
    {
        app_process_catch_rest_cb(msgid,param,dest_id,src_id);
    }
    
    return (KE_MSG_CONSUMED);
    
};

上面代码是注册是注册 app_process_handle[]数组里面定义的函数。随便拿出其中一个数组的来分析 (process_event_func_t) app_gap_process_handler

/*
 * FUNCTION DEFINITIONS
 ****************************************************************************************
 */

static const struct ke_msg_handler app_gap_process_handlers[]=
{
    {GAPM_DEVICE_READY_IND,                 (ke_msg_func_t)gapm_device_ready_ind_handler},
    {GAPM_CMP_EVT,                          (ke_msg_func_t)gapm_cmp_evt_handler},
    {GAPC_CMP_EVT,                          (ke_msg_func_t)gapc_cmp_evt_handler},    {GAPC_CONNECTION_REQ_IND,               (ke_msg_func_t)gapc_connection_req_ind_handler},
    {GAPC_DISCONNECT_IND,                   (ke_msg_func_t)gapc_disconnect_ind_handler},
    {APP_MODULE_INIT_CMP_EVT,               (ke_msg_func_t)app_module_init_cmp_evt_handler},
    {GAPM_ADV_REPORT_IND,                   (ke_msg_func_t)gapm_adv_report_ind_handler},   
};
enum process_event_response app_gap_process_handler (ke_msg_id_t const msgid,
                                         void const *param,
                                         ke_task_id_t const dest_id,
                                         ke_task_id_t const src_id, 
                                         enum ke_msg_status_tag *msg_ret)
{
    return (app_std_process_event(msgid, param,src_id,dest_id,msg_ret, app_gap_process_handlers,
                                         sizeof(app_gap_process_handlers)/sizeof(struct ke_msg_handler)));
}


enum process_event_response app_std_process_event (             
                                         ke_msg_id_t const msgid,
                                         void const *param,
                                         ke_task_id_t const src_id,
                                         ke_task_id_t const dest_id,
                                         enum ke_msg_status_tag *msg_ret,
                                         const struct ke_msg_handler *handlers,
                                         const int handler_num)
{
    ke_msg_func_t func = NULL;
    func = handler_search(msgid, handlers, handler_num );
    
    if (func != NULL)
    {
        (*msg_ret) = (enum ke_msg_status_tag) func(msgid, param, dest_id, src_id);
        return (PR_EVENT_HANDLED);
    }
    else
        return (PR_EVENT_UNHANDLED);
        
};


上面是app_gap_process_handler函数注册app_gap_process_handlers数组里面的函数。每个函数都一个ID 和一个回调函数。其他的函数注册远离一样。。

这样注册了 可以用

void ke_timer_set(ke_msg_id_t const timer_id, ke_task_id_t const task, uint32_t delay);;来启动对应的事件

void ke_timer_clear(ke_msg_id_t const timerid, ke_task_id_t const task);//来停止事件


//还不知道怎么注册蓝牙服务的、、、

2在user_callback_config.h里面

.再看 user_app_callbacks 结构体,里面是对应蓝牙协议栈对应的回调函数,比如。

 蓝牙开始广播 则:回调default_app_on_db_init_complete函数

蓝牙连上了回调:default_app_on_connection

蓝牙断开回调:default_app_on_disconnect等等

但是.但是 但是 还知道在哪里注册这些东西的。

static const struct app_callbacks user_app_callbacks = {
    .app_on_connection              = default_app_on_connection,
    .app_on_disconnect              = default_app_on_disconnect,
    .app_on_update_params_rejected  = NULL,
    .app_on_update_params_complete  = NULL,
    .app_on_set_dev_config_complete = default_app_on_set_dev_config_complete,
    .app_on_adv_undirect_complete   = app_advertise_complete,
    .app_on_adv_direct_complete     = NULL,
    .app_on_db_init_complete        = default_app_on_db_init_complete,
    .app_on_scanning_completed      = NULL,
    .app_on_adv_report_ind          = NULL,                                                                                              .app_on_pairing_request         = default_app_on_pairing_request,
    .app_on_tk_exch_nomitm          = default_app_on_tk_exch_nomitm,
    .app_on_irk_exch                = NULL,
    .app_on_csrk_exch               = default_app_on_csrk_exch,
    .app_on_ltk_exch                = default_app_on_ltk_exch,
    .app_on_pairing_succeded        = NULL,
    .app_on_encrypt_ind             = NULL,
    .app_on_mitm_passcode_req       = NULL,
    .app_on_encrypt_req_ind         = default_app_on_encrypt_req_ind,
};

当蓝牙广播的时候回调

void default_app_on_db_init_complete( void )
{
    EXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);
    return;  
}

然后如下

/**
 ****************************************************************************************
 * @brief Structure containing the operations used by the default handlers.
 * @return void
 ****************************************************************************************
 */
struct default_app_operations {
    void (*default_operation_adv)(void);
};

再看default_operation_adv的地址,最终调用default_advertise_operation函数

// Default Handler Operations
static const struct default_app_operations user_default_app_operations = {
    .default_operation_adv = default_advertise_operation,
};

/**
 ****************************************************************************************
 * @brief The advertise operation used by the rest of default handlers.
 * @return None.
 ****************************************************************************************
 */
void default_advertise_operation(void)
{
        if (user_default_hnd_conf.adv_scenario==DEF_ADV_FOREVER)
            app_easy_gap_undirected_advertise_start();
        else if (user_default_hnd_conf.adv_scenario==DEF_ADV_WITH_TIMEOUT)
            app_easy_gap_undirected_advertise_with_timeout_start(user_default_hnd_conf.advertise_period,NULL);
}

因为我们定义的是 DEF_ADV_FOREVER所以 跳到这里然后开始广播

void app_easy_gap_undirected_advertise_start(void)
{
    struct gapm_start_advertise_cmd* cmd;
    cmd = app_easy_gap_undirected_advertise_start_create_msg();

    // Send the message
    app_advertise_start_msg_send(cmd);
    adv_cmd=NULL ;

    // We are now connectable
    ke_state_set(TASK_APP, APP_CONNECTABLE);

}


3.看下蓝牙连上的时候的回调

void default_app_on_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param)
{
    if (app_env[connection_idx].conidx != GAP_INVALID_CONIDX)
    {

        if (user_default_hnd_conf.adv_scenario==DEF_ADV_WITH_TIMEOUT)
            app_easy_gap_advertise_with_timeout_stop( );
        
        default_advertise_stop_operation();

        app_prf_enable (param->conhdl);
        if ((user_default_hnd_conf.security_request_scenario==DEF_SEC_REQ_ON_CONNECT) && (BLE_APP_SEC))
        {
             app_easy_security_request(connection_idx);
        }
    }
    else
    {
        // No connection has been establish, restart advertising
        EXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);
    }
    
    return;

}

这里主要看 app_prf_enable (param->conhdl);

void app_prf_enable (uint16_t conhdl)
 {
     uint8_t i=0;

     while( user_prf_funcs[i].task_id != TASK_NONE )
     {
        if( user_prf_funcs[i].enable_func != NULL )
        {
            user_prf_funcs[i++].enable_func(conhdl);         
        }
            else i++;
     }
     
     i=0;   
        /*--------------------------------------------------------------
        * ENABLE REQUIRED PROFILES
        *-------------------------------------------------------------*/
        while( prf_funcs[i].task_id != TASK_NONE )
        {
            if(( prf_funcs[i].enable_func != NULL ) && (!app_task_in_user_app(prf_funcs[i].task_id)))
            {
                prf_funcs[i++].enable_func(conhdl);         
            }
            else i++;
        }
        
        i=0;
#if BLE_CUSTOM_SERVER      while( cust_prf_funcs[i].task_id != TASK_NONE )
        {
            if( cust_prf_funcs[i].enable_func != NULL )
            {
                cust_prf_funcs[i++].enable_func(conhdl);         
            }
            else i++; 
        }
#endif
}
这里主要是注册服务的初始化事件 ,看prf_funcs[]数组 如下

const struct prf_func_callbacks prf_funcs[] =
{
    #if BLE_PROX_REPORTER
    {TASK_PROXR,     app_proxr_create_db, app_proxr_enable},
    #endif
    
    #if BLE_BAS_SERVER
    {TASK_BASS,      app_bass_create_db, app_bass_enable},
    #endif
    
    #if BLE_FINDME_TARGET   {TASK_FINDT,     NULL, app_findt_enable},
    #endif
    
    #if BLE_FINDME_LOCATOR
    {TASK_FINDL,     NULL, app_findl_enable},
    #endif
    
    #if BLE_DIS_SERVER
    {TASK_DISS,      app_diss_create_db, app_diss_enable},
    #endif
    
    #if BLE_SPOTA_RECEIVER
    {TASK_SPOTAR,    app_spotar_create_db, app_spotar_enable},
    #endif
    
    {TASK_NONE,    NULL, NULL},   // DO NOT MOVE. Mast always be last
};
以BLE_BAS_SERVER服务来分析。连上蓝牙就启动app_bass_enable启动电池采集事件。。









©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值