Duband源码下载地址:http://pan.baidu.com/s/1uBFFC
1.Main函数(main.c)
a) gpio_init(); //初始化全部IO口为初始状态(输入、关上拉、关复用)
b) pre_init(); //初始化时钟与RTC0并进行待机,待RTC0中断唤醒。用此方式待电源稳定
c) init1(); //初始化LED、MOTOR、TIMER、ADC、G-SENSOR等硬件。初始化TIMER、系统调度等相关服务
d) 检测是否在充电状态,如果是则关闭系统
e) bootup_check();//启动检测,点亮全部LED。如果未进行过出厂测试,则进行出厂自检
f) reset_check(); //复位检测,在这里代码只是简单输出信息。如打开了INTERNAL_DEV宏,则为内部设备,进行FLASH删除
g) init2(); //初始化看门狗,定时器服务创建,外部中断服务(gpiote_int_init())初始化,系统时间初始化,bond管理器初始化,蓝牙协议栈初始化,蓝牙服务创建,打开G-SENSOR
h) 读取闹铃、用户信息、用户目标、运行/睡眠数据
2.蓝牙通信 (bd_communicate_protocol.c)
a) void L1_receive_data(ble_nus_t * p_nus, uint8_t * data, uint16_t length)
L1_receive_data()为蓝牙通信接收的入口函数,该函数为蓝牙UART服务的接收数据回调函数。
通过数据包长度字段判断是否接收完整一个包(一帧或多帧),接收完成后调用L1_crc_check函数校验CRC是否正确。如果CRC正确则调用L1_receive_response返回ACK,并调用L2_frame_resolve解释数据包。如CRC校验错误,则调用L1_receive_response返回NAC,并调试schedule_crc_error_handle(这个任务只是简单输出信息)。
b) uint32_t L2_frame_resolve(uint8_t * data, uint16_t length,RECEIVE_STATE * resolve_state)
当接收完整的数据包并且CRC校验正确,就会进入该函数中解释数据包。程序首先判断是否有手环已绑定。未绑定状态下,只可以响应绑定、工厂测试、固件升级、输出日志的命令。绑定状态下可响应全部命令。
c) uint32_t L1_send(L2_Send_Content * content)
数据的发送通过调用L1_send实现,该函数的参数为发送数据包的指针函数。如在return_alarm_list()中返回的闹钟列表命令,通过填充全局变量global_reponse_buffer来实现发送数据的链接。在L1_send()函数里再使用全局变量global_L1_header_buffer封装成完成的数据包。最后调用schedule_async_send()调度发送服务。发送部分比较复杂,后面将单独分析。
3.发送数据
a) void send_all_data(bool is_from_cb)
该函数为上传数据的唯一接口,函数里面先启动发送数据定时服务。然后依次检测是否有数据,检测顺序为sleep in flash > sleep in ram > sleep setting in ram > sport in flash > sport in ram,如有数据则调用相应的send函数,如send_sleep_data_in_ram()。
该函数进入时判断是否为绑定状态,非绑定状态下不传数据。接着判断sending_flag是否为true,如果为true说明正在发送数据,则启动发送服务定时器,达到定时器服务中断后再重试的效果。
b) void send_data_timeout(void * val)
定时发送服务函数,该定时服务的定时时间为5000MS。里面所做的处理就是重复调用send_all_data()去发送数据。
c) void send_all_data_callback(SEND_STATUS status)
该函数为发送数据的回调函数,在低层数据发送完成后会调用该回调函数进行发送错误处理,或更新发送缓存处理。
4.L1层数据传输
5.定时器服务
duBand使用的定时器服务是NRF51 SDK里面提供的APP定时器服务接口,该服务使用RTC中断作为APP定时器中断,通过SWI0(app_timer_start()与app_timer_stop())中断调用LIST TIMER HANDING来设置定时器状态。
a) void timer_init()
在main()-->init1()中调用该函数初始化APP定时器,主要是设置APP定时器的链表。
b) void timers_create(void)
在main()-->init2()中调用该函数建立APP定时器,其实就是填充各APP定时器链表。
c) void RTC1_IRQHandler(void)
RTC1中断,为1ms一次的中断。在timer_init()中初始化该中断。在该中断中主要调用timer_timeouts_check()遍历APP定时器链表。
d) void SWI0_IRQHandler(void)
软件中断0。