1. 定义一个DFU 服务
#ifdef BLE_DFU_APP_SUPPORT
/** @snippet [DFU BLE Service initialization] */
ble_dfu_init_t   dfus_init;
// Initialize the Device Firmware Update Service.
memset(&dfus_init, 0, sizeof(dfus_init));
dfus_init.evt_handler   = dfu_app_on_dfu_evt;
dfus_init.error_handler = NULL;
dfus_init.evt_handler   = dfu_app_on_dfu_evt;
dfus_init.revision      = DFU_REVISION;
err_code = ble_dfu_init(&m_dfus, &dfus_init);
APP_ERROR_CHECK(err_code);
dfu_app_reset_prepare_set(reset_prepare);
dfu_app_dm_appl_instance_set(m_app_handle);
/** @snippet [DFU BLE Service initialization] */
#endif // BLE_DFU_APP_SUPPORT

2.添加服务到事件分配函数中

3.添加服务初始化函数,以及事件处理函数
uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)              //初始化服务函数
{
if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
{
return NRF_ERROR_NULL;
}
p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
ble_uuid_t service_uuid;
uint32_t   err_code;
const ble_uuid128_t base_uuid128 =
{
{
0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
}
};
service_uuid.uuid = BLE_DFU_SERVICE_UUID;                                          //服务的UUID
err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
VERIFY_SUCCESS(err_code);
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&service_uuid,
&(p_dfu->service_handle));
VERIFY_SUCCESS(err_code);
p_dfu->uuid_type = service_uuid.type;
err_code = dfu_pkt_char_add(p_dfu);             // DFU Packet characteristic to the BLE Stack
VERIFY_SUCCESS(err_code);
err_code = dfu_ctrl_pt_add(p_dfu);              //DFU Control Point characteristic to the BLE Stack.
VERIFY_SUCCESS(err_code);
err_code = dfu_rev_char_add(p_dfu, p_dfu_init);    //adding DFU Revision characteristic to the BLE Stack
VERIFY_SUCCESS(err_code);
p_dfu->evt_handler = p_dfu_init->evt_handler;
if (p_dfu_init->error_handler != NULL)
{
p_dfu->error_handler = p_dfu_init->error_handler;
}
m_is_dfu_service_initialized = true;
return NRF_SUCCESS;
}
void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)     //事件处理函数
{
switch (p_evt->ble_dfu_evt_type)
{
case BLE_DFU_START:
//复位进入bootloader 转到bootload的主函数执行
// Starting the bootloader - will cause reset.
bootloader_start(p_dfu->conn_handle);      
/*****************starting  主要程序有几个注意的 ********************  
err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);  //  设置  BOOTLOADER_DFU_START=0xB1
err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);  //设置协议栈中断向量表
/**********************************************************************/
break;
default:
{
// Unsupported event received from DFU Service.
// Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
uint32_t err_code = ble_dfu_response_send(p_dfu,
BLE_DFU_START_PROCEDURE,
BLE_DFU_RESP_VAL_NOT_SUPPORTED);
APP_ERROR_CHECK(err_code);
}
break;
}
}

4.程序由app->bootload
int main(void)
{
uint32_t err_code;
bool     dfu_start = false;
bool     app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START); //这个寄存器值由app设置 这里相同 所以APPSET=1
if (app_reset)
{
NRF_POWER->GPREGRET = 0;      //清除,防止一直boot
}
leds_init();
// This check ensures that the defined fields in the bootloader corresponds with actual
// setting in the chip.
APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);   
// Initialize.
timers_init();
buttons_init();
(void)bootloader_init();    
if (bootloader_dfu_sd_in_progress())          //协议栈更新,这里我们不更新  所以值为false直接进去else程序
{
nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);
err_code = bootloader_dfu_sd_update_continue();
APP_ERROR_CHECK(err_code);
ble_stack_init(!app_reset);
scheduler_init();
err_code = bootloader_dfu_sd_update_finalize();
APP_ERROR_CHECK(err_code);
nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
}
else
{
// If stack is present then continue initialization of bootloader.
ble_stack_init(!app_reset);     //协议栈app_set==1
scheduler_init();
}
dfu_start  = app_reset;
dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) ? true: false);
if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))    
{
nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);
// Initiate an update of the firmware.
err_code = bootloader_dfu_start();
/***********************************代码追溯*************************** 
//  bootloader_dfu_start()
---->>>>>>
dfu_transport_update_start()
---->>>>>{
....      
gap_params_init();
services_init();
conn_params_init();
sec_params_init();
advertising_start();   //开启广播后 连接设备  ,进行数据传输。
......
}
/*************************************************************************///
APP_ERROR_CHECK(err_code);
nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
}
if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress())    //判断传输状态和地址是否正确
{
// Select a bank region to use as application region.
// @note: Only applications running from DFU_BANK_0_REGION_START is supported.
bootloader_app_start(DFU_BANK_0_REGION_START);       // 重启开始  重启app中断向量表的reset  所以程序从app开始执行
}
NVIC_SystemReset();  
}
        转载:https://blog.csdn.net/sinat_23338865/article/details/52295156

