1.BootLoader和app程序的跳转
BootLoader程序设置为64KB,
核心是分散加载文件的内容。
程序跳转函数
void iap_jump_app(uint32_t appaddr)
{
if(((*(uint32_t*)appaddr)&0x2FF00000)==0x20000000) // 检查栈顶地址是否合法.
{
/* Initialize user application's Stack Pointer & Jump to user application */
JumpToApplication = (pFunction) (*(__IO uint32_t*) (appaddr + 4)); // 用户代码区第二个字为程序开始地址(复位地址)
__set_MSP(*(__IO uint32_t*) appaddr); // 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
JumpToApplication(); // 跳转到APP.
}
}
APP程序设置
APP地址偏移
生成bin文件
命令内容为“$K\ARM\ARMCC\bin\fromelf.exe --bin --output=Bin@L.bin !L”
2.传输协议
2.1Ymodem 文件传输协议
协议内容
传输案例
2.2 Ymodem上位机
secure crt安装完成后,使用串口进行传输数据
3.FLASH
/**
* @brief 此函数对所有用户闪存区域进行擦除a
* @param start: 用户闪存区域的开始
* @retval FLASHIF_OK : 用户闪存区域成功擦除
* FLASHIF_ERASEKO : 发生了错误
*/
uint32_t FLASH_If_Erase(uint32_t start)
{
uint32_t FirstSector = 0,NbrOfPages = 0;
uint32_t PageError = 0;
FLASH_EraseInitTypeDef pEraseInit;
HAL_StatusTypeDef status = HAL_OK;
/* 解锁闪存以启用闪存控制寄存器访问 *************/
HAL_FLASH_Unlock();
/* 获取启动用户闪存区域的扇区 */
NbrOfPages = (USER_FLASH_END_ADDRESS - start)/FLASH_PAGE_SIZE;
pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
// pEraseInit.Banks = start;
pEraseInit.Banks = FLASH_BANK_1;
pEraseInit.Sector = FLASH_SECTOR_1;
pEraseInit.NbSectors = NbrOfPages;
pEraseInit.VoltageRange=FLASH_VOLTAGE_RANGE_4;
printf("erase bank=%d,nbsectors=%d\r\n",FLASH_BANK_1,NbrOfPages+1);
status = HAL_FLASHEx_Erase(&pEraseInit, &PageError);
/* 锁定闪存以禁用闪存控制寄存器访问(建议保护闪存免受可能不必要的操作)*********/
HAL_FLASH_Lock();
printf("erase status=%d\r\n",status);
if (status != HAL_OK)
{
/* 页面擦除时发生错误 */
return FLASHIF_ERASEKO;
}
return FLASHIF_OK;
}
/* Public functions ---------------------------------------------------------*/
/**
* @brief 此函数在闪存中写入数据缓冲区 (数据是32位对齐的).
* @note 写入数据缓冲区后,检查闪存内容
* @param destination: 目标位置的起始地址
* @param p_source: 指向要写入数据的缓冲区的指针
* @param length: 数据缓冲区的长度(单位是32位字)
* @retval uint32_t 0: 数据成功地写入闪存
* 1: 在闪存中写入数据时发生错误
* 2: 闪存中的写入数据不同于预期的数据
*/
uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
{
uint32_t i = 0;
/* 解锁闪存以启用闪存控制寄存器访问 *************/
HAL_FLASH_Unlock();
for (i = 0; (i < length) && (destination <= (USER_FLASH_END_ADDRESS-4)); i+=8)
{
// printf("p_source=%x,destination=%x;length=%d\r\n",p_source,destination,length-i);
/* 设备电压范围应为[2.7V至3.6V],操作将通过Word完成*/
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, destination, (uint32_t*)(p_source)) == HAL_OK)
{
/* 检查写入的值 */
if (*(uint32_t*)destination != *(uint32_t*)(p_source))
{
/* 闪存内容与SRAM内容不匹配 */
printf("FLASHIF_WRITINGCTRL_ERROR,i=%d\r\n",i);
return(FLASHIF_WRITINGCTRL_ERROR);
}
/* 增量Flash目的地地址 */
destination += 32;
p_source += 8;
}
else
{
printf("FLASHIF_WRITING_ERROR\r\n");
/* 在闪存中写入数据时发生错误 */
return (FLASHIF_WRITING_ERROR);
}
}
/* 锁定闪存以禁用闪存控制寄存器访问(建议保护闪存免受可能不必要的操作 *********/
HAL_FLASH_Lock();
return (FLASHIF_OK);
}