代码之家  ›  专栏  ›  技术社区  ›  c0m4

如何从Cortex-M3(STM32)上的RAM执行函数?

  •  7
  • c0m4  · 技术社区  · 14 年前

    我正在尝试从Cortex-M3处理器(STM32)上的RAM执行一个函数。该函数擦除和重写的内部闪存,所以我肯定需要在内存,但我怎么做呢?

    对于10条指令(我可以用调试器跟踪执行)来说,这很好,但是我得到一个总线错误,处理器复位。buss错误发生在循环的第二次传递上,因此代码应该是正确的(因为它在第一次传递时工作)。我在想,更快的内存访问会在某种程度上影响总线的计时。。。

    编辑:更多信息: 工具链:RealView MDK-ARM V 4.10 汇编程序:Armasm v4.0.0.728 处理器:STM32F103ZE

    复位发生时,不精确的RR位在总线故障寄存器中设置。

    4 回复  |  直到 10 年前
        1
  •  7
  •   Community LiorH    4 年前

    循环迭代崩溃可能是因为函数正在分支到一个绝对地址,而不是相对于RAM中的新函数位置。在该点访问原始代码位置是否会因为闪存擦除操作而导致总线错误?

    __ram EXECUTING FUNCTIONS IN RAM 技术支持文章:

    Vision允许您定位模块 到特定的内存区域 在对话框中输入 选项-目标 单击源文件(或文件组) 属性 以下地区 .

    ARMExamplesRAM\U函数

    它应该生成启动代码,负责将函数复制到RAM并将调用正确链接到该位置。否则,如果您需要将任意函数动态复制到RAM中,那么请查看编译 position independent code (PIC) 用RealView。

        2
  •  2
  •   Amardeep AC9MF    14 年前

    链接 按你写的地址跑。。。代码可能无法重新定位,可能会跳转到旧位置的某个位置。

        3
  •  2
  •   supercat    11 年前

    由于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
    

    注意,\u myVar和0x12345678可以紧跟在它们出现的例程的代码之后;如果您试图使用上一条指令后面的标签来确定例程的长度,那么这样的长度将无法包含补充数据。

    我的建议是用汇编语言编写一个小例程来做你需要的事情。它只是一些指令,你可以确切地知道代码在做什么,它可能有什么地址依赖关系,而且你不必担心将来的编译器版本会以这样一种方式改变你的代码,从而破坏某些东西[例如,上述代码的第三个版本将没有问题,即使 dat1

        4
  •  1
  •   peter_mcc    12 年前

    使用IAR编译器(我知道你的问题是关于Keil的,但我没有这个问题)你可以将整个项目或单个文件标记为“位置独立”。从使用这个在过去与其他处理器,这意味着你可以移动它“任何地方”,它仍然可以正常工作