做了一个简单的stm32 bootloader,从SD卡里读文件启动
[复制链接]
由于需要文件系统,所以直接从正点原子的文件系统例程改,先准备flash擦写函数
//从指定位置擦除flash
由于是stm32f103ze,有512kb内存,
app函数指定从0x8040000开始
#define START_ADDRESS 0x8040000
void FLASH_EraseAll(u32 datasize)
{
u8 i;
u8 page = datasize/2048+1;
FLASH_Unlock();
for(i=0;i<page;i++)
FLASH_ErasePage(START_ADDRESS +(i*2048));
FLASH_Lock();
}
//从指定位置写数据
void Flash_WriteU16(u32 addr,u16 data)
{
if(addr<START_ADDRESS)
return ;
FLASH_Unlock();
FLASH_ProgramHalfWord(addr,data);
FLASH_Lock();
}
主函数从sd卡里读app.bin文件,有的话就拷贝复制,如果没有就读内部flash,地址有效就从内部启动
FIL fnew;
FRESULT res;
u16 buf[4];
u32 msp;
u32 reset;
extern FATFS *fs[_VOLUMES];
extern UINT br,bw;
void Bootloader_Jump(u32 Sect,u32 Msp ,u32 Reset);
void Start_From_FLASH(void);
int main(void)
{
u32 total,free;
u8 t=0;
u32 i = 0;
u8 data[2];
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
my_mem_init(SRAMIN); //初始化内部内存池
while(SD_Init())//检测不到SD卡
{
printf("SD Card Error!\r\n");
delay_ms(500);
printf("Please Check!\r\n");
delay_ms(500);
LED0=!LED0;//DS0闪烁
}
exfuns_init(); //为fatfs相关变量申请内存
f_mount(fs[0],"0:",1); //挂载SD卡
while(exf_getfree("0",&total,&free)) //得到SD卡的总容量和剩余容量
{
printf("SD Card Fatfs Error!\r\n");
delay_ms(500);
LED0=!LED0;//DS0闪烁
}
printf("FATFS OK!\r\n");
printf("SD Total Size: %d MB\r\n",total>>10);
printf("SD Free Size: %d MB\r\n",free>>10);
/*
进入bootloader
*/
res = f_open(&fnew,"0:app.bin",FA_OPEN_EXISTING|FA_READ);
if(res == FR_OK)//打开成功?
{
printf("open succesfully \r\n");
FLASH_EraseAll(fnew.fsize+1);
printf("fnew.fsize is %d \r\n",fnew.fsize);
f_lseek(&fnew,0);
br = 0;
for(i=0; i<fnew.fsize;i++)
{
f_read(&fnew,data,2,&br);
Flash_WriteU16(START_ADDRESS+i*2,data[0]+(data[1]<<8));
}
f_lseek(&fnew,0);
br = 0;
for(i=0;i<20;i++)
{
f_read(&fnew,data,2,&br);
}
f_close(&fnew);
f_mount(0,"0:",1); //卸载SD卡
printf("jump to the app\r\n");
FLASH_ReadBuffer(START_ADDRESS,buf,4);
msp = buf[0]+(buf[1]<<16);
reset = buf[2]+(buf[3]<<16);
Bootloader_Jump(START_ADDRESS,msp,reset);
}
else
{
printf("open app bin flie error \r\n");
Start_From_FLASH();
}
/*
end
*/
while(1)
{
delay_ms(200);
LED0=!LED0;
}
}
void Bootloader_Jump(u32 Sect,u32 Msp ,u32 Reset)
{
u32 base;
u32 offset;
if ((Msp &0x2FFE0000 ) == 0x20000000)//地址有效判断
printf("legal!!!!!!!!!!!!!! %x\r\n",Msp );
else
{
printf("illegal!!!!!!!!!!!!!! %x\r\n",Msp );
return;
}
base =(Sect>NVIC_VectTab_FLASH)?NVIC_VectTab_FLASH:NVIC_VectTab_RAM;
offset = Sect-base;
NVIC_SetVectorTable(base,offset);
__set_MSP(Msp);
((void(*)())(Reset))();
}
void Start_From_FLASH(void)
{
printf("Start_From_FLASH \r\n");
FLASH_ReadBuffer(START_ADDRESS,buf,4);
msp = buf[0]+(buf[1]<<16);
reset = buf[2]+(buf[3]<<16);
Bootloader_Jump(START_ADDRESS,msp,reset);
}
这个还是有些简陋,准备继续调试从串口或者直接将程序烧写至spiflash,然后利用sdram启动
|