首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F7 -从内存和闪存执行代码

STM32F7 -从内存和闪存执行代码
EN

Stack Overflow用户
提问于 2019-03-28 03:26:45
回答 1查看 1.9K关注 0票数 1

我相信我的链接器脚本有问题,但我不确定这是否是真正的罪魁祸首。

背景:

我在一个项目中使用STM32F730。uC有64K闪光灯和256 K内存。其中64K是TCM,192 K是普通RAM。这个项目将超过64k的内部闪存,所以我打算从RAM中运行额外的代码。板上有外部闪存,因此在启动时,uC将执行一个从星载闪存读取板闪存的加载例程,并将数据存储到RAM中的正确位置。这部分起作用,但只是有时。离板闪存是以多种方式编程的,但我相信所需的代码就在那里。此外,当从调试器运行时会发生错误,并且绕过片外闪存加载。

所有问题都将涉及从调试器运行。此时没有从片外闪存加载代码。

我有长时间的函数调用打开以允许跳转到RAM,这确实解决了我有一个问题,但不是这个问题。

问题

有时,当通过调试器加载代码时,代码工作得完美无缺。其他时候,代码根本不起作用,并且出现了严重的错误。我不是一个嵌入式专家(我主要从事PCB设计和FPGA工作),但我成功地完成了组装,并找到了导致问题的奇怪事物,但没有找到问题发生的原因。我当前的项目有一个IMU驱动程序加载到RAM中,并且应该将数据通过USB发送回来。当完全在闪存中加载时,这是可以工作的,但并不总是在RAM中。例如,当我打开调试优化时,它可以工作,但是没有优化会导致错误。

我修改了我的链接器如下:

代码语言:javascript
复制
/* Specify the memory areas */
MEMORY
{
TCM_RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 64K
CODE_RAM (xrw)      : ORIGIN = 0x20010000, LENGTH = 64K
DATA_RAM (xrw)      : ORIGIN = 0x20020000, LENGTH = 112K
FLASH (rx)      : ORIGIN = 0x8000000, LENGTH = 64K
}

