【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提供的操作库函数,因此这里不继续分析下去了,拿来就用就好了。

前言: 智能运动手环是可穿戴设备的一个主要发展方向,国内外均有产品面世。其使用方式为腕部佩戴(可以有其它变种佩戴形式),基本功能为运动记录、睡眠质量检测、时间显示和静音闹钟、与智能手机的配合产生的实用功能(如来电提醒、手机防丢、一键拍照和解锁等)。 百度智能运动手环硬件方案总体介绍: 百度智能手环基于Nordic公司nRF51822芯片开发,芯片集成BLE蓝牙4.0协议。使用LIS3DH作为加速度传感器,进行运动和睡眠监测。 手环硬件电路设计部分包括: 蓝牙射频电路; 使用SPI接口的G-sensor; 使用 I2C接口的线性马达驱动电路; 使用I2C接口的LED点阵驱动,与线性马达共用总线; 使用 GPIO的按键输入; 使用 GPIO的LED 灯; 使用 GPIO的普通马达驱动电路; 外部复位电路; 如截图: 百度智能手环电路原理图截图: 百度智能运动手环设计方案成功案例如下: 1.TCL BOOM Band 这是TCL基于百度智能手环方案打造的产品,于2014年1月上市。有运动计步、睡眠监测,来电提醒、蓝牙防丢等功能。 视频展示: 2.OPPO O band OPPO O band,OPPO基于百度智能手环方案打造,于2014年6月上市。采用了LED点阵,并且增加了智能拍照功能 视频展示: 智能手环相关设计项目:小米智能手环设计分享(原理图+源代码+制作教程等) 附件内容包括: 智能手环电路原理图和PCB PDF档、元器件清单、硬件设计详细讲解; ROM源码、ROM烧录工具、百度智能手环ROM设计详细讲解; 匹配的手机App及云存储和服务等; 百度智能手环蓝牙私有通信协议;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值