FlashDriver(关键代码重定向)

目录

前言

1.驱动源码编写

2.代码重定向

3.获取映像文件

4.使用映像文件


前言

        FlashDriver意为flash驱动代码块,出于某些原因,本地不允许保存修改flash的代码,因此需要更新时,将通过外部接口,传输flash驱动,即用即毁。以STM32F103为例,FlashDriver的应用流程如下:

1.驱动源码编写

        在过程中实现并测试flash驱动,需要注意的是,flashdriver作为独立执行的映像,不允许有外部依耐(即调用其他模块的接口),知名系统库除外(但最好自己实现,如memcpy)。

void waitFlash(void)
{

}

void flash_erase(uint32_t addr, uint32_t cnt)
{


}

uint8_t flash_read(uint32_t addr, uint8_t *buffer, uint32_t len)
{

}

void flash_cpy(uint8_t *des, uint8_t *src, uint32_t len)
{

}
void flash_write(uint32_t addr, uint8_t *buffer, uint32_t len)
{

}

const FlashApi_t fp __attribute__((section("flbase"),used)) = 
{
  .read = flash_read,
  .write = flash_write,
  .erase = flash_erase,
};

2.代码重定向

        既然是打着主意将FlashDriver放到RAM中执行,我们可以自定义sct文件,将flashDriver相关驱动,重定向到RAM中(可能涉及到寻址,这一块我也不太清楚)。

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00004000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x20004000 0x00001000  {  ; RW data
   * (flbase, +First)  ;确保header信息在最前面
   flashDriver.o (+RO +XO +RW +ZI) ;将 flashDriver所有数据放到RW_IRAM2
   ;.ANY (FLASH)
  }
}

        我们可以看到,flashDriver.c所有的所有函数的执行域都在RW_IRAM2中,且header信息位于RW_IRAM2的起始位置。

3.获取映像文件

这里提供两种方法

        1)查看map文件,确定flashdriver的执行地址和映像大小,在Keil command中,输入指令获取hex文件:

SAVE <文件名.hex> <起始地址>, <结束地址>

SAVE flash.hex 0x20004000, 0x200041a0

接着使用Jflash工具将hex转为bin。

        2)查看map文件,可以确定flashDriver的加载地址和映像大小,直接将整个工程的hex导入JFlash,将指定范围的数据导出为bin。

        对比两种方法生成的文件,不能说有点相似,只能说一模一样,啊,不对,这个少一个字节了么?哦,不好意思,区间一般是左闭右开,第二种方法,有可能少一个。

4.使用映像文件

        在没有flash的工程中,使用外部接口,将flashdriver的映像文件传输到指定的RAM区域(为什么不是任意RAM区域:和寻址有关。如果驱动代码实现了位置独立,也不是不可以),通过header信息可直接定位各接口位置。

uint8_t flashBin[512] __attribute__((section(".FLASH"))) = {0};

FlashApi_t *api  = NULL;
void flashInit(void)
{
  memcpy(flashBin, bin_Start, (bin_End- bin_Start)<<2);
  api  = (FlashApi_t*)flashBin;
}
  #ifdef FLASH_TEST
  flashInit();
  #endif

  {
    uint8_t tm[8] ={1,2,3,4,5,6,7,8};
    uint8_t tn[48] ={0};
    api->write(0x08010000, tm ,8);
    tm[0]++;
    api->write(0x08010000+16, tm ,8);
    tm[0]++;
    api->write(0x08010000+32, tm ,8);
    tm[0]++;
    api->read(0x08010000+32, tn ,8);
    api->erase(0x08010000, 1);
  }

结语

        这里偷了个懒,直接用汇编的语法将bin文件写入flash,然后手动拷贝到指定RAM区,模拟外部传输,测试通过~

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值