/* Define output sections */
SECTIONS
{
  /* The startup code goes first into FLASH */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

    /* NP 2019-03-15 - RAM Executable code should be linked to RAM                              */
    /*      NOTE: With code linked this way it WILL NOT RUN WITHOUT THE DEBUGGER OR BOOTLADED   */
    /*              Any loaded code will be wiped from RAM on a power cycle.                    */
  .coderam : 
  {
    . = ALIGN(4);
    __RAM_CODE_SECTION_START = .;
    *(.text.imu*)
    . = ALIGN(4);
    __RAM_CODE_SECTION_END = .;

  }>FLASH//CODE_RAM 


  /* The program code and other data goes into FLASH */
  .text :
  {
    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH

每个imu驱动程序函数都是从imu*开始的,所以我尝试用*(.text.imu*)行将所有imu函数加载到内存中,我尝试指定imu.o,但是经过多次搜索和尝试和错误之后,我找不出正确的语法。我在闪存。*在闪存和内存之间切换。注意,当我使用闪存时,它将它存储在地址0x0,为什么?我认为这是一个非常初级的问题,但我不明白为什么。

问题:我在初始化函数中遇到了一个问题,这是对RAM代码的第一个函数调用。这是C代码片段:

代码语言:javascript
复制
uint8_t imu_init(void)
{
    uint8_t retry_cnt = 0U;

      imu_trans.device_csn_bank = IMU_CSN_BANK;
      imu_trans.device_csn_pin = IMU_CSN_PIN;
      imu_trans.device = DEVICE_IMU;
      imu_trans.speed = SPI_SPEED_6_75MBIT;
      imu_trans.rxBuf = imuRxBuf;
**Continues, but hard fault occurs earlier**

通过查看程序集,当从RAM运行时,下面的代码在我的init函数中运行:

代码语言:javascript
复制
                                          imu_init:
20010000: 0x000080b5 imu_init+0             push    {r7, lr}
20010002: 0x000082b0 imu_init+2             sub     sp, #8
20010004: 0x000000af imu_init+4             add     r7, sp, #0
 69                                         uint8_t retry_cnt = 0U;
20010006: 0x00000023 imu_init+6             movs    r3, #0
20010008: 0x00000000 imu_init+8             movs    r0, r0
 71                                           imu_trans.device_csn_bank = IMU_CSN_BANK;
2001000a: 0x00001d4b imu_init+10            ldr     r3, [pc, #116]  ; (0x20010080 <imu_init+128>)
2001000c: 0x00000000 imu_init+12            movs    r0, r0
2001000e: 0x00000060 imu_init+14            str     r0, [r0, #0]
 72                                           imu_trans.device_csn_pin = IMU_CSN_PIN;
20010010: 0x00fb7100 imu_init+16                    ; <UNDEFINED> instruction: 0xfb000071
20010014: 0x0000001d imu_init+20            adds    r0, r0, #4
20010016: 0x00004a5a imu_init+22            ldrh    r2, [r1, r1]
 73                                           imu_trans.device = DEVICE_IMU;
20010018: 0x0000001b imu_init+24            subs    r0, r0, r4
2001001a: 0x00004b4f imu_init+26            ldr     r7, [pc, #300]  ; (0x20010148 <imu_process_vals+4>)
2001001c: 0x0000f400 imu_init+28            lsls    r4, r6, #3
 74                                           imu_trans.speed = SPI_SPEED_6_75MBIT;

显然,它在行20010010: 0x00fb7100 imu_init+16 ; <UNDEFINED> instruction: 0xfb000071上有很强的故障。有趣的是(这是我没有得到的),这不是在十六进制文件!?!

代码语言:javascript
复制
*snip*
:020000042001D9
:1000000080B582B000AF0023FB711D4B1D4A5A60C2
:100010001B4B4FF480721A80194B01221A72184B35
*snip*

第三行的开头是硬故障指令!但是内存浏览器显示:

代码语言:javascript
复制
0x0000000020010000  B082B580 2300AF00 4B1D0000  .µ.°.¯.#...K
0x000000002001000C  60000000 0071FB00 5A4A1D00  ...`.ûq...JZ

所以看起来RAM中确实有一个不好的指令,但是为什么!?它看起来也像是0x2001000C也被破坏了,因为它不匹配十六进制文件。我最初认为在加载过程中有一些东西在做这个,但是如果我也在重置处理程序上设置一个断点,我就不明白原因了。我以为这是社会福利署的腐败,但每次都是一样的,所以我也不确定这是一个因素。我最初认为其中一些指令是等待状态(mov、r0、r0),但现在我认为它们已经损坏了值?

毫不奇怪,加载到闪存的代码读取与十六进制文件相同的内容:

代码语言:javascript
复制
0x000000000800AEC4  B082B580 2300AF00 4B1D71FB 605A4A1D F44F4B1B 801A7280  .µ.°.¯.#ûq.K.JZ`.KOô.r..
0x000000000800AEDC  22014B19 4B18721A 729A2202 4A184B16 4B1560DA 611A4A17  .K.".r.K.".r.K.JÚ`.K.J.a

所以,TL;DR: 1。如果我在闪存中加载所有的东西,那么它可以很好地工作2。如果我将imu驱动程序加载到RAM中,而在闪存中加载其他所有驱动程序,那么它就会出现故障3。如果我打开调试优化-Og,它会再次工作,但可能会将错误转移到其他地方。

任何帮助都将是非常感谢的,我已经花了大约30个小时试图让这个看似简单的东西开始工作(它确实奏效了!)然后它就停止了),我已经没有什么办法去尝试了。

谢谢,尼克

编辑

我想我可能已经追查到这个了.我尝试从ST链接实用程序和查看内存加载相同的文件,然后尝试加载调试器和查看内存。

当然,调试器加载的代码与ST Link util加载的代码不同。ST链接util加载的代码按预期工作- USB枚举和发送数据。

我做了一个比较,第二个RAM地址(0x20010008之后的所有内容)都损坏了。

那么这可能是调试器设置问题吗?我使用的STlinkV3通过社会福利署-该项目需要特殊的设置运行从内存?再说一遍,有时它在RAM中工作得很好,但其他时候却不行。

EN

回答 1

Stack Overflow用户

发布于 2019-07-05 04:37:46

这最后成了真相的问题。我不确定它是否是我使用的特定版本,但是当使用truestudio中的调试特性时,调试器不会始终对RAM进行编程。

解决方法是使用STM32CubeProg,但这意味着不进行调试。

有趣的是,简单地将ST链接配置为外部工具是没有问题的。ext-tool.pdf

代码现在从flash / ram运行/执行,它们之间的转换没有问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55389711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档