【NRF51822】百度手环开源源码分析--存储部分
一、编写说明
对duBand源码的存储部分进行分析,本文档用于记录分析过程。
二、源码分析
1. 存储区域划分
在使用nRF Studio进入程序下载时,可以看出,存储区域分为三个Region,如下图所示,分别存在蓝牙协议栈、应用程序和Bootloader。
在APP中,程序存储区域再细分为APP、DATA和SWAP区,通过阅读源码,得知区域图详细划分如下图所示(注意:duBand的设计文档区域划分与源码的不同)。在Bootloader的源码中,APP DATA的大小为42KB,但在APP的源码中,设置着PAGE_NUM_FOR_DATA为32,而NRF51822的页大小为1024 B,因此APP DATA的大小实际为32 KB,还有10 KB的存储空间没有用到。
2. 代码分析
duBand的每一类型的参数存储占用各一个FLASH页面,如ALARM、USER PROFILE、TARGET等,都各占1 KB的存储空间,但实际上只用到少量。接下来以两个实例分析的方式分析存储和读取的代码,以save_alarm()与load_alarm()为例进行分析。
duBand中的数据存储与读取函数使用了一个比较灵活和高效的方法,就是利用memcmp()与memcpy()进行操作。当有数据需要保存时,先将数据从FLASH中读取出来,再通过memcmp()进行比较,如果数据不同,则有必要保存,否则没有更新,则不保存。存储的时候使用memcpy()将新数据复制至缓冲中,再写到FLASH中。
1) save_alarm()
以save_alarm()为例,其代码如下图所示。(1)先定义数据alarm_mem[],用于存放FLASH中读取出来的数据。(2)调用bd_flash_read_page()读取FLASH内容。(3)如果读取出来的闹钟数量与设置的闹钟数量相等,(4)则检测闹钟内容是否有更新,(5)如没有更新,则不需要重新存储,直接return。如有数据更新,则继续运行下去。(6)获取ALARM存储数据的绝对地址。(7)检测FLASH是否已檫除,(8)如未檫除则需要调用ble_flash_page_delay_erase()进行异步存储,这样做的原因是因为檫除操作比较耗时,如果同步去檫除时,会导影响蓝牙程序,因此这个做了一个异步操作,详细参与异步存储。(9)否则调用save_alarms_into_flash()保存ALARM数据。
save_alarms_into_flash()为具体的存储操作函数,如下图所示。(1)定义临时数据alarm_mem[],用于存在数据。(2)将当前ALARM数据复制至alarm_mem[]中。(3)将alarm_mem[]的数据写进FLASH中。
2) load_alarm()
读取参数的函数就比较简单了,因为不涉及长时间的操作,因此不用进行异步处理,如下图所示,(1)先定义存储读取出来的数据的临时数组alarm_mem[]。(2)读取相应FLASH数据至alarm_mem[]中。如果读取失败,则清空ALARM数据,(4)如果读取成功,则将数据复制至ALARM的全局变量中。
3. 异步存储
由于FLASH的擦除操作比较耗时,为了不影响系统的实时性并不影响蓝牙通讯,当需要对FLASH擦除时,存储系统使用了异步处理事件。通过ble_flash_page_delay_erase()将要删除的页面号写入删除队列flash_page_to_erase_Q[]。具体的操作在ble_flash_erase_data_page()中进行,此函数在ble_radio_notification_init()中注册为RADIO回调事件,并由ble_flash_on_radio_active_evt()异步调用。
先来分析ble_flash_page_delay_erase()函数,如下图所示。(1)先判断目标页面是否已经存在擦除队列中,如在,则不作任何处理。(2)判断目标页面是否在APP DATA区域内,否则返回错误。(3)如果RADIO不在工作中时,则马上进行页面擦除并返回。(4)判断擦除队列是否已满,是则返回错误。(5)将目标页面写入擦除队列中。在这个函数内,其实有个陷阱,如上面所描述的第(3)步,如果这里马上删除了的话,就不会调用异步写入(后面分析)的操作,但是这个操作是无伤大雅的,如果蓝牙断开/不工作,也没有存储的必要。
将目标擦除页写入了队列后,在RADIO的ACTIVE回调函数ble_flash_on_radio_active_evt()中,如下图所示,(1)会判断队列中是否有数据和其它一些条件(如RADIO是否正在工作、蓝牙状态),(2)如有数据,则判断是否已经调用异步擦除,(3如没有则进行异步调用。
最终的擦除和更新操作是在ble_flash_erase_data_page()中完成的,此函数由app_sched调度运行。如下图所示,(1)程序先判断蓝牙是否处于工作状态,(2)如果蓝牙空闲,则可以马上进行页面擦除,(3)并调用sync_data_to_flash()更新相应页面的数据。(4)再判断是否还有需要擦除的页面,有则调用app_sched继续调度ble_flash_erase_data_page()并返回。(5)如果蓝牙正在广播或保持长连接状态下,则需要判断inactive_last_time(此值在ble_flash_on_radio_active_evt()中赋值,估计主要是用于检测是否处于有校时间内)是否合法,合法才进行页面擦除并更新相应页面的数据。
数据更新函数sync_data_to_flash()的代码如下图所示,该函数实现比较简单,只是更新不同的页号去调用相应的数据存储函数。
4. 读写校验
读写的校验在底层的函数ble_flash_page_write()和ble_flash_page_read()中实现。由于这是NORDIC提供的操作库函数,因此这里不继续分析下去了,拿来就用就好了。
【NRF51822】百度手环开源源码分析--存储部分相关推荐
- 【NRF51822】百度手环开源源码分析--底层通讯部分
一.编写说明 duBand源码中的通讯部分源码较多,但细细阅读发现其分层结构清晰,很值得借鉴.为了深入对duBand通讯源码的学习,并理解通讯分层设计的思想,决定对duBand源码的通讯部分进行分析, ...
- 【NRF51822】百度手环开源源码分析--框架部分
1.Main函数(main.c) a) gpio_init(); //初始化全部IO口为初始状态(输入.关上拉.关复用) b) pre_init(); //初始化时钟与RTC0并进行待机,待RTC0中 ...
- 【NRF51822】百度手环开源源码分析--数据自动同步部分
1. void send_all_data(boolis_from_cb) 发送数据都是通过send_all_data()去上传的. 1) static boolneed_send_sync_pr ...
- 2022全球20多款知名的Android刷机ROM镜像和Android系统开源源码(覆盖全球机型)
推荐阅读 Android10系统定制|frida逆向分析实战课程 2022全球20多款知名的Android刷机ROM镜像和Android系统开源源码(覆盖全球机型) 因此,您拥有一台Android设 ...
- Android开源源码推荐(一)
qianqianlianmeng Android开源源码推荐(一) 1.Android-ViewPagerIndicator http://www.akaifa.com/code/86/android ...
- 很火的仿soul交友盲盒1.0全开源源码
简介: 目前很火的仿soul交友盲盒1.0全开源源码,2000块钱购买的一套仿soul盲盒交友开源源码 网盘下载地址: http://kekewl.org/UUqVYnPqS0t0 图片:
- 云蹦迪云广场舞软件开源源码
云蹦迪广场舞 意:第2,3步只在第一次运行时需要配置 一定要按照顺序执行,执行顺序有错会报错 开播 在抖音找到自己的直播间,复制直播间号(绿色区域是直播间号)(只在第一次运行时需要) 在解压后的deb ...
- PHP抽奖小程序/微信红包封面抽奖小程序/抽奖小程序开源源码
PHP抽奖小程序源码,微信红包封面抽奖小程序,全开源.带流量主(需要自行替换代码),独立后台,亲测完美可用. 下载 PHP抽奖小程序/微信红包封面抽奖小程序/抽奖小程序开源源码 亲测截图:
- Telegram Android开源源码运行
TG-Android开源源码运行 源码地址 https://github.com/DrKLO/Telegram 环境介绍 Android Studio版本至少3.4,或者直接去官网下载最新的 手机最低 ...
最新文章
- mysql+keepalived必须要lvs吗_MySQL 双主热备 + LVS + Keepalived 高可用操作记录
- 「后端小伙伴来学前端了」CSS 做三角边框,必会的基础操作之一
- pipreqs生成python项目依赖清单
- 给你一个能生成1到5随机数的函数,用它写一个函数生成1到7的随机数
- ASP.NET Session的七点认识(转)
- JAVA基础知识|lambda与stream
- iOS音频的后台播放总结(后台网络请求歌曲,Remote控制,锁屏封面,各种打断)...
- 加载执行预编译的Sql :prepareStatement
- 更换百度地图图标html,百度地图接口,自定义图标,点击切换图标
- php页面自分页刷新,详解PHP+AJAX无刷新分页实现方法
- yolov5继续训练_震惊! 它来了!YOLOv5它来了!
- Silverlight开发的15个最佳实践
- 归类问题:简单的代价函数和梯度下降----吴恩达机器学习
- Windows10原神二次元美化主题工具包分享
- Win32屏幕保护程序
- STM32入门指南(0)—配置开发环境
- Android编译报 Removing unused resources requires unused code shrinking to be turned on
- python中气泡图文字标签_Excel中制作气泡图及为气泡图的系列数据点添加文本数据标签...
- 【MAUI】条形码,二维码扫描功能
- FlinkCEP的底层理论:NFA-b Automaton原理介绍