当前位置: 首页 > news >正文

以投资思维做网站/百度网址大全 官网首页

以投资思维做网站,百度网址大全 官网首页,海口建设,东莞凤岗房价启动过程完成后立即进入main_func函数。该函数在进入主循环while(1)之前,只调用了system_init()函数。system_init()函数里面包含了对看门狗、时钟、外设、检查和读取蓝牙物理地址、BLE的初始化等等。BLE初始化部分具体包含init_pwr_and_clk_…

启动过程完成后立即进入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 initialisesystem_init();/************************************************************************************** Platform initialization*************************************************************************************/while(1){do {// schedule all pending eventsschedule_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 allowedif (((!BLE_APP_PRESENT) && (check_gtl_state())) || (BLE_APP_PRESENT)){//Disable the interruptsGLOBAL_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 allowedarch_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 operationWFI();//resume operationarch_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 operationWFI();}}// restore interruptsGLOBAL_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 messageASSERT_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 StateAPP_DISABLED,/// Database Initialization StateAPP_DB_INIT,/// Connectable stateAPP_CONNECTABLE,/*** CONNECTED STATES*//// Security state,APP_SECURITY,/// Connection Parameter Update StateAPP_PARAM_UPD,/// Connected stateAPP_CONNECTED,/// Number of defined states.APP_STATE_MAX
};

app_gapm_reset_op()函数创建并发送一个重置GAP的消息,其原型如下:

 ***************************************************************************************** @brief Send a gap manager reset operation.* @return void*****************************************************************************************/
__INLINE void app_gapm_reset_op (void)
{struct gapm_reset_cmd* cmd = app_gapm_reset_msg_create();//生成消息app_gapm_reset_msg_send(cmd);//发送消息
}

重置GAP操作完成后,会产生一个GAPM_CMP_EVT消息,该消息触发回调函数gapm_cmp_evt_handler()。在这个函数里,对GAPM_RESET、GAPM_SET_DEV_CONFIG、GAPM_ADV_NON_CONN、GAPM_ADV_UNDIRECT、GAPM_ADV_DIRECT、GAPM_SCAN_ACTIVE、GAPM_SCAN_PASSIVE、GAPM_CONNECTION_DIRECT、GAPM_CANCEL等各种操作完成的消息进行分类处理。

/******************************************************************************************* @brief Handles GAP manager command complete events.* @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_cmp_evt_handler(ke_msg_id_t const msgid,struct gapm_cmp_evt const *param,ke_task_id_t const dest_id,ke_task_id_t const src_id)
{switch(param->operation){// reset completedcase GAPM_RESET:{if(param->status != GAP_ERR_NO_ERROR){ASSERT_ERR(0); // unexpected error}else{// set device configurationapp_easy_gap_dev_configure ();}}break;// device configuration updatedcase GAPM_SET_DEV_CONFIG:{if(param->status != GAP_ERR_NO_ERROR){ASSERT_ERR(0); // unexpected error}else{EXECUTE_CALLBACK_VOID(app_on_set_dev_config_complete);}}break;// Non connectable advertising finishedcase GAPM_ADV_NON_CONN:{EXECUTE_CALLBACK_PARAM(app_on_adv_nonconn_complete, param->status);}break;// Undirected connectable advertising finishedcase GAPM_ADV_UNDIRECT:{EXECUTE_CALLBACK_PARAM(app_on_adv_undirect_complete, param->status);}break;// Directed connectable advertising finishedcase GAPM_ADV_DIRECT:{EXECUTE_CALLBACK_PARAM(app_on_adv_direct_complete, param->status);}break;case GAPM_SCAN_ACTIVE:case GAPM_SCAN_PASSIVE:{EXECUTE_CALLBACK_PARAM(app_on_scanning_completed, param->status);}break;case GAPM_CONNECTION_DIRECT:if (param->status == GAP_ERR_CANCELED){EXECUTE_CALLBACK_VOID(app_on_connect_failed);}break;case GAPM_CANCEL:{if(param->status != GAP_ERR_NO_ERROR){ASSERT_ERR(0); // unexpected error}if (app_process_catch_rest_cb != NULL){app_process_catch_rest_cb(msgid, param, dest_id, src_id);}}break;default:if (app_process_catch_rest_cb != NULL){app_process_catch_rest_cb(msgid, param, dest_id, src_id);}break;}return (KE_MSG_CONSUMED);
}

gapm_cmp_evt_handler函数判断消息是GAPM_RESET完成后,会调用app_easy_gap_dev_configure (),来配置GAP参数。dev_configure就是device configuration的缩写。同样,该函数并不是自己去配置GAP,而是产生一个配置GAP的消息并发送出去。函数原型如下:

void app_easy_gap_dev_configure(void)
{struct gapm_set_dev_config_cmd* cmd = app_easy_gap_dev_config_create_msg();app_gapm_configure_msg_send(cmd);set_dev_config_cmd = NULL;
}

GAP配置完成后,会再次产一个GAPM_CMP_EVT消息,该消息的内容则是GAPM_SET_DEV_CONFIG完成,然后会再次触发gapm_cmp_evt_handler函数处理,具体调用EXECUTE_CALLBACK_VOID(app_on_set_dev_config_complete);函数,void (*app_on_set_dev_config_complete)(void)函数时APP回调函数结构体的一个成员。该结构体如下:

struct app_callbacks
{void (*app_on_connection)(const uint8_t, struct gapc_connection_req_ind const *);void (*app_on_disconnect)(struct gapc_disconnect_ind const *);void (*app_on_update_params_rejected)(const uint8_t);void (*app_on_update_params_complete)(void);void (*app_on_set_dev_config_complete)(void);void (*app_on_adv_nonconn_complete)(const uint8_t);void (*app_on_adv_undirect_complete)(const uint8_t);void (*app_on_adv_direct_complete)(const uint8_t);void (*app_on_db_init_complete)(void);void (*app_on_scanning_completed)(const uint8_t);void (*app_on_adv_report_ind)(struct gapm_adv_report_ind const *);void (*app_on_connect_failed)(void);
#if (BLE_APP_SEC)void (*app_on_pairing_request)(const uint8_t, struct gapc_bond_req_ind const *);void (*app_on_tk_exch_nomitm)(const uint8_t, struct gapc_bond_req_ind const *);void (*app_on_irk_exch)(struct gapc_bond_req_ind const *);void (*app_on_csrk_exch)(const uint8_t, struct gapc_bond_req_ind const *);void (*app_on_ltk_exch)(const uint8_t, struct gapc_bond_req_ind const *);void (*app_on_pairing_succeded)(void);void (*app_on_encrypt_ind)(const uint8_t);void (*app_on_mitm_passcode_req)(const uint8_t);void (*app_on_encrypt_req_ind)(const uint8_t, struct gapc_encrypt_req_ind const *);void (*app_on_security_req_ind)(const uint8_t);
#endif
};

在user_callback_config.h文件里,定义了app_on_set_dev_config_complete = default_app_on_set_dev_config_complete。

static const struct app_callbacks user_app_callbacks = {.app_on_connection              = user_app_connection,.app_on_disconnect              = user_app_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_nonconn_complete    = NULL,.app_on_adv_undirect_complete   = user_app_adv_undirect_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,
#if (BLE_APP_SEC).app_on_pairing_request         = NULL,.app_on_tk_exch_nomitm          = NULL,.app_on_irk_exch                = NULL,.app_on_csrk_exch               = NULL,.app_on_ltk_exch                = NULL,.app_on_pairing_succeded        = NULL,.app_on_encrypt_ind             = NULL,.app_on_mitm_passcode_req       = NULL,.app_on_encrypt_req_ind         = NULL,.app_on_security_req_ind        = NULL,
#endif // (BLE_APP_SEC)
};

default_app_on_set_dev_config_complete()函数的原型如下,该回调函数里调用了app_db_init_start()函数。

void default_app_on_set_dev_config_complete( void )
{// Add the first required service in the databaseif (app_db_init_start()){// No service to add in the DB -> Start AdvertisingEXECUTE_DEFAULT_OPERATION_VOID(default_operation_adv);}
}

app_db_init_start()函数先调用内核ke_state_set()函数,把APP task的状态从APP_DISABLED转换到APP_DB_INIT状态,也就是Database Initialization State。然后调用app_db_init_next(void)函数,为所有包含的配置文件初始化数据库。

bool app_db_init_start(void)
{// Indicate if more services need to be added in the databasebool end_db_create = false;// We are now in Initialization Stateke_state_set(TASK_APP, APP_DB_INIT);end_db_create = app_db_init_next();return end_db_create;
}/******************************************************************************************* @brief Initialize the database for all the included profiles.* @return true if succeeded, else false*****************************************************************************************/
static bool app_db_init_next(void)
{static uint8_t i __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY;static uint8_t k __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY;// initialise the databases for all the included profileswhile( user_prf_funcs[k].task_id != TASK_NONE ){if ( user_prf_funcs[k].db_create_func != NULL ){user_prf_funcs[k++].db_create_func();return false;}else k++;}// initialise the databases for all the included profileswhile( prf_funcs[i].task_id != TASK_NONE ){if (( prf_funcs[i].db_create_func != NULL )&& (!app_task_in_user_app(prf_funcs[i].task_id)))    //case that the this task has an entry in the user_prf as well{prf_funcs[i++].db_create_func();return false;}else i++;}#if BLE_CUSTOM_SERVER{static uint8_t j __attribute__((section("retention_mem_area0"),zero_init)); //@RETENTION MEMORY;while( cust_prf_funcs[j].task_id != TASK_NONE ){if( cust_prf_funcs[j].db_create_func != NULL ){cust_prf_funcs[j++].db_create_func();return false;}else j++;}j = 0;}#endifk = 0;i = 0;return true;
}

并在app_db_init_start()完成返回1时调用default_operation_adv回调函数,该函数default_operation_adv = user_app_adv_start。

user_app_adv_start()回调函数开启广播,其原型如下,先是调用了app_easy_timer()开启定时任务,然后调用app_easy_gap_undirected_advertise_get_active(),为可连接的无向事件(ADV_IND)创建广告消息, 然后调用mnf_data_update()加载制造商信息,然后使用app_add_ad_struct()函数加载广播或者扫描回复的具体信息,该信息在GAP开始广播命令结构体gapm_start_advertise_cmd定义。

void user_app_adv_start(void)
{// Schedule the next advertising data updateapp_adv_data_update_timer_used = app_easy_timer(APP_ADV_DATA_UPDATE_TO, adv_data_update_timer_cb);struct gapm_start_advertise_cmd* cmd;cmd = app_easy_gap_undirected_advertise_get_active();// add manufacturer specific data dynamicallymnf_data_update();app_add_ad_struct(cmd, &mnf_data, sizeof(struct mnf_specific_data_ad_structure));app_easy_gap_undirected_advertise_start();
}/// Set advertising mode Command
struct gapm_start_advertise_cmd
{/// GAPM requested operation:/// - GAPM_ADV_NON_CONN: Start non connectable advertising 启动不可连接的广播/// - GAPM_ADV_UNDIRECT: Start undirected connectable advertising 启动无定向可连接的广播/// - GAPM_ADV_DIRECT: Start directed connectable advertising启动定向连接广播/// - GAPM_ADV_DIRECT_LDC: Start directed connectable advertising using Low Duty Cycle 使用低占空比的定向连接广播struct gapm_air_operation op;/// Minimum interval for advertising  广播最小时间间隔uint16_t             intv_min; /// Maximum interval for advertising 广播最大时间间隔uint16_t             intv_max;  ///Advertising channel map  广播通道mapuint8_t              channel_map; /// Advertising information 广播的信息union gapm_adv_info{/// Host information advertising data (GAPM_ADV_NON_CONN and GAPM_ADV_UNDIRECT) 主机信息广播数据struct gapm_adv_host host;///  Direct address information (GAPM_ADV_DIRECT) 直接地址信息/// (used only if reconnection address isn't set or host privacy is disabled) 仅在未设置重连接地址或禁用主机隐私时使用struct gap_bdaddr direct;} info;
};

在gapm_start_advertise_cmd结构体下,还包含一个gapm_air_operation结构体和一个gapm_adv_info联合体。

/// Air operation default parameters 空中默认参数
struct gapm_air_operation
{/// Operation code.操作码uint8_t code;/*** Own BD address source of the device: 设备自身的BD地址源:* - GAPM_STATIC_ADDR: Public or Random Static Address according to device address configuration* - GAPM_GEN_RSLV_ADDR: Generated Random Resolvable Private Address* - GAPM_GEN_NON_RSLV_ADDR: Generated Random non-Resolvable Private Address*/uint8_t addr_src;/// Dummy data use to retrieve internal operation state (should be set to 0).//虚拟数据用于检索内部操作状态(应设置为0)。uint16_t state;
};

gapm_adv_info联合体包含2个结构体:gapm_adv_host host、gap_bdaddr direct。

/// Advertising data that contains information set by host.包含由主机设置的信息的广告数据。
struct gapm_adv_host
{/// Advertising mode : 广播模式/// - GAP_NON_DISCOVERABLE: Non discoverable mode 不可发现模式/// - GAP_GEN_DISCOVERABLE: General discoverable mode 常规可发现模式/// - GAP_LIM_DISCOVERABLE: Limited discoverable mode 受限的可发现模式/// - GAP_BROADCASTER_MODE: Broadcaster mode 广播模式uint8_t              mode;/// Advertising filter policy:/// - ADV_ALLOW_SCAN_ANY_CON_ANY: Allow both scan and connection requests from anyone/// - ADV_ALLOW_SCAN_WLST_CON_ANY: Allow both scan req from White List devices only and///   connection req from anyone/// - ADV_ALLOW_SCAN_ANY_CON_WLST: Allow both scan req from anyone and connection req///   from White List devices only/// - ADV_ALLOW_SCAN_WLST_CON_WLST: Allow scan and connection requests from White List///   devices onlyuint8_t              adv_filt_policy;/// Advertising data length - maximum 28 bytes, 3 bytes are reserved to set/// Advertising AD type flags, shall not be set in advertising datauint8_t              adv_data_len;/// Advertising datauint8_t              adv_data[ADV_DATA_LEN];/// Scan response data length- maximum 31 bytesuint8_t              scan_rsp_data_len;/// Scan response datauint8_t              scan_rsp_data[SCAN_RSP_DATA_LEN];/// Peer Info - bdaddrstruct gap_bdaddr peer_info;
};/// Address information about a device address
struct gap_bdaddr
{/// BD Address of device蓝牙设备48bit物理地址struct bd_addr addr;/// Address type of the device 0=public/1=private randomuint8_t addr_type;
};

所有广播信息准备完成后,调用app_easy_gap_undirected_advertise_start()函数,该函数负责产生一个开始广播的消息并发送出去。具体是通过app_easy_gap_undirected_advertise_start_create_msg()和app_advertise_start_msg_send()函数完成。消息发送完成后,调用了内核的状态切换函数ke_state_set(),把TASK_APP状态更改为 APP_CONNECTABLE状态。函数原型如下:

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 messageapp_advertise_start_msg_send(cmd);adv_cmd = NULL ;// We are now connectableke_state_set(TASK_APP, APP_CONNECTABLE);
}

