2676|0

21

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

做了一个简单的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启动

此帖出自stm32/stm8论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表