我试图执行一个功能自RAM在cm3(STM32).该函清除和重新编写内部的闪光,所以我绝对需要在RAM但我怎么做?

我想是这样的:复制功能于一个字节列在RAM使用memcpy(检查,它得到正确对准),设置一个功能的指针指向的字节列一再呼吁的功能(指针)。

这工作好也许10的说明(我可以按照执行与调试器),但后来我得到布斯的错误和处理重置。巴斯的错误出现在第二次通过一个循环,使该代码应收(作为它工作的第一个通过)。我认为越快RAM访问渣土上的巴斯时以某种方式...

无论如何是没有一个正确的方式做到这一点?如何将一个分散的文件看起来像那样的地方一个功能在RAM自动(我采用Keil uVision为cm3)?

编辑:更多信息:工具:Arm结臂V4.10 编译器:Armcc v4。0.0.728 汇编:Armasm v4。0.0.728 接头:ArmLink v4。0.0.728 处理器:STM32F103ZE

该IMPRECISERR位设在巴斯的错,登记时的重置发生。

有帮助吗?

解决方案

崩溃后的循环是可能的,因为功能的分支,一个绝对的地址并不是相对新的功能定位在存。会访问的原始代码的位置在这一点导致巴士错误,因为闪清除工作?

我相信你可以标记的功能是汇编和复制到RAM正确与通过附加卡蜜拉 __ram 指令的功能定义。指导在如何做到相同的一条指令编译器看到的 执行职能RAM 技术支持的文章:

µVision可以让你找到模块 具体记忆的区域 输入的对话 项目 选择目标.为此,正确的 点击一来源文件(或者文件组) 和打开的话 选择- 性能.然后选择的记忆 区域下 存储器转让.

有一个例子文件夹 ARMExamplesRAM_Function.

这应产生的启动代码照顾的复制的功能RAM和链接电话的那位置是否正确。否则,如果你需要动态复制任意的功能RAM,然后看看到汇编 位置的独立代码(PIC) 与Arm.

其他提示

不知道更多关于你的情况,我只能提出几个一般的东西...请确保您有该功能有效的堆栈(或避免在函数中的所有堆栈操作),你的中断被禁止的,任何在系统量表向量不指向代码消失,当你擦除闪存。最后,确保你的功能的链接的在地址上运行你把它...代码可能无法再定位和老位置可以跳转到一个点。

由于在ARM具有加载立即数据,这对于ARM生成代码频繁幻影长矛代码和数据实用程序的能力有限。例如,像一个语句

void myRoutine(void)
{
  myVar1=0x12345678;
  myVar2=0x87654321;
}

可能最终作为这样的:

myRoutine:        
    ldr r0,=myVar1; Load the address of _myVar
    ldr r1,=0x12345678
    str r1,[r0]
    ldr r0,=myVar1; Load the address of _myVar
    ldr r1,=0x87654321
    str r1,[r0]
    bx  lr

which would get translated into:
    ldr r0,dat1
    ldr r1,dat2
    str r1,[r0]
    ldr r0,dat3
    ldr r1,dat4
    str r1,[r0]
    bx  lr
... followed some time later by
dat1 dcd _myVar1
dat2 dcd 0x12345678
dat3 dcd _myVar2
dat4 dcd 0x12345678

or perhaps even something like:
    mar  r0,dat1
    ldrm r0,[r1,r2,r3,r4]
    str r2,[r1]
    str r4,[r3]
    bx  lr
... followed some time later by
dat1 dcd _myVar1
dat2 dcd 0x12345678
dat3 dcd _myVar2
dat4 dcd 0x12345678

请注意_myVar和0×12345678,可以立即放置在它们出现的例程的代码以下;如果尝试使用以下的最后一条指令的标签以确定所述程序的长度,例如长度将不能包括补充数据。

要注意到ARM的另外一点是,由于历史的原因,代码的地址往往有他们最显著位设置,即使代码实际上开始于半字的边界。因此,指令为地址为0x12345679将占据两个或四个字节开始0×12345678。这可对于像的memcpy地址计算复杂化。

我的建议是用汇编语言编写一个小的程序,做你所需要的。这只是几个指令,就可以知道到底是什么代码正在做和地址依赖性它可能有,你不会有未来的编译器版本修改代码以这样的方式来碰坏[如担心上面的代码的第三个版本也没问题,即使dat1降落奇数半字边界由于M3的LDR指令可以处理未对齐的读取,但第四(略更快和更紧凑),使用LDRM在这样的情况下会失败版本;即使今天的编译器版本使用四个LDR指令,将来的版本可能会使用LDRM。

IAR编译器(我知道你的问题是关于Keil的,但我不把它一起玩),你可以标记,或者整个项目或单个文件是“位置无关”。从与其他处理器使用过去这意味着你可以将它“任何地方”,它仍然会工作确定

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top