CN / EN
文档反馈
感谢关注汇顶文档,期待您的宝贵建议!
感谢您的反馈,祝您愉快!
文档中心 > GR5xx固件升级开发指南/ DFU移植方式详解 Copy URL

DFU移植方式详解

为方便用户将GR5xx提供的DFU方案应用到自定义的工程中,本章以ble_app_template_dfu示例工程为例(工程位于SDK_Folder\projects\ble\ble_peripheral\ble_app_template_dfu),介绍为该工程移植DFU功能的操作。移植过程主要包括以下步骤:

  1. 添加DFU组件和OTA Profile。
  2. DFU初始化。
  3. 添加DFU调度器。
  4. DFU服务初始化及数据接收处理。
  5. 修改固件地址和名称。

具体操作步骤如下:

  1. 添加DFU组件和OTA Profile。

    在gr_libraries和gr_profiles工程文件夹下分别添加dfu_port.c(位于SDK_Folder\components\libraries\dfu_port)和otas.c文件(SDK_Folder\components\profiles\otas),如下图所示。

    图 48 Keil工程列表
  2. DFU初始化,代码位于user_periph_setup.c文件的app_periph_init()函数中,如下所示:
    #include “dfu_port.h”
    void app_periph_init(void)
    {
         ……
         dfu_uart_init();
         dfu_port_init(uart_send_data, DFU_FW_SAVE_ADDR, &dfu_pro_call);
         ……
    }
    
    • dfu_uart_init()是串口初始化函数,当使用串口通讯方式时,需要初始化串口。具体实现可参考user_periph_setup.c中的dfu_uart_init()函数。
    • dfu_port_init()是DFU初始化函数,初始化时注册串口发送接口、固件存储地址以及升级过程回调函数。
      • uart_send_data是串口发送数据函数,使用UART通信方式升级时,需要注册该接口,具体实现可参考user_periph_setup.c中的uart_send_data()函数。
      • DFU_FW_SAVE_ADDR表示向Master推荐的固件存储地址(Bank1起始地址)。以GR551x为例,其值可设置为:
        #define DFU_FW_SAVE_ADDR (FLASH_START_ADDR + 0x60000)
        说明:

        该宏的值不是固定的。设置时需注意不能和App bootloader固件、Bank0固件的地址冲突。

      • dfu_pro_call是升级过程中的升级进度回调函数结构体全局变量,具体定义可参考如下代码:
        static void dfu_program_start_callback(void);
        static void dfu_programing_callback(uint8_t pro);
        static void dfu_program_end_callback(uint8_t status);
        
        static dfu_pro_callback_t dfu_pro_call =
        {
            .dfu_program_start_callback = dfu_program_start_callback,
            .dfu_programing_callback = dfu_programing_callback,
            .dfu_program_end_callback = dfu_program_end_callback,
        };
        
        static void dfu_program_start_callback(void)
        {
            APP_LOG_DEBUG("Dfu start program");
        }
        
        static void dfu_programing_callback(uint8_t pro)
        {
            APP_LOG_DEBUG("Dfu programing---%d%%", pro);
        }
        
        static void dfu_program_end_callback(uint8_t status)
        {
            APP_LOG_DEBUG("Dfu program end");
            if (0x01 == status)
            {
                APP_LOG_DEBUG("status: successful");
            }
            else
            {
                APP_LOG_DEBUG("status: error");
            }
        }
        
  3. 添加DFU调度器,并需添加头文件#include "dfu_port.h",如下所示:
    #include "dfu_port.h"
    int main(void)
    {
         ……
        while (1)
        {
             dfu_schedule();
             ……
        }
    }
    
  4. DFU服务初始化及数据接收处理。
    当使用低功耗蓝牙通信方式升级时,在 user_app.c文件的service_init函数中初始化DFU相关服务,如下所示:
    static void services_init(void)
    {
        dfu_service_init(dfu_enter);
    }
    

    dfu_enter()函数定义默认为空,用户可在函数内部添加DFU启动时的自定义操作。

    当以UART通信方式升级时,需添加接收数据处理操作,参考代码如下所示:

    void dfu_uart_evt_handler(app_uart_evt_t * p_evt)
    {
        switch(p_evt->evt_type)
        {
            ……
            case APP_UART_EVT_RX_DATA: 
            ……
            dfu_uart_receive_data_process(s_dfu_uart_rx_buffer, p_evt->data.size); 
            app_uart_receive_async(APP_UART1_ID, s_dfu_uart_rx_buffer,DFU_UART_RX_BUFF_SIZE);
            ……
            break;
            ……
        }
    }
    
    说明:

    在手机端当前连接设备的DFU任务尚处于停止状态时,点击升级按钮前,若需通过 GRToolbox 获取固件信息,可通过写控制点的方式手动下发唤醒DFU任务的命令,具体操作请参考固件升级

  5. 修改固件地址和名称。
    • 根据Flash布局设计,修改固件地址。在custom.config.h中设置APP_CODE_LOAD_ADDR和APP_CODE_RUN_ADDR。以GR551x为例,将APP_CODE_RUN_ADDR和APP_CODE_LOAD_ADDR设置为0x01030000。

    • 修改固件名称。参考App bootloader查找APP固件规则,如果App bootloader使能了BOOTLOADER_BY_NAME_ENABLE(默认使能),为使App bootloader固件能正确跳转至应用固件,则需匹配两者的固件名称。App bootloader固件默认COMMENTS为"ble_app_temp",因此需在custom.config.h中添加如下的ble_app_template_dfu固件COMMENTS。
      #define APP_INFO_COMMENTS	"ble_app_temp"

扫描关注

打开微信,使用“扫一扫”即可关注。