【问题标题】:GCC ARM: get actual value from SP registerGCC ARM:从 SP 寄存器获取实际值
【发布时间】:2017-08-13 08:11:48
【问题描述】:

如何从SP寄存器中获取实际值?

我想用一些初始值填充整个 SRAM,但我不想覆盖堆栈的实际内容。

我的启动代码(也覆盖了堆栈的实际内容):

void RESET_handler() {
    unsigned *src, *dst;
    // initialize memory
    // .....

    // fill SRAM
    dst = &_bss_end;
    while (dst < &_stacktop) {
        *dst++ = 0x55555555;
    }
}

_bss_end 是静态变量已用内存的末尾,_stacktop 指向 SRAM 内存的末尾或堆栈顶部。

虽然这个函数是重置处理程序 gcc 让它安全并开始将一些寄存器推入堆栈 (more info)。是的,此时堆栈的实际内容无关紧要,覆盖它是安全的,但为了清除,我想通过用 SP 的实际值替换 &amp;_stacktop 来停止在堆栈之前填充。

也欢迎任何其他想法,除了建议将启动代码重写为汇编程序。

【问题讨论】:

  • 崇尚 C 标准的人不会喜欢你的问题和我的评论。 char *approximativeStackTop(char x) {return(&amp;x);} 呢?
  • 我想知道整个练习的目的是什么?您是否尝试以这种方式调试一些内存问题?
  • @Felix 在开发过程中很高兴看到堆栈有多高,你有多少可用内存,比计算或任何静态分析都要好。
  • 目标架构是什么?
  • @PeterJ ARM, Cortex-M (STM32F0xx)

标签: c gcc cpu-registers cortex-m bare-metal


【解决方案1】:

只有修改启动文件才能可靠地完成。

我将只关注单个堆栈(对于线程 * 特权) openSTM32类型启动示例:

/* Call the clock system intitialization function.*/
    bl  SystemInit
/* Call static constructors */

    bl  fillStack  // <------------ add this

    bl __libc_init_array
/* Call the application's entry point.*/
    bl  main

然后在你的任何 C 文件中实现fillStack 函数。 使用 CMSIS 内在指令,例如 __get_MSP()

【讨论】:

  • 感谢您的建议,但有一个问题是我的裸机模型不使用 CMSIS,我完全避免使用它。但我启发了 CMSIS 如何实现__get_MSP() 函数,它非常简单。这是我修改后的阅读 msp:register unsigned *msp_reg; __asm__ volatile ("mrs %0, msp\n" : "=r" (msp_reg) );,它在我的启动中按预期工作。
  • 有什么理由不使用 CMSIS?它只是一堆方便的定义、typedef、内在函数和内联函数。它不是一个库——没有开销,没有添加数据。 CMSIS 是最裸机 - 只是普通硬件。
  • 在我的项目中,我将外围设备重写为具有位域的 C++ 类或结构。我完全避免使用 #define,但我使用 C++11/14 中的所有商品,如 namespaceclasstemplateenum classauto、位域、inline 函数、.. . 代码现在更干净,可读性更好,优化效果也很好(代码小而且速度快)
  • PS 你不能使用寄存器,因为如果优化打开它会被忽略:)
  • 是的,但是如果它们与 __asm__() 连接,寄存器将不会被忽略......我刚刚测试了所有优化,如 -Os -O3 -Ofast .. 并且在任何地方都正确编译并且代码是工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多