stm32 RAM 中运行代码的方法-不动分散加载文件在
因特殊需要,iap需要做成 可以更新iap代码的,想了想,也只有ram中运行代码了, 一般iap代码都很小,往往相应的 单片机的ram都要大于 iap代码大小, 所以可以简单点,把iap代码全部复制到ram中,然后来个强制跳转,更新IAP的FLASH,OK, 重启完事^_^。需要注意的是,代码使用位置无关码,这个概念汇编里面比较清楚,即访问资源使用相对地址,一般也都是,如果有疑问,可以在相应汇编窗口下查看是否是相对寻址的代码。下面是主要代码
#include "test.h"u8 inRam;
// 是否在 ram中const u8VER_IAP[4] __attribute__((at(REV_IAP_ADDR_CONTROL))) = {1, 0, 0, 0};
//版本u8ramRunIap[1024*32] __attribute__((at(RAM_CODE_ADDR)));
//sram: 把iap 搬到 ram 运行.../* 为了在ram中执行 所有 const char*字符串数组, 去掉const,
* 这样就会复制到ram,引用也是ram中的, 用到的中断向量需转换地址 */char* CPUID[2];
//= { "fh", "fdh", "fgh", "dfg"};
char* iapFile[2];
//= { "dh.bin", "dgf.bin", "dfhg.bin", "gh.bin", "dfg", "dh" };
//常量指针, 指向flash, 擦除&之后, 不能再访问!!!void* addrCov(void* addr)//访问flash时,改至访问ram 对应的位置
{
return (void*)((u32)addr - FLASH_BASE + RAM_CODE_ADDR);
}void RamVectorSet(void)/* 所以code 复制到ram后, 中断向量改到 ram */
{
u32* p = (u32*)(RAM_CODE_ADDR+4);
//reset vect
u8 i;
p[1] = (u32)addrCov((void*)(p[1]));
//复位向量
p[3] = (u32)addrCov((void*)(p[3]));
//硬错误向量
for(i = 14;
i < SECT_NUM;
i++)
{
p[i] = (u32)addrCov((void*)(p[i]));
}
}//复制整个code区至 ram, 再强制跳转至 ram 区 main 函数
int main(void)
{
iapfunjump2ram;
CPUID[0]= "try";
//为了生成位置无关码
CPUID[1]= "e4t";
iapFile[0] = "rtry.bin" ;
iapFile[1] = "yer.bin";
if(!inRam)// inRam = 0, 说明第一此执行到这,在 flash执行的
{
inRam = 1;
memcpy((void *)ramRunIap, (const void *)(FLASH_BASE), 1024*32);
//复制代码, 设置向量偏移, 计算ram 处的 main 函数 并跳转
SCB->VTOR = RAM_CODE_ADDR & 0xfffffe00;
jump2ram = (iapfun)(addrCov(main));
jump2ram();
// 跳到 ram中的 main函数了
} while(1)
{
/code //
}
}
【stm32 RAM 中运行代码的方法-不动分散加载文件在】
推荐阅读
- 热闹中的孤独
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- “成长”读书社群招募
- 2020-04-07vue中Axios的封装和API接口的管理