初始化流程包括:
该函数是应用的入口,系统通常执行正常模式
/******************************************************************
* @brief main() is a start of main codes.
* @param none
* @retval 0
*/
int main(void)
{
#if FEAUTRE_SUPPORT_FLASH_2_BIT_MODE
if (FLASH_SUCCESS == flash_try_high_speed(FLASH_MODE_2BIT))
{
APP_PRINT_INFO0("Switch to 2-Bit flash mode");
}
#endif
extern uint32_t random_seed_value;
srand(random_seed_value);
global_data_init();/* check test mode */
app_global_data.test_mode = get_test_mode();
reset_test_mode();APP_PRINT_INFO1("Test Mode is %d", app_global_data.test_mode);
switch (app_global_data.test_mode)
{
case NOT_TEST_MODE:
{
APP_PRINT_INFO0("RCU is in NOT_TEST_MODE");
#if (MP_TEST_MODE_TRIG_SEL & MP_TEST_MODE_TRIG_BY_GPIO)
mp_test_check_trig_gpio_status();
#endif
app_normal_power_on_seq();
}
break;#if MP_TEST_MODE_SUPPORT_SINGLE_TONE_TEST
case SINGLE_TONE_MODE:
{
APP_PRINT_INFO0("RCU is in SINGLE_TONE_MODE");
WDG_Disable(); /* Avoid unexpected reboot */
single_tone_init();
}
break;
#endif#if MP_TEST_MODE_SUPPORT_FAST_PAIR_TEST
case AUTO_PAIR_WITH_FIX_ADDR_MODE:
{
APP_PRINT_INFO0("RCU is in AUTO_PAIR_WITH_FIX_ADDR_MODE");
mp_test_load_fp_mac_addr();
app_normal_power_on_seq();
}
break;
#endif#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
case DATA_UART_TEST_MODE:
{
APP_PRINT_INFO0("RCU is in DATA_UART_TEST_MODE");
app_normal_power_on_seq();
}
break;
#endifdefault:
break;
}os_sched_start();
return 0;
}
/******************************************************************
* @brief app_normal_power_on_seq() contains the app normal power on sequence.
* @param none
* @return none
* @retval void
*/
void app_normal_power_on_seq(void)
{
board_init();
driver_init();
le_gap_init(1);
rcu_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
sw_timer_init();
task_init();
}
NOTE:正常开机流程
/******************************************************************
* @brief Board_Init() contains the initialization of pinmux settings and pad settings.
*
* All the pinmux settings and pad settings shall be initiated in this function.
* But if legacy driver is used, the initialization of pinmux setting and pad setting
* should be peformed with the IO initializing.
* @param none
* @return none
* @retval void
*/
void board_init(void)
{
app_pinmux_config();
app_pad_config();
}
/******************************************************************
* @brief app_pinmux_config() contains the initialization of app pinmux config.
* @param none
* @return none
* @retval void
*/
void app_pinmux_config(void)
{
/*only when in normal mode and fast pair mode, keyscan can be config*/
if ((app_global_data.test_mode == NOT_TEST_MODE)
|| (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
{
keyscan_pinmux_config();
}
}
/******************************************************************
* @brief app_pad_config() contains the initialization of app pad config.
* @param none
* @return none
* @retval void
*/
void app_pad_config(void)
{
/*only when in normal mode and fast pair mode, keyscan can be config*/
if ((app_global_data.test_mode == NOT_TEST_MODE)
|| (app_global_data.test_mode == AUTO_PAIR_WITH_FIX_ADDR_MODE))
{
keyscan_init_pad_config();
}
}
/******************************************************************
* @brief driver_init() contains the initialization of peripherals.
*
* Both new architecture driver and legacy driver initialization method can be used.
* @param none
* @return none
* @retval void
*/
void driver_init(void)
{
#if SUPPORT_LED_INDICATION_FEATURE
/*led module init*/
led_module_init();
#endif#if MP_TEST_MODE_SUPPORT_DATA_UART_TEST
if (app_global_data.test_mode == DATA_UART_TEST_MODE)
{
/*data uart mode uart init*/
uart_test_init();
}
#endif#if SUPPORT_BAT_DETECT_FEATURE
bat_init_driver();
#endif
}
/**
* @brief Initialize parameters of GAP.
* @param[in] link_num Initialize link number.
* @retval true Success.
* @retval false Failed because of invalid parameter.
*
* Example usage
* \code{.c}
int main(void)
{
board_init();
driver_init();
le_gap_init(1);
app_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
task_init();
os_sched_start();return 0;
}
* \endcode
*/
bool le_gap_init(uint8_t link_num);
/******************************************************************
* @brief Initialize peripheral and gap bond manager related parameters
* @param none
* @return none
* @retval void
*/
void rcu_le_gap_init(void)
{
uint8_t device_name[GAP_DEVICE_NAME_LEN] = {C_DEVICE_NAME};
uint16_t appearance = GAP_GATT_APPEARANCE_GENERIC_REMOTE_CONTROL;//advertising parameters
uint8_t adv_evt_type = GAP_ADTYPE_ADV_IND;
uint8_t adv_direct_type = GAP_REMOTE_ADDR_LE_PUBLIC;
uint8_t adv_direct_addr[GAP_BD_ADDR_LEN] = {0};
uint8_t adv_chann_map = GAP_ADVCHAN_ALL;
uint8_t adv_filter_policy = GAP_ADV_FILTER_ANY;
uint16_t adv_int_min = DEFAULT_ADVERTISING_INTERVAL_MIN;
uint16_t adv_int_max = DEFAULT_ADVERTISING_INTERVAL_MIN;//GAP Bond Manager parameters
uint8_t auth_pair_mode = GAP_PAIRING_MODE_PAIRABLE;
uint16_t auth_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
uint8_t auth_io_cap = GAP_IO_CAP_NO_INPUT_NO_OUTPUT;
uint8_t auth_oob = false;
uint8_t auth_use_fix_passkey = false;
uint32_t auth_fix_passkey = 0;
uint8_t auth_sec_req_enalbe = false;
uint16_t auth_sec_req_flags = GAP_AUTHEN_BIT_BONDING_FLAG;
uint8_t slave_init_mtu_req = true;
le_set_gap_param(GAP_PARAM_SLAVE_INIT_GATT_MTU_REQ, sizeof(slave_init_mtu_req),
&slave_init_mtu_req);//maximum MTU size default is 247//Register gap callback
le_register_app_cb(app_gap_callback);#if FEATURE_SUPPORT_PRIVACY
privacy_init(app_privacy_callback, true);
#endif//Set device name and device appearance
le_set_gap_param(GAP_PARAM_DEVICE_NAME, GAP_DEVICE_NAME_LEN, device_name);
le_set_gap_param(GAP_PARAM_APPEARANCE, sizeof(appearance), &appearance);//Set advertising parameters
le_adv_set_param(GAP_PARAM_ADV_EVENT_TYPE, sizeof(adv_evt_type), &adv_evt_type);
le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR_TYPE, sizeof(adv_direct_type), &adv_direct_type);
le_adv_set_param(GAP_PARAM_ADV_DIRECT_ADDR, sizeof(adv_direct_addr), adv_direct_addr);
le_adv_set_param(GAP_PARAM_ADV_CHANNEL_MAP, sizeof(adv_chann_map), &adv_chann_map);
le_adv_set_param(GAP_PARAM_ADV_FILTER_POLICY, sizeof(adv_filter_policy), &adv_filter_policy);
le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MIN, sizeof(adv_int_min), &adv_int_min);
le_adv_set_param(GAP_PARAM_ADV_INTERVAL_MAX, sizeof(adv_int_max), &adv_int_max);
le_adv_set_param(GAP_PARAM_ADV_DATA, sizeof(app_pairing_adv_data), app_pairing_adv_data);
le_adv_set_param(GAP_PARAM_SCAN_RSP_DATA, sizeof(app_scan_rsp_data), app_scan_rsp_data);// Setup the GAP Bond Manager
gap_set_param(GAP_PARAM_BOND_PAIRING_MODE, sizeof(auth_pair_mode), &auth_pair_mode);
gap_set_param(GAP_PARAM_BOND_AUTHEN_REQUIREMENTS_FLAGS, sizeof(auth_flags), &auth_flags);
gap_set_param(GAP_PARAM_BOND_IO_CAPABILITIES, sizeof(auth_io_cap), &auth_io_cap);
gap_set_param(GAP_PARAM_BOND_OOB_ENABLED, sizeof(auth_oob), &auth_oob);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY, sizeof(auth_fix_passkey), &auth_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_FIXED_PASSKEY_ENABLE, sizeof(auth_use_fix_passkey),
&auth_use_fix_passkey);
le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_ENABLE, sizeof(auth_sec_req_enalbe), &auth_sec_req_enalbe);
le_bond_set_param(GAP_PARAM_BOND_SEC_REQ_REQUIREMENT, sizeof(auth_sec_req_flags),
&auth_sec_req_flags);
}
/******************************************************************
* @brief Add simple profile service and register callbacks
* @param none
* @return none
* @retval void
*/
static void app_le_profile_init(void)
{
#if (SUPPORT_VOICE_FEATURE && (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW || VOICE_FLOW_SEL == RTK_GATT_VOICE_FLOW))
server_init(7);
#else
server_init(6);
#endif
app_global_data.bas_srv_id = bas_add_service((void *)app_profile_callback);
app_global_data.dis_srv_id = dis_add_service((void *)app_profile_callback);
app_global_data.hid_srv_id = hids_add_service((void *)app_profile_callback);
app_global_data.vendor_srv_id = vendor_svc_add_service((void *)app_profile_callback);
app_global_data.ota_srv_id = ota_add_service((void *)app_profile_callback);
#if SUPPORT_VOICE_FEATURE
#if (VOICE_FLOW_SEL == ATV_GOOGLE_VOICE_FLOW)
app_global_data.atvv_srv_id = atvv_add_service(app_profile_callback);
#elif (VOICE_FLOW_SEL == RTK_GATT_VOICE_FLOW)
app_global_data.voice_srv_id = voice_service_add_service(app_profile_callback);
#endif
#endif
#if SUPPORT_SILENT_OTA
app_global_data.dfu_srv_id = dfu_add_service((void *)app_profile_callback);
#endif
server_register_app_cb(app_profile_callback);
}
/******************************************************************
* @brief pwr_mgr_init() contains the setting about power mode.
* @param none
* @return none
* @retval void
*/
void pwr_mgr_init(void)
{
#if DLPS_EN
if (false == dlps_check_cb_reg(app_dlps_check_cb))
{
APP_PRINT_ERROR0("Error: dlps_check_cb_reg(app_dlps_check_cb) failed!");
}
DLPS_IORegUserDlpsEnterCb(app_enter_dlps_config);
DLPS_IORegUserDlpsExitCb(app_exit_dlps_config);
DLPS_IORegister();
lps_mode_set(LPM_DLPS_MODE);
#else
lps_mode_set(LPM_ACTIVE_MODE);
#endif
}
/******************************************************************
* @brief software timer init function
* @param none
* @return none
* @retval void
*/
void sw_timer_init(void)
{
/* adv_timer is used to stop advertising after timeout */
if (false == os_timer_create(&adv_timer, "adv_timer", 1, \
ADV_UNDIRECT_PAIRING_TIMEOUT, false, adv_timer_callback))
{
APP_PRINT_INFO0("[sw_timer_init] init adv_timer failed");
}/* pair_fail_disconn_timer is used to disconnect for pair failed */
if (false == os_timer_create(&next_state_check_timer, "pair_fail_disconn_timer", 1, \
PAIR_FAIL_DISCONN_TIMEOUT, false, next_state_timeout_timer_callback))
{
APP_PRINT_INFO0("[sw_timer_init] init pairing_exception_timer failed");
}#if FEATURE_SUPPORT_NO_ACTION_DISCONN
/* no_act_disconn_timer is used to disconnect after timeout if there is on action under connection */
if (false == os_timer_create(&no_act_disconn_timer, "no_act_disconn_timer", 1, \
NO_ACTION_DISCON_TIMEOUT, false, no_act_disconn_timer_callback))
{
APP_PRINT_INFO0("[sw_timer_init] init no_act_disconn_timer failed");
}
#endif#if (AON_WDG_ENABLE == 1)
if (false == os_timer_create(&aon_watch_dog_wake_up_dlps_timer, "aon_watch_dog_wake_up_dlps_timer",
1, \
AON_WDG_TIMER_WAKEUP_DLPS_PERIOD, true, aon_watch_dog_wake_up_dlps_callback))
{
APP_PRINT_INFO0("[sw_timer_init] init aon_watch_dog_wake_up_dlps_callback failed");
}
else
{
os_timer_start(&aon_watch_dog_wake_up_dlps_timer);
APP_PRINT_INFO0("Start aon_watch_dog_wake_up_dlps_callback!");
}
#endif/* update_conn_params_timer is used to update desired connection parameters after timeout */
if (false == os_timer_create(&update_conn_params_timer, "update_conn_params_timer", 1
, UPDATE_CONN_PARAMS_TIMEOUT, false, update_conn_params_timer_cb))
{
APP_PRINT_INFO0("[sw_timer_init] init update_conn_params_timer failed");
}keyscan_init_timer();
key_handle_init_timer();
}
/******************************************************************
* @brief task_init() contains the initialization of all the tasks.
*
* There are four tasks are initiated.
* Lowerstack task and upperstack task are used by bluetooth stack.
* Application task is task which user application code resides in.
* Emergency task is reserved.
* @param none
* @return none
* @retval void
*/
void task_init(void)
{
app_task_init();
}