IAP(In Application Programming)即在应用编程
下面是STM32-IAP过程
1.接收更新代码,为二进制文件
由于内置RAM只有256KB,因此我将接收的数据丢到外部SDRAM里
uint8_t g_RxBuf1[UART1_RX_BUF_SIZE] __attribute__ ((at(SDRAM_APP_BUF))); /* 接收缓冲区 */
2.将代码从SDRAM复制到FLASH
首先解锁FALSH
然后写FLASH
最后再上锁
/* FLASH 解锁 ********************************/
/* 使能访问FLASH控制寄存器 */
FLASH_Unlock();
/* 擦除用户区域 (用户区域指程序本身没有使用的空间,可以自定义)**/
/* 清除各种FLASH的标志位 */
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
uwStartSector = GetSector(FLASH_USER_START_ADDR);
uwEndSector = GetSector(FLASH_USER_END_ADDR);
/* 开始擦除操作 */
uwSectorCounter = uwStartSector;
while (uwSectorCounter <= uwEndSector)
{
/* VoltageRange_3 以“字”的大小进行操作 */
if (FLASH_EraseSector(uwSectorCounter, VoltageRange_3) != FLASH_COMPLETE)
{
/*擦除出错,返回,实际应用中可加入处理 */
return -1;
}
/* 计数器指向下一个扇区 */
if (uwSectorCounter == FLASH_Sector_11)
{
uwSectorCounter += 40;
}
else
{
uwSectorCounter += 8;
}
}
/* 以“字”的大小为单位写入数据 ********************************/
uwAddress = FLASH_USER_START_ADDR;
while (uwAddress < FLASH_USER_START_ADDR + applen)
{
W_word = 0;
while(i < applen)
{
W_word = (uint32_t)g_RxBuf1[i + 3] << 24;
W_word |= (uint32_t)g_RxBuf1[i + 2] << 16;
W_word |= (uint32_t)g_RxBuf1[i + 1] << 8;
W_word |= (uint32_t)g_RxBuf1[i];
i = i + 4;
if (FLASH_ProgramWord(uwAddress, W_word) == FLASH_COMPLETE)
{
uwAddress = uwAddress + 4;
}
else
{
/*写入出错,返回,实际应用中可加入处理 */
return -1;
}
}
}
/* 给FLASH上锁,防止内容被篡改*/
FLASH_Lock();
3.检查栈顶地址,跳转到新的APP
typedef void (*iapfun)(void); //定义一个函数类型的参数.
if(((*(vu32*)appxaddr)&0x2FF00000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
以上就是IAP的大致过程。