一、概述
对于 CH592(448KB Flash),44KB 的 APP 空间往往无法满足复杂应用的需求。通过将协议栈从默认的 0x00010000 后移至 0x00040000,可 将 APP 区域扩展至 236KB,同时 IAP 区域也相应后移。
扩容后地址布局:
| 区域 | 起始地址 | 大小 | 说明 |
|---|---|---|---|
| Jump IAP | 0x00000000 | 4 KB | 跳转至 IAP 新地址 |
| APP | 0x00001000 | 236 KB | 4KB ~ 240KB |
| IAP | 0x0003C000 | 16KB | 240KB ~ 256KB |
| LIB(协议栈) | 0x00040000 | 192 KB | 256KB ~ 448KB,使用 CH59xBLE_ROMx.hex |
下面分别介绍 Jump IAP、APP、IAP 三个工程的修改步骤。
二、Jump IAP 工程修改(1 处)
修改启动文件(Startup.s)
Jump IAP 的功能仅为跳转至 IAP 起始地址。
j 0x3C000 /* 跳转至 IAP 新起始地址 0x0003C000 */
三、APP 工程修改(6 处)
整个配置过程分为以下四个步骤。为保持配置一致性,必须直接先复制粘贴 OnlyUpdateApp_Peripheral 例程中的 Link.ld 和 Startup.s 文件,然后再根据当前工程需求进行以下修改:
步骤1:修改链接脚本文件(Link.ld)
Link.ld 文件定义了各个存储区域的起始地址与占用空间。使用固定库时协议栈被放置于Flash的高地址区域,因此需要相应调整应用程序(APP)区域的起始地址与占用空间。
以起始地址为 0x00040000 的 CH59xBLE_ROMx.hex 为例,修改后的 MEMORY 配置如下:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00001000, LENGTH = 236K /* APP从4KB开始,可用236KB */
RAM (xrw) : ORIGIN = 0x20002000, LENGTH = 18K /* 0x20000000~0x20002000预留给协议栈 */
}
注意:此处 LENGTH = 236K 即对应地址范围 0x00001000 ~ 0x0000BFFF(4KB ~ 240KB),与JUMP IAP区域(0KB-4KB)IAP区域(240KB~256KB)无缝衔接。
步骤2:修改启动文件(Startup.s)
启动文件(startup_CH592.S)在使用固定库时需要配置跳转目标地址,使其跳转至固定库所在的起始地址。修改汇编跳转指令如下:
la t0, main
csrw mepc, t0
j 0x40000 /* 跳转至协议栈基址,与所选ROM版本一致 */
步骤3:添加固定库使能宏定义
在工程的预处理宏定义中,需添加 CH59xBLE_ROM=1,用于启用 ROM 固定库。该宏会引导 CONFIG.h 头文件包含 CH59xBLE_ROM.h(而非 CH59xBLE_LIB.h ),从而调用固化的协议栈 API 。
工程中所有包含协议栈头文件的地方,严禁直接包含 CH59xBLE_LIB.h ,必须统一采用如下条件编译写法:
#ifdef CH59xBLE_ROM
#include "CH59xBLE_ROM.h"
#else
#include "CH59xBLE_LIB.h"
#endif
步骤4:添加固定库地址宏定义
程序中需要添加固定库对应地址的宏定义,使编译系统明确协议栈固件在 Flash 中的具体位置。在预处理宏中添加:
LIB_FLASH_BASE_ADDRESS=0x00040000
步骤5:添加OTA文件标志
为使手机APP能识别有效的升级固件,需在应用程序中嵌入一个固定的标志位。该标志将被放置在独立的段(section)中,供IAP程序读取判断。
在代码中添加如下定义:
/* 用于IAP校验文件有效性的标志 */
const uint32_t Address = 0xFFFFFFFF;
__attribute__((aligned(4))) uint32_t Image_Flag __attribute__((section(".ImageFlag"))) = (uint32_t)&Address;
说明:Image_Flag 的值固定为 &Address(即 0xFFFFFFFF 的地址),实际值可根据需要调整。该段需在链接脚本中显式放置,确保位于APP固件的固定偏移处。
步骤6:添加OTA跳转程序
通过蓝牙特性写入触发 OTA 升级。本例使用 SIMPLEPROFILE_CHAR3 特性接收任意一字节数据后调用 Jump_OTA() 函数设置升级标志并执行软复位。首先,在特性回调函数中添加跳转处理:
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
{
switch(paramID)
{
case SIMPLEPROFILE_CHAR1:
{
uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
tmos_memcpy(newValue, pValue, len);
PRINT("profile ChangeCB CHAR1.. \n");
break;
}
case SIMPLEPROFILE_CHAR3:
{
uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
tmos_memcpy(newValue, pValue, len);
PRINT("profile ChangeCB CHAR3..\n");
PRINT("jump OTA \n");
mDelaymS(5);
Jump_OTA(); /* 触发OTA跳转 */
break;
}
default:
break;
}
}
其次,实现 Jump_OTA() 函数,该函数在DataFlash中写入OTA标志,然后复位芯片,使Jump IAP程序判断该标志并引导至IAP升级流程。
/* OTA升级标志值 */
#define IMAGE_OTA_FLAG 0x03
/* DataFlash存储地址(需避开蓝牙协议栈使用的区域) */
#define OTA_DATAFLASH_ADD 0x00076000 - FLASH_ROM_MAX_SIZE
/* DataFlash临时缓冲区 */
__attribute__((aligned(8))) uint8_t block_buf[16];
/*********************************************************************
* @fn Jump_OTA
*
* @brief 设置OTA标志并软复位,跳转至IAP
*
* @return none
*/
void Jump_OTA(void)
{
uint16_t i;
uint32_t ver_flag;
/* 读取第一块DataFlash原有数据 */
EEPROM_READ(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
/* 擦除第一块DataFlash */
EEPROM_ERASE(OTA_DATAFLASH_ADD, EEPROM_PAGE_SIZE);
/* 更新Image信息,写入OTA标志 */
block_buf[0] = IMAGE_OTA_FLAG;
/* 编程DataFlash */
EEPROM_WRITE(OTA_DATAFLASH_ADD, (uint32_t *)&block_buf[0], 4);
/* 执行软复位,Jump IAP将根据标志决定是否进入IAP */
SYS_ResetExecute();
}
四、IAP 工程修改(4 处)
步骤1:修改链接脚本(Link.ld)
链接脚本(.ld)定义了各存储区域的基址与长度。根据地址规划,将APP区域起始地址设为 0x0003C000,长度设为 16KB;同时调整RAM起始地址,为协议栈保留前8KB空间。
MEMORY
{
FLASH (rx) : ORIGIN = 0x0003C000, LENGTH = 16K /* IAP从240KB开始,可用16KB */
RAM (xrw) : ORIGIN = 0x20002000, LENGTH = 18K /* 0x20000000~0x20002000预留给协议栈 */
}
注意:此处 LENGTH = 16K 即对应地址范围 0x0003C000 ~ 0x00040000(240KB ~ 256KB),与APPP区域(4KB-240KB)ROM区域(256KB~448KB)无缝衔接。
步骤2:修改启动文件(Startup.s)
启动文件(startup_CH592.S)在使用固定库时需要配置跳转目标地址,使其跳转至固定库所在的起始地址。修改汇编跳转指令如下:
la t0, main
csrw mepc, t0
j 0x40000 /* 跳转至协议栈基址,与所选ROM版本一致 */
步骤3:添加固定库地址宏定义
程序中需要添加固定库对应地址的宏定义,使编译系统明确协议栈固件在 Flash 中的具体位置。在预处理宏中添加:
LIB_FLASH_BASE_ADDRESS=0x00040000
步骤4:修改ota.h中app占用大小
#define IMAGE_A_SIZE 236 * 1024
五、固件烧录与 OTA 验证
1.固定烧录
使用最新版 WCHISPTOOL 直接选择四个 HEX 文件(JUMP IAP/APP/IAP/ROM)进行烧录。
ps:使用带 x 后缀的版本:CH59xBLE_ROMx.hex(起始地址 0x00040000)。
2.OTA验证
验证 OTA 流程:烧录完成后,使用 BLE 调试助手连接设备,向特征 CHAR3 写入任意 1 字节数据,触发跳转至 IAP,设备名称将更新为 OTA_OTA_OTAOTA ,使用 OTA APP 选择新固件进行升级。
浙公网安备 33010602011771号