除SWJ-DP外的所有调试组件。有关系统中不同调试组件的更多信息,请参阅第72页的调试和跟踪。如果设备处于调试接口模式,则禁止从CPU锁定复位。CPU锁定是不可能在系统关闭。
如果设备处于调试接口模式,则Debug组件不会被重置。从OFF模式唤醒时RAM不会被重置,但根据RAM寄存器部分的设置,或整个RAM,在设备进入系统OFF模式后可能不会被保留。看门狗重置在系统关闭不可用.
因此在某些特殊情况下将数据临时存储在RAM或寄存器中更加合适,如.上图中标星的情形。应用中常用到的场景比如:
- 在进行DFU (OTA) 功能时,无论从应用程序跳转到bootloader (NVIC_ SystemReset),还是从bootloader跳转到应用程序,都可以用RAM或寄存器来传递变量、标志等。
- 应用程序有类似日历功能的应用,并且不希望其数据在应用重启时被清空。
#define ENTER_PAIR_GPREGRET2_MASK (0xF8)
#define ENTER_PAIR_GPREGRET2 (0x58)
#define ENTER_PAIR_BIT_MASK (0x01)
#define ENTER_PAIR_START (ENTER_PAIR_GPREGRET2 | ENTER_PAIR_BIT_MASK)
#define DTM_GPREGRET2_MASK (0xF8)
#define DTM_GPREGRET2 (0x58)
#define DTM_BIT_MASK (0x02)
#define DTM_START (DTM_GPREGRET2 | DTM_BIT_MASK)
#define RADIO_TEST_GPREGRET2_MASK (0xF8)
#define RADIO_TEST_GPREGRET2 (0x58)
#define RADIO_TEST_BIT_MASK (0x04)
#define RADIO_TEST_START (RADIO_TEST_GPREGRET2 | RADIO_TEST_BIT_MASK)
#define LED_OFF_GPREGRET2_MASK (0xF8)
#define LED_OFF_GPREGRET2 (0x48)
#define LED_OFF_BIT_MASK (0x01)
#define LED_OFF_START (LED_OFF_GPREGRET2 | LED_OFF_BIT_MASK)
// 写GPREGRET寄存器之前,需要先Clear
err_code = sd_power_gpregret_clr(0, 0xffffffff);
VERIFY_SUCCESS(err_code);
err_code = sd_power_gpregret_set(0, ENTER_PAIR_START);
VERIFY_SUCCESS(err_code);
原理简介:
对于单片机做的产品,要实现在线升级,单片机内部一般是两段代码,一个是bootloader程序,一个是用户app程序,bootloader程序主要就是实现app升级的程序,它是单片机上电后首次运行的程序,app程序就是实现产品功能的程序。
对于nRF51822来说,稍微有点特殊,但是本质原理也是一样的,nRF51822芯片内部有段SoftDevice的程序,它是芯片上电后首次运行的程序,不过这段程序不负责程序升级,它是Nordic官方提供的蓝牙协议栈程序,当然它也具备一点bootloader的功能,也就是说,芯片上电后,它会判断芯片内部是否有bootloader代码(bootloader代码位置固定,所以它能判断出是否有合法的bootloader程序),若有bootloader程序则会跳转到bootloader程序执行,若没有bootloader程序而只检测到了用户的app程序,那么就直接跳转到app程序运行,当然这个bootloader程序是我们自己写的代码,只是它存储的位置和app程序是不一样的。
bootloader程序差不多也只做两件事情,1:控制程序的跳转,比如跳转到app程序;2:实现app程序升级;
当然bootloader是我们自己写的,你要实现更多的功能也是可以的,但是最基本的功能就是这两个,bootloader运行后,检测直接跳转到app的条件是否满足(app程序合法,相关标志位合法),若满足就直接跳转到app执行app程序,若不满足就继续执行bootloader,等待升级的相关操作命令;
手机端DFU功能简介:
单片机段程序准备好了,当然就需要手机端程序来实现固件的升级了,主要工作流程如下:
1,扫描蓝牙设备,连接蓝牙设备,查询蓝牙设备是否支持DFU服务;
2,若支持DFU服务,那么将本地的固件通过蓝牙发送出去;
3,数据发送完毕,升级固件成功
所谓DFU(Device Firmware Update),就是设备固件升级的意思,而OTA(Over The Air)是实现DFU的一种方式而已,准确说,OTA的全称应该是OTA DFU,即通过空中无线方式实现设备固件升级。只不过大家为了方便起见,直接用OTA来指代固件空中升级(有时候大家也将OTA称为FOTA,即Firmware OTA,这种称呼意思更明了一些)。只要是通过无线通信方式实现DFU的,都可以叫OTA,比如2G/3G/4G/WiFi/蓝牙/NFC/Zigbee,他们都支持OTA。DFU除了可以通过无线方式(OTA)进行升级,也可以通过有线方式进行升级,比如通过UART,USB或者SPI通信接口来升级设备固件。
不管采用OTA方式还是有线通信方式,DFU包括后台式(background)和非后台式两种模式。后台式DFU,又称静默式DFU(Silent DFU),在升级的时候,新固件在后台悄悄下载,即新固件下载属于应用程序功能的一部分,在新固件下载过程中,应用可以正常使用,也就是说整个下载过程对用户来说是无感的,下载完成后,系统再跳到BootLoader模式,由BootLoader完成新固件覆盖老固件的操作,至此整个升级过程结束。比如智能手机升级Android或者iOS系统都是采用后台式DFU方式,新系统下载过程中,手机可以正常使用哦。非后台式DFU,在升级的时候,系统需要先从应用模式跳入到BootLoader模式,由BootLoader进行新固件下载工作,下载完成后BootLoader继续完成新固件覆盖老固件的操作,至此升级结束。早先的功能机就是采用非后台式 DFU来升级操作系统的,即用户需要先长按某些按键进入bootloader模式,然后再进行升级,整个升级过程中手机正常功能都无法使用。
下面再讲双区DFU(dual bank)和单区DFU(single bank),双区或者单区DFU是新固件和老固件覆盖的两种方式。后台式DFU必须采用双区模式进行升级,即老系统(老固件)和新系统(新固件)各占一块bank(存储区),假设老固件放在bank0中,新固件放在bank1中,升级的时候,应用程序先把新固件下载到bank1中,只有当新固件下载完成并校验成功后,系统才会跳入BootLoader模式,然后擦除老固件所在的bank0区,并把新固件拷贝到bank0中。非后台式DFU可以采用双区也可以采用单区模式,与后台式DFU相似,双区模式下新老固件各占一块bank(老固件为bank0,新固件为bank1),升级时,系统先跳入BootLoader模式,然后BootLoader程序把新固件下载到bank1中,只有新固件下载完成并校验成功后,才会去擦除老固件所在的bank0区,并把新固件拷贝到bank0区。单区模式的非后台式DFU只有一个bank0,老固件和新固件分享这一个bank0,升级的时候,进入bootloader模式后立马擦除老固件,然后直接把新固件下载到同一个bank中,下载完成后校验新固件的有效性,新固件有效升级完成,否则要求重来。跟非后台式DFU双区模式相比,单区模式节省了一个bank的Flash空间,在系统资源比较紧张的时候,单区模式是一个不错的选择。不管是双区模式还是单区模式,升级过程出现问题后,都可以进行二次升级,都不会出现“变砖”情况。不过双区模式有一个好处,如果升级过程中出现问题或者新固件有问题,它还可以选择之前的老固件老系统继续执行而不受其影响。而单区模式碰到这种情况就只能一直待在bootloader中,然后等待二次或者多次升级尝试,此时设备的正常功能已无法使用,从用户使用这个角度来说,你的确可以说此时设备已经“变砖”了。所以说,虽然双区模式牺牲了很多存储空间,但是换来了更好的升级体验。