stm32 RAM 中运行代码的方法-不动分散加载文件在

    因特殊需要,iap需要做成 可以更新iap代码的,想了想,也只有ram中运行代码了, 一般iap代码都很小,往往相应的 单片机的ram都要大于 iap代码大小, 所以可以简单点,把iap代码全部复制到ram中,然后来个强制跳转,更新IAP的FLASH,OK, 重启完事^_^。需要注意的是,代码使用位置无关码,这个概念汇编里面比较清楚,即访问资源使用相对地址,一般也都是,如果有疑问,可以在相应汇编窗口下查看是否是相对寻址的代码。下面是主要代码


#include "test.h"

u8 inRam;  // 是否在 ram中

const u8  VER_IAP[4] __attribute__((at(REV_IAP_ADDR_CONTROL))) = {1, 0, 0, 0};   	//版本

u8  ramRunIap[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)
{
	iapfun  jump2ram;

	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 //
	}
}

 

  • 1
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值