nrf52832关于freertos使用
2026/7/19 4:58:30 网站建设 项目流程

基于上一讲移植好的工程,这一讲讲述基于freertos的ble如何写代码

首先main函数

static void log_init(void) { ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); NRF_LOG_DEFAULT_BACKENDS_INIT(); } //日志初始化
static void clock_init(void) { ret_code_t err_code=nrf_drv_clock_init(); APP_ERROR_CHECK(err_code); } //时钟初始化

#if NRF_LOG_ENABLED // Start execution. if(pdPASS!=xTaskCreate(logger_thread,"LOGGER",256,NULL,1,&m_logger_thread)) { APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } #endif //如果开启日志就创建日志输出任务 #if NRF_LOG_ENABLED static void logger_thread(void * arg) { UNUSED_PARAMETER(arg); while (1) { NRF_LOG_FLUSH(); // 把缓存里所有日志串口输出 vTaskSuspend(NULL); // 执行完自动挂起自己,不再占用CPU } } #endif

SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; //放在 main 初始化阶段,全局开启深睡眠模式。 当所有 FreeRTOS 任务都阻塞(vTaskDelay、信号量、队列等待),空闲任务执行 __WFI(),芯片直接进入深睡眠,大幅降低待机功耗。

static void ble_stack_init(void) { ret_code_t err_code; err_code = nrf_sdh_enable_request();//内部判断使用外部时钟或者内部时钟进行初始化使用 APP_ERROR_CHECK(err_code); uint32_t ram_start = 0; err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);//获取ram起始地址 APP_ERROR_CHECK(err_code); // Enable BLE stack. err_code = nrf_sdh_ble_enable(&ram_start);//使能协议栈 APP_ERROR_CHECK(err_code); // Register a handler for BLE events. NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);//启动观察者 }
static void buttons_leds_init(bool * p_erase_bonds) { ret_code_t err_code; bsp_event_t startup_event; err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler); APP_ERROR_CHECK(err_code); err_code = bsp_btn_ble_init(NULL, &startup_event); APP_ERROR_CHECK(err_code); *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); }//初始化按键和灯用来指示状态或者删除绑定

static void gap_params_init(void) { ret_code_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }

static void gatt_init(void) { ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL); APP_ERROR_CHECK(err_code); }//gatt初始化

static void advertising_init(void) { ret_code_t err_code; ble_advertising_init_t init; memset(&init, 0, sizeof(init)); init.advdata.name_type = BLE_ADVDATA_FULL_NAME;//完整名字 init.advdata.include_appearance = true;//显示外观 init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;//通用可发现模式 init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);//计算uuid大小 init.advdata.uuids_complete.p_uuids = m_adv_uuids;//完整uuid列表 init.config.ble_adv_fast_enabled = true;//快速广播 init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; init.config.ble_adv_fast_timeout = APP_ADV_DURATION; init.evt_handler = on_adv_evt;//回调函数 err_code = ble_advertising_init(&m_advertising, &init);//初始化广播 APP_ERROR_CHECK(err_code); ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);//预留功能 }

static void conn_params_init(void) { ret_code_t err_code; ble_conn_params_init_t cp_init; memset(&cp_init, 0, sizeof(cp_init)); cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = m_hrs.hrm_handles.cccd_handle; cp_init.disconnect_on_fail = false; cp_init.evt_handler = on_conn_params_evt; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init(&cp_init); APP_ERROR_CHECK(err_code); }//配置连接参数

以上所有初始化完之后调用nrf_sdh_freertos_init(advertising_start,NULL);创建BLE任务,传入广播函数,开启调度后会自动运行广播,然后进入ble死循环,在死循环中等待ble协议栈触发的任务唤醒,唤醒之后在独立协议栈中运行而不在中断中,相比逻辑更安全,接下来就自行添加服务了,不需要在freertos任务中加,而是在开启广播任务之前初始化即可,注意堆栈分配,开启jtt查看调试信息,前面几次我都直接返回的是fatal error,没有日志,这种情况说明堆栈太小,直接去加大广播任务的栈,还有freertos的configTOTAL_HEAP_SIZE栈,sdk_config.h中的NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE栈,或者启动文件.s中也要加大,还有

这是我的ram可以参考,具体还要不断加大根据rtt打印判断

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询