蓝鲸手环软件系统
1 硬件框架
[TOC]
主要器件型号如下:
硬件模块 | 型号 | 参数 |
---|---|---|
MCU | Apollo2Blue | 48MHz/256KB RAM/1MB ROM |
Norflash | 8MB | |
GPS | UBX-M8230 | |
LCD | Truly | 1.1寸/160*64 |
TP | 联阳 | |
PPG | PPS964 | |
G-Sensor | MC3632 | |
PMU | MAX14745D | |
BT | 内置AM | |
Motor | AWA |
2 软件框架
如上图所示,蓝鲸的软件结构可以分为APP应用、中间件(Middleware)、HAL&BSP三个层次,另外还有一个BootLoader。
APP应用主要是实现UI交互逻辑和UI界面显示,通过API和消息接口,可以与中间件进行数据交互。
中间件实现了系统的大部分的组件,包含了GUI库(GUI Lib)、运动算法库(Algo Lib)、心率算法库(HRM Lib)、电源管理(PM)、通信协议(Protocol)、算法模块(Algo Ctrl)、数据存储模块(His Data)、数据查询模块(Data Reader)、运动模块(Sports)、Preference、AGPS、GPS、工厂测试(Factory)、升级模块(OTA)、健康模块(Providers)、调试模块等。
HAL是中间件和BSP之间的一个抽象接口层。
BSP实现了各个硬件模块的驱动。
Bootloader主要用于OTA升级过程中执行文件的搬移,将最新的版本搬到执行区域。
3 主要子系统框架介绍
3.1 APP应用
主要完成UI显示和交互逻辑,数据和系统控制是由中间件的各个模块提供,UI显示由GUI控件提供。模块之间通信主要是通过消息传递。
3.2 GUI模块
Libaroma是一个用纯C写的控件库,支持Linux、X86、QNX等不同平台。针对不同平台API做了一层封装,可以很快的移植到不同平台,参照Android的材料设计风格实现控件库,已经写好了Fragment、ViewPager、Button、ProgressBar、ListView、Dialog等控件,开发者可以实现自己的控件。目前
Libaroma框架只绝对布局,控件的开发基本和Android类似,也有Window,WindowManagr、EventHub等概念,支持Window转场动画。
3.3 私有协议模块
数据接收流程如下图,当DM端通过BLE的写特征值写入数据时,手环端BLE协议写回调函数会将数据送出,在回调函数中调用Message pack的API对数据包解析,并根据cmd字段对解析后的内容通过消息分发出去。
数据发送流程如下图,当数据需要发送时,先调用Message pack的API对数据进行打包,再调用BLE的发送接口发送出去。这里用到了两种发送方式,一种是写特征值的方式,这个主要是返回DM需要读取的数据;另一种是发送notify的方式,这个主要是回应DM发送过来的命令成功与否。
3.4 ANCS通知模块
和私有协议的接收流程类似,不同之处是这里是通过ANCS Service接收到数据,数据格式是ANCS规范定义的。
3.5 运动算法
运动算法包括计步、睡眠、骑行、久坐、翻腕、运动检测、敲击、游泳、健身等。除游泳和健身是采用SVM的深度学习算法外,其他都是采用传统算法,通过计算三轴数据的能量值和角度,并滤波,加上特征提取和判断逻辑。
- 传统算法运算量少,占用资源少,可以做到低功耗,全天候运行。
- 深度学习算法相对占用资源比较多,功耗会比较大,只能在进入特定场景下运行。
3.6 健康模块
健康模块中有心率、计步、睡眠、久坐四个业务,每个业务的软件架构基本是一样的,都是监听并处理其他模块发过来的消息。此模块与其他模块的关系如下:
健康模块是中间件中的一个重要模块,分别与穿戴协议、心率UI、计步UI、健康UI、运动UI、运动算法模块、心率算法模块、存储模块有交互。
- DM通过穿戴协议可以设置参数和读取健康数据,健康模块中要处理穿戴协议传过来的命令以及返回数据给穿戴协议。
- UI通过消息和API从健康模块获取相应的数据,健康模块也会根据设置的数值给UI主动发送消息,用于弹出提醒框。
- 运动算法的开关是通过健康模块来控制的,算法的数据会主动上报给健康模块。
- 健康模块会调用存储模块的接口保存健康数据,当DM要拉取健康数据的时候,健康模块也会调用存储模块查询历史数据,并返回给DM。
3.7 运动模块
运动模块中有室外跑步、室内跑步、游泳、骑行、健走、健身等业务,业务逻辑都是监听并处理其他模块发过来的消息,记录心率、步数、gps、距离、姿态等数据。此模块与其他模块的关系如下:
运动模块是中间件中的一个重要模块,分别与穿戴协议、跑步UI、游泳UI、骑行UI、健走UI、健身UI、健康模块、运动算法模块、GPS模块、存储模块有交互。
- DM通过穿戴协议可以设置参数和读取健康数据,运动模块中要处理穿戴协议传过来的命令以及返回数据给穿戴协议。
- UI通过消息和API从运动模块获取相应的数据,运动模块也会根据设置的数值给UI主动发送消息,用于实时更新数据。
- 运动模块会调用存储模块的接口保存运动记录、心率数据、GPS数据,当DM要拉取运动数据的时候,运动模块也会调用存储模块查询历史数据,并返回给DM。
3.8 GPS模块
GPS模块主要的任务是开关GPS、星历数据的下发、命令的下发、报文接收并解析,定位信息保存和发送等。
业务主要流程如下:
3.9 AGPS下载模块
主要业务流程如下,异常处理流程没有画出:
等全部的数据接收完成后,DM端发送命令给手环,进行全部数据的校验,校验成功后返回校验成功的消息给DM。
3.10 存储查询模块
蓝鲸硬件上有两块flash,一个是mcu片内的1MB ROM,一个是外部4/8MB norflash。片内的ROM主要用于存放代码,外部放norflash主要用于存放数据。
两个flash我们规划了不同的分区,用于满足手环系统的需求。
片内的ROM分区表如下:
分区名 | 地址范围 | 大小 | 备注
—|—|—|—|—
Bootloader | 0x00000-0x03FFF | 16KB | Bootloader
flag | 0x04000-0x07FFF | 16KB | ota flag和image地址、crc等
image | 0x08FFF-0xF7FFF | 984KB | image执行文件
factory | 0xF8000-0xFFFFF | 8KB | 工厂信息
外部的norflash分区表如下:
分区名 | 地址范围 | 大小 | 备注
—|—|—|—|—
OTA | 0x000000-0x0FFFFF | 1MB | OTA升级包
front | 0x100000-0x1FFFFF | 1MB | 字库
log | 0x200000-0x2FFFFF | 1MB | 离线log
bt_pair1 | 0x300000-0x300FFF | 4KB | ios蓝牙配对信息
bt_pair2 | 0x301000-0x301FFF | 4KB |ios蓝牙配对信息
bt_pair3 | 0x302000-0x302FFF | 4KB |ios蓝牙配对信息
bt_pair4 | 0x303000-0x303FFF | 4KB |ios蓝牙配对信息
bt_pair5 | 0x304000-0x304FFF | 4KB |ios蓝牙配对信息
agps | 0x305000-0x313FFF | 60KB |agps星历文件
agps head| 0x314000-0x318FFF | 20KB | agps星历文件头
resume | 0x319000-0x33FFFF | 156KB |保留
user data | 0x340000-0x37FFFF | 256KB |用户健康历史数据
sport data | 0x380000-0x3FFFFF | 512KB |运动历史数据
除历史数据外,其他的分区的数据存储比较简单,都是整块区域数据的读写。
历史数据的存储设计成一个循环buffer的机制,始终保持最近的数据,当数据量超过分区容量时,覆盖最早的数据。
3.11 OTA模块
主要业务流程如下,异常处理流程没有画出:
等全部的数据接收完成后,DM端发送命令给手环,进行全部数据的校验,校验成功后修改OTA的标志位,并返回校验成功的消息给DM,DM再发送重启的命令给手环,手环重启进入OTA流程,OTA完成后将标志位还原。
3.12 Preference模块
此模块维护了一组持久化数据,这些数据更新的频率可能会比较高,并且系统关机重启后,数据不会丢失。
业务逻辑如下:
分配了一块4KB大小的Flash区域用于保存数据,开机后,会将flash中的数据拷贝到内存中的一个全局变量,用于临时保存并更新数据。当系统关机重启前,全局变量中的数据会保存到flash中。
3.13 电源管理模块
电源管理模块负责充电管理、LCD背光管理、电量管理、温度报警、假关机管理等。
3.14 Common Driver模块
Common driver模块是中断处理的下半部,将一些中断处理函数中耗时的操作放到中断上下文之外去处理,保证了中断时间尽量的少。处理的中断有串口中断、TP中断、PMU中断、电池电量检测ADC中断、NTC检测ADC中断等。
3.15 看门狗模块
Apollo2Blue芯片的看门狗设置成0.75秒会产生一次中断,1.5秒不喂狗会超时重启。根据这个硬件特性,系统设计了一套喂狗机制:
- 使用事件标志组的方式,监控各个task,被监控的task每分钟设置一次事件标志组中对应的标志位。当全部的标志位都置位了,就清一次看门狗中断计数器g_ui8NumWatchdogInterrupts。
- 在看门狗中断中,对进入中断的次数计数g_ui8NumWatchdogInterrupts,当g_ui8NumWatchdogInterrupts小于180的时候就喂狗,否则就停止喂狗,等待超时重启。
3.16 消息模块
任务之间的数据通信主要靠消息机制,由于FreeRTOS系统只提供了点对点的API,我们在此基础上实现了类似Android的注册和广播的消息API。
使用队列将注册的消息保存起来,在发送消息的时候查找遍历队列中的消息,逐个发送出去。
3.17 工厂测试模块
产线生产的时候需要对硬件测试、写入信息、控制软件进入特定模式等,因此在手环代码要加入相关的代码。
需要通过发送特定的命令才能激活工厂测试代码,命令的发送方式主要有以下两种:
- 在SMT阶段,产线的夹具接通手环的串口,通过PC上位机发送串口命令。
- 在组装阶段,通过dongle连接手环的BLE Service,上位机发送蓝牙命令给手环。
3.18 BootLoader
Bootloader的主要作用是用来完成OTA,每次启动首先进入bootloader,通过判断保存在flash中的标志位,来决定是否进行代码搬移,主要流程如下图:
3.19 调试
调试方式目前有如下几种:
- 串口log:每个task都有宏单独控制log的开关,方便调试使用。
- AT指令:手环上实现了AT指令的解析,可以自己添加指令用于调试。
- KEIL DEBUG:可以设置断点和单步跟踪。
- 离线log:在flash中分出来一个单独的区域,用于存放离线log,在整机的情况下非常有用,但容量有限。