在gd32e230上做bootloader跳转到application时添加 __set_MSP( * ( __IO uint32_t * ) App_Addr )这一句初始堆栈指针就无法跳转,但是去掉这句话就可以正常跳转,请教一下各位 这是怎么回事?实在想不明白以下是跳转程序。
void IAP_ExecuteApp (uint32_t App_Addr)
{
uint32_t JumpAddress;
usart_disable(USART0);
JumpAddress = * ( __IO uint32_t * )(App_Addr + 4); //用户代码区第二个字为程序开始地址(复位地址)
// __set_MSP( * ( __IO uint32_t * ) App_Addr ); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
(*( void (*)( ) )JumpAddress) (); //跳转到APP.
}
第二个遇到的问题:在用bootloader进行程序升级测试时,划分三个区,分别是bootloder区,app1主程序区,app2待升级程序区。在测试时直接把待升级程序下载到所划分的区域中,然后利用bootloader copy到app1主程序区时,就在也没办法跳转了,下面是程序,恳请各位帮忙看看!感谢!
搬运app2程序到app1
unsigned int temp[64]={0}; //4个字节的数组
void MoveCode(unsigned int src_addr, unsigned int des_addr, unsigned int byte_size)
{
/*1.擦除目的地址 前512K(bank0)地址,每页大小2KB,BANK1每页大小4KB*/
SerialPutString("> Start erase des flash......\r\n");
memset(temp,0,sizeof(temp));
erase_page(des_addr, (byte_size/FMC_PAGE_SIZE)); //删除app1的代码
SerialPutString("> Erase des flash down......\r\n");
/*2.开始拷贝*/
SerialPutString("> Start copy......\r\n");
for(int i = 0; i < byte_size/(64*4); i++)
{
ReadFlash_U32((src_addr + i*64*4), temp, 64*4); //从APP2地址中读出
FLASH_Program((des_addr + i*64*4), 64*4, temp);//按字写入APP1地址
memset(temp,0,sizeof(temp));
}
SerialPutString("> Copy down......\r\n");
/*3.擦除源地址*/
SerialPutString("> Start erase src flash......\r\n");
erase_page(src_addr, (byte_size/FMC_PAGE_SIZE)); //擦除 APP2内容
SerialPutString("> Erase src flash down......\r\n");
}
**读若干个数据 4个字节**
```c
void ReadFlash_U32(uint32_t addr, uint32_t * buff, uint16_t word_size)
{
for(int i =0; i < (word_size/4); i++)
{
buff[i] = *(__IO uint32_t*)(addr + 4 * i);
}
}
**写入程序**
```c
TestStatus FLASH_Program(uint32_t WRITE_START_ADDR, uint16_t Size, uint32_t *data)
{
uint32_t see_data=0;
uint32_t Address;
TestStatus TransferStatus = PASSED;
uint32_t i;
/* Unlock the Flash Bank1 Program Erase controller */
fmc_unlock();
/* Clear All pending flags */
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
/* Program Flash Bank1 */
Address = WRITE_START_ADDR;
i = 0;
while(Address < (WRITE_START_ADDR + Size))
{
fmc_word_program(Address, data[i]);
see_data=*(uint32_t*)Address;
if ( see_data!= data[i])
{
TransferStatus=FAILED;//校验失败
SerialPutString("FAILED\r\n");
}
i++;
Address = Address + 4;
fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_WPERR | FMC_FLAG_PGERR);
}
fmc_lock();
return TransferStatus;
}