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 中运行代码的方法-不动分散加载文件在】

    推荐阅读