Añadir servicio DFU desarrollado por nrf52832

Prefacio: Agregar el servicio DFU al programa BLE de Nordic es mucho más simple que crear DFU. Básicamente, seguir el proceso permitirá que su aplicación realice DFU inalámbrica

1. Preparaciones tempranas

1. Agregue el código fuente DFU
nRF5_SDK_15.2.0_9412b96 \ components \ ble \ ble_services \ ble_dfu \ ble_dfu.c
nRF5_SDK_15.2.0_9412b96 \ components \ ble \ ble_services \ ble_dfu \ ble_dfu_bonded.c
nRF5_941_bK_ components \ ble \ ble_services \ ble_dfu \ ble_dfu_unbonded.c
nRF5_SDK_15.2.0_9412b96 \ components \ bibliotecas \ bootloader \ dfu \ nrf_dfu_svci.c

2. 添加 头 文件 路径
.. \ Bibliotecas \ componentes \ bibliotecas \ svc
.. \ Bibliotecas \ componentes \ bibliotecas \ cargador de arranque
.. \ Bibliotecas \ componentes \ bibliotecas \ cargador de arranque \ dfu
.. \ Bibliotecas \ componentes \ bibliotecas \ cargador de arranque \ ble_dfu
.. \ Libraries \ components \ ble \ ble_services \ ble_dfu
.. \ Libraries \ components \ softdevice \ mbr \ nrf52832 \ headers

3. 添加 宏
1) BLE_SETTINGS_ACCESS_ONLY 
2) NRF_DFU_SVCI_ENABLED 
3) NRF_DFU_TRANSPORT_BLE = 1

4. Modifique el archivo sdk_config.h
1) Habilite el módulo DFU
#ifndef BLE_DFU_ENABLED
#define BLE_DFU_ENABLED 1
#endif

2) Modifique el número de UUID personalizados utilizados. Cada uno adicional debe modificar la dirección de inicio y usar el tamaño de la RAM en el proyecto. El tamaño de RAM ocupado por 1 UUID es 0x10
#ifndef NRF_SDH_BLE_VS_UUID_COUNT
#define NRF_SDH_BLE_VS_UUID_COUNT 2
#endif

Modifique de acuerdo con la cantidad de UUID personalizados realmente utilizados

2. Modificar el código del programa principal

1. Incluir archivos de encabezado

#include "nrf_power.h"
#include "nrf_bootloader_info.h"
#include "nrf_dfu_ble.h"
#include "ble_dfu.h"
#include "nrf_dfu_ble_svci_bond_sharing.h"
#include "nrf_svci_async_function.h"
#include "nrf_svci_async_handler.h"

2. Inicialice el servicio DFU en la función de servicio de inicialización

//获取广播配置参数
static void advertising_config_get(ble_adv_modes_config_t * p_config)
{
    memset(p_config, 0, sizeof(ble_adv_modes_config_t));

    p_config->ble_adv_fast_enabled  = true;
    p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
    p_config->ble_adv_fast_timeout  = APP_ADV_DURATION;
}

//断开连接
static void disconnect(uint16_t conn_handle, void * p_context)
{
    UNUSED_PARAMETER(p_context);

    ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
    if (err_code != NRF_SUCCESS)
    {
        NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code);
    }
    else
    {
        NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle);
    }
}

//DFU回调函数
static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
{
	ret_code_t err_code;
    switch (event)
    {	//在进入bootloader执行DFU前的准备工作
        case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
            NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
			//防止设备断开连接时进行广播
            ble_adv_modes_config_t config;
            advertising_config_get(&config);
            config.ble_adv_on_disconnect_disabled = true;
            ble_advertising_modes_config_set(&m_advertising, &config);

            // 断开当前的所有连接
            uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
            NRF_LOG_INFO("Disconnected %d links.", conn_count);

        case BLE_DFU_EVT_BOOTLOADER_ENTER:
            NRF_LOG_INFO("Device will enter bootloader mode.");
            break;

        case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
            NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
            break;

        case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
            NRF_LOG_ERROR("Request to send a response to client failed.");
            APP_ERROR_CHECK(false);
            break;

        default:
            NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
            break;
	}
}

static void dfu_s_init(void)
{
    uint32_t err_code;

	ble_dfu_buttonless_init_t dfus_init = {0};
	//注册DFU回调函数
	dfus_init.evt_handler = ble_dfu_evt_handler;
	//初始化DFU
	err_code = ble_dfu_buttonless_init(&dfus_init);
	APP_ERROR_CHECK(err_code);
}

static void services_init(void)
{
    //初始化DFU服务
    dfu_s_init();
}

3. Registre el monitor de estado de la pila de protocolos

//协议栈状态发送改变时会调用此函数
static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
{
    if (state == NRF_SDH_EVT_STATE_DISABLED)
    {
        //在复位之前禁用协议栈,并告知bootloader启动时跳过CRC
        nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
        //进入system off模式
        nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
    }
}

NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
{
    .handler = buttonless_dfu_sdh_state_observer,
};

Hasta ahora, se ha introducido el proceso de agregar el servicio DFU al programa BLE escrito por usted mismo.

Publicado 81 artículos originales · 21 elogios · 30,000+ visitas

Supongo que te gusta

Origin blog.csdn.net/qq_33575901/article/details/102612429
Recomendado
Clasificación