状态切换完成后,BLE已经开始定时广播了,可以使用手机搜索到该蓝牙的存在,这就是蓝牙BLE协议栈的整个启动过程。

以上内容有点多,但是逻辑时序是很清晰的。期间APP task总共切换了三次状态,从Disabled State( APP_DISABLED)到Database Initialization State(APP_DB_INIT)数据库初始状态,然后到Connectable state( APP_CONNECTABLE)可连接状态,该状态下蓝牙发射机在定时对外广播。

http://www.jmfq.cn/news/4845457.html

相关文章:

  • 网站 开发/网站搭建软件
  • 娄底市住房和城乡建设局网站/培训班招生方案有哪些
  • 网站开发找哪家/十八大禁用黄app入口
  • 资中网站建设/什么叫软文推广
  • dedecms更改网站logo/网络广告的优势有哪些
  • 网站里的活动专题栏怎么做/百度山西授权代理
  • 长春怎样建网站?/适合seo的网站
  • 建设专业网站/什么是网络推广营销
  • 做网站凡科如何/百度搜索引擎的网址
  • 如何将自己做的网站/软文平台发布
  • 做医疗网站要几个人/网络营销案例ppt课件
  • wordpress连接谷歌地图/游戏优化大师官方下载
  • 手机网站建设代理商/做网站哪个平台好
  • 东营建设信息网官网查询/优化推广关键词
  • 网站开发做什么的/中国人民银行网站
  • 自学做动态网站/推广优化网站排名教程
  • 网站开发和设计如何合作/微信营销推广软件
  • 阜阳网站建设价格低/如何建立独立网站
  • 免费网站使用/免费观看b站的广告网站平台
  • 自己电脑做网站要下载/西点培训前十名学校
  • 合肥做网站的公司有哪些/如何建立网上销售平台
  • 跨境电商平台培训哪家最正规/企业网站排名优化公司
  • 营销技巧的重要性/seo公司后付费
  • 公司网站建设技术方案/seo营销论文
  • 怎样做旅游城市住宿网站/中国营销网站
  • 长沙做营销型网站公司/一个新产品怎么推广
  • 公司做了网站怎么做推广/企业seo案例
  • 怎么做苹果手机网站/百度公司的发展历程
  • 衡水提供网站设计公司哪家专业/百度网站建设
  • 如何建设大型电子商务网站/建站公司哪家好