【NRF51822】DFU过程梳理相关推荐

  1. SprinBoot集成disConf的过程梳理

    SprinBoot集成disConf的过程梳理: 打开pom.xml文件,添加disconf-client的依赖关系,工程会自动下载Disconf客户端的jar包 <dependency> ...

  2. nrf51822笔记之密码配对过程梳理

    配对的触发有以下几种情况: 1:主机直接发起. 2:从机发起安全请求,如果之前绑定过,那么主机会直接用用保存的LTK加密链路,如果没有那么主机会发起配对请求. 3:BLE中的有一个安全模式的概念.当某 ...

  3. 数据中台数据分析过程梳理

    在当今社会中,随着企业的快速发展,相关业务系统的建设也会越来越多,新的业务模式.新的IT架构.多云环境的出现等等.而一些问题就逐渐暴露了出来:企业之间的IT无法做到互通.新模式生产数据与旧数据无法互通 ...

  4. matlab的pca图像去噪程序,PCA实现过程梳理以及降噪处理

    现在CNV分析方法有很多,但是随着NGS成本的降低,高深度的测序下背景下,read count(depth)方法逐渐变为各个分析软件的主流.最近在看GATK的CNV分析方法,其中在创建PoN(Pane ...

  5. ble连接过程建立_BLE配对绑定过程梳理

    (一)BLE SM为以下三种procedure提供支持: 1. Pairing; 2. Bondig; 3. Encryption Re-establishment; 区别于传统蓝牙的配对过程,BLE ...

  6. BLE配对绑定过程梳理

    (一)BLE SM为以下三种procedure提供支持: 1. Pairing; 2. Bondig; 3. Encryption Re-establishment; 区别于传统蓝牙的配对过程,BLE ...

  7. Https 客户端与服务器交互过程梳理(转)

    本文试图以通俗易通的方式介绍Https的工作原理,不纠结具体的术语,不考证严格的流程.我相信弄懂了原理之后,到了具体操作和实现的时候,方向就不会错,然后条条大路通罗马.阅读文本需要提前大致了解对称加密 ...

  8. Java类加载过程梳理,一篇搞定

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/hsz2568952354/ article/details/96763284 最近在看Java虚拟机,正好看到类加载这块,所以 ...

  9. TIF 和Hdmi cec hotplug热插拔事件过程梳理一

    从Hal开始,具体的code不贴了,只贴下接口. 1.注册接口 hardware\libhardware\include\hardware\hdmi_cec.h /** (*register_even ...

  10. 使用Nordic的nrf52840实现蓝牙DFU过程

    需要用到的软件: 交叉编译环境:gcc-arm-none-eabi MinGW:下载 Python:下载 micro-ecc源码:下载 nRFUtil:下载或者直接使用python的pip来安装 手机 ...

最新文章

  1. 深入浅出Redis五种基本数据类型
  2. 操作系统思考 第二章 进程
  3. IT公司比较流行的10种编程语言
  4. UIActionSheet的使用
  5. dHedge DAO和一些顶级基金向基金管理者投资14.5万sUSD
  6. js中的empty()和remove()的区别
  7. 使用Visual Studio进行单元测试-Part4
  8. 努比亚 Z17(Nubia NX563J) 解锁BootLoader 并刷入recovery
  9. 【mediasoup 带宽估计】aimd算法2 : AimdRateControl
  10. 启动系统提示“NTLDR is missing”的解决办法
  11. 解决视频资源音乐资源在Android模拟器中不能播放的问题
  12. 计算机类游戏本,游戏本电脑性价比排行2020年推荐 “性价比之最”你知道吗?...
  13. 如何写一个一天爬取 100 万张网页的爬虫
  14. Community Day - Let's re:Invent re:Invent 技术创新盘点
  15. 小米AX1800开SSH权限
  16. 低功耗蓝牙BLE-Advertising State/Scanning State
  17. 6级听力词汇与习语3
  18. IDEA插件之输入法自动切换【Smart Input Source】
  19. 个性化MDT离线U盘
  20. Lab3-1 832001227

热门文章

  1. 使用TextMeshPro实现打字机效果
  2. Mac 使用ab命令压测配置及使用总结
  3. Flutter与RN
  4. 吉林大学软件学院黄庆道《最优化算法》对偶单纯形使用大M法条件
  5. 关于MFC的使用总结之四——添加menu菜单
  6. sphinx使用笔记
  7. list(map(tokenizer.tokenize, text))
  8. java 爬虫 微博_最新新浪微博爬虫程序Java版 2015
  9. EndNote简明教程(三分钟上手EndNote)
  10. Nerv-京东高性能前端框架