OTA(Over-the-air programming) 叫做空中编程, 这里用它来做系统升级
目录
1.开启OTA功能的方法
2.开启失败的问题排查
3. 开启OTA功能后的Flash布局
4. 系统是如何进入OTA模式的
5. OTA传输过程 - 镜像是怎么发送到设备的
6.OTA启动升级流程 - 镜像是怎么样替换的
开启OTA的方法是修改export OTA_BASIC ?= 1
作者在实际操作的过程中遇到按以上方法修改仍然不成功的问题, 最后查出来是两个原因
第一个原因和以下问题有关:
在common.mk和config中的target.mk中分别定义OTA_BASIC的值为1和0,请问在哪个文件中定义的值会生效?
答: 这个和根目录下的Makefile有关, 因为文件包含的数据序是common.mk在后, 所以生效的是在common.mk中的定义, 所以调试时建议在common.mk尾部打印相关信息.
相关代码如下
TARGET_CFG_FILE = config/$(T)/target.mk
TARGET_COMMON_FILE = config/common.mk
include $(srctree)/$(TARGET_CFG_FILE)
include $(srctree)/$(TARGET_COMMON_FILE)
第二个原因:
在target.mk中定义了GOOGLE_SERVICE_ENABLE为1,而在common.mk中此宏的相关判断将OTA_BASIC设置为1了
所以虽然已经在两个.mk文件中export OTA_BASIC ?= 1, 结果OTA还是生效,
其布局是这样的
以下是相关代码:
// common.mk
ifneq ($(filter 1,$(OTA_BASIC) $(BES_OTA_BASIC)),)
export OTA_CODE_OFFSET ?= 0x18000
endif
ifneq ($(filter 1,$(OTA_BASIC) $(BES_OTA_BASIC)),)
KBUILD_CPPFLAGS += -D__APP_IMAGE_FLASH_OFFSET__=$(OTA_CODE_OFFSET)
KBUILD_CPPFLAGS += -DNEW_IMAGE_FLASH_OFFSET=0x200000
KBUILD_CPPFLAGS += -DFIRMWARE_REV
endif # OTA
// best1000.lds.S
#if !defined(OTA_BOOT_SIZE) && defined(OTA_CODE_OFFSET)
#define FLASH_REGION_BASE (FLASH_BASE + OTA_CODE_OFFSET)
#else
#define FLASH_REGION_BASE (FLASH_BASE)
#endif
// ota_control.c
void ota_flash_init(void)
{
// 部分省略
new_image_copy_flash_offset = NEW_IMAGE_FLASH_OFFSET;
}
ps:从代码来看,BES_OTA_BASIC也可能导致OTA功能的开启
思考题:
对于没有使能OTA的工程, 如果给他多烧写一个OTA镜像会怎么样?
设置寄存器值HAL_SW_BOOTMODE_ENTER_HIDE_BOOT, 然后重启
流程图:
代码:
// 这只是其中一处, 并未包含所有准备工作
void app_otaMode_enter(APP_KEY_STATUS *status, void *param)
{
hal_norflash_disable_protection(HAL_NORFLASH_ID_0);
hal_sw_bootmode_set(HAL_SW_BOOTMODE_ENTER_HIDE_BOOT);
hal_cmu_sys_reboot();
}
判定到有新的镜像后, 会记录新镜像信息, 切换到需要拷贝镜像的状态, 并重启,
拷贝新镜像到之前镜像的位置, 恢复到普通启动状态
欢迎阅读更多 BES专栏文章