话说上周末
约了5年的女神终于答应跟我去吃饭了
中午跟他去吃猪扒饭
我坐在对面静静的看着她吃饭的样子
甚可爱,就忍不住多看了几眼
tibYmDzmEV0HZ9iaOXo32Gyialb71PkKicGs3201vThHL3EPJmPW19OK4SAMgYn13ibXkuKjZw/0" style="height:auto !important;" />
发现我偷看之后,她脸一红
说:你看什么呢?
突然间,我有点紧张,不知所措
说道:“没什么,你吃吧,我看猪扒饭呢”
她正在扒饭的手一顿。。。抬起头看着我
然后。。。。。
好言归正传,
智能产品迅猛发展,今天我们就来揭秘百度手环。
我们先来看看百度手环的OTA。
OTA是指空中升级,百度手环的OTA使用蓝牙通过APP把.bin文件发到手环进行固件升级。这样就可以对设备进行远程升级、维护了是不是很吊。
51822是百度手环采用的低功耗蓝牙,下面我们解读一下他的OTA。
先看他的ROM组成。
可以看出来,在Flash里烧了三个代码(常见单片机只烧一个)。
他由BOOTLOADER
APPLICATION
SOFTDEVICE三部分代码组成,
还有一部分是SWAP这部分是进行OTA时存放接收手机发过来的Bin文件的。
SOFTDEVICE是官方提供的HEX,我们不能修改。
nRF51822程序加载顺序
1)SoftDevice加载;
2)SoftDevice初始化蓝牙协议栈;
3)SoftDevice检查0x10001014处是否保存有有效的BootLoader地址, 如果不是跳转到0x14000处的APP执行,流程结束.
4)SoftDevice跳转到BootLoader
5)BootLoader进行他的业务处理工作;
6)BootLoader跳转到0x14000处的APP执行,流程结束.
下面介绍百度手环的成个代码关于OTA的工作流程。
1:SoftDevice加载;
2:SoftDevice初始化蓝牙协议栈;
3:我们已经有 Bootloader了所以他检查Bootloader是不是合理
代码: APP_ERROR_CHECK_BOOL(NRF_UICR->CLENR0 == CODE_REGION_1_START);//检测BOOTLOADER是否存在
4:检查Bootloader标志位if (should_enter_bootloader || (wdt_reset & 0x02))
if进入OTA模式 err_code = bootloader_dfu_start();//进入OTA里面完成:蓝牙连接,BIN传到WSAP.
等待完成进入。
然后进入APP(是否设置标志位都进入)
//跳到DFU_BANK_0_REGION_START(0x00014000) application程序存放的首地址跳过去就不会往下运行了
bootloader_app_start(DFU_BANK_0_REGION_START);
5:进入APP后如果设置标志位,然后复位循环以上的。
注意:Bootloader和Application还有SoftDevice是三个独立的代码,
其中SoftDevice是官方提供的HEX文件,(S110、S120或者S130等蓝牙协议)不可修改。
代码分析
这时Application工程中的触发OTA模式
/**********************************************************************
* User to reset the MCU & enter OTA
***********************************************************************/
void trigger_ota_mode(void)
{
sd_power_gpregret_set(0x01);//设置一个保留的寄存器为0X01(作为启动OTA的标志)
//reset the system and start OTA
NVIC_SystemReset();//复位进入OTA
}
然后再BOOTLOADER里判断标志位。
uint8_t should_enter_bootloader = NRF_POWER->GPREGRET & 0xff;
uint16_t wdt_reset = (NRF_POWER->RESETREAS) & (0xFFFF);
if (should_enter_bootloader || (wdt_reset & 0x02))
满足进入OTA,不满足跳转Application。
简单的说就是:
设置标志位》判断》进入》运行》跳转到APP。
下面是BOOTLOAER mian完整代码
int main(void)
{
uint32_t err_code;
wdt_stop(); //stop wdt whether it started or not
leds_init();
// This check ensures that the defined fields in the bootloader corresponds with actual
// setting in the nRF51 chip.
APP_ERROR_CHECK_BOOL(NRF_UICR->CLENR0 == CODE_REGION_1_START);//检测BOOTLOADER是否存在
//检查BOOTLOADER的地址是不是0X03C800
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();
//进入 OTA的条件, application程序中 sd_power_gpregret_set(0x01);就是设置这个 NRF_POWER->GPREGRET
uint8_t should_enter_bootloader = NRF_POWER->GPREGRET & 0xff;
uint16_t wdt_reset = (NRF_POWER->RESETREAS) & (0xFFFF);
if (should_enter_bootloader || (wdt_reset & 0x02))
{
nrf_gpio_pin_set(LED1);
// Initiate an update of the firmware.
err_code = bootloader_dfu_start();//进入OTA里面完成:蓝牙连接,BIN传到WSAP.
APP_ERROR_CHECK(err_code);
nrf_gpio_pin_clear(LED1);
}
//exit from DFU unit so just Start application
//进入OTA条件不满足进入application
{
//set retain register
NRF_POWER->GPREGRET = 0x00;//清0
//clear AIRCR register
NRF_POWER->RESETREAS = 0x04;
if(wdt_reset & 0x02) {
NRF_POWER->RESETREAS = 0x02;
}
// Select a bank region to use as application region.
// @note: Only applications running from DFU_BANK_0_REGION_START is supported.
//跳到DFU_BANK_0_REGION_START(0x00014000) application程序存放的首地址跳过去就不会往下运行了
bootloader_app_start(DFU_BANK_0_REGION_START);
}
leds_off();
//comes here should reenter DFU
//这里重新进入OTA应该是如果bootloader_app_start(DFU_BANK_0_REGION_START);失败
NRF_POWER->GPREGRET = 0x01;
NVIC_SystemReset();//复位重新进入OTA因为NRF_POWER->GPREGRET = 0x01;
}
大家看完帮我看看上面的问题。。。。