【问题标题】:No symbol 'GPIOA' in current context当前上下文中没有符号“GPIOA”
【发布时间】:2017-12-12 17:10:53
【问题描述】:

我正在尝试使用 OpenOCD 和 GDB(通过 VSCode 作为可视调试界面启动)调试我的 STM32F446RE Nucleo 板,但我无法使用 print 访问变量。

这是我的 main.c

#include "../architecture/CMSIS/inc/stm32f4xx.h"
#include "system_stm32f4xx.h"

#define WAIT(x) for (int i = 0; i < (x); i++)

inline static void init_led2();

int main() {

  init_led2();                      // setup led3
  while (1) {
  #define INDEX 5
    GPIOA->BSRR = 1 << INDEX;       // set led2 output
    WAIT(0x1FFFF);                  // wait for awhile
    GPIOA->BSRR = 1 << INDEX << 16; // reset led3 output
    WAIT(0x1FFFF);
  #undef INDEX
  }
  return 0;
}


// led3 is connected to GPIO pin PB3
inline void init_led2() {
#define MASK 3                                // 2bit mask
#define INDEX 5                               // index of the port
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;                     // enable GPIOA clock
  // set the mode to general purpose output
  GPIOA->MODER &= ~(MASK << (INDEX * 2));     // clear bit field
  GPIOA->MODER |= 1 << (INDEX * 2);
  // set output mode to push-pull
  GPIOA->OTYPER &= ~(1 << (INDEX));
  // set low speed
  GPIOA->OSPEEDR &= ~(MASK << (INDEX * 2));
  // no pull up/down resistors
  GPIOA->PUPDR &= ~(MASK << (INDEX * 2));

#undef MASK
#undef INDEX
}

我有两个断点,一个在

    GPIOA->BSRR = 1 << INDEX;       // set led2 output

另一个在:

    GPIOA->BSRR = 1 << INDEX << 16; // reset led3 output

我的代码运行良好(LED 闪烁),我可以成功进入这个主循环并在这些点停止。

我正在尝试使用print GPIOA-&gt;ODR 为我的 LED 打印输出寄存器以查看它,但每当我这样做时,我都会出错:

No symbol 'GPIOA->ODR' in current context

即使我已经中断了主循环,并且只要我点击继续,我就可以看到 LED 正在打开和关闭。

无论我输入什么,都会出现同样的错误:

No symbol 'GPIOA' in current context
No symbol 'GPIOA->BSRR' in current context
No symbol 'GPIOA->MODER' in current context

GPIOA-&gt;ODRGPIOA 结构所指向的字段ODR 的取消引用,该结构应该是存储在地址0x40020014 的值。如果我在调试控制台窗口中输入x 0x40020014 以查看该寄存器,它实际上返回正常,我什至可以看到它在每个断点上切换。

为什么print 不能工作,为什么它不能识别GPIOA 或其任何成员变量/地址?

【问题讨论】:

  • note that GPIOA-&gt;ODR is simply a useful define statement that eventually leads - 不是。它是 GPIOA 指针指向的结构中的字段 ODR 的解引用。
  • @PeterJ_01 你是对的;我已经编辑了原帖

标签: arm gdb stm32 openocd


【解决方案1】:

GPIOA 等 STM32 外设是使用预处理器宏链定义的——例如:

#define PERIPH_BASE           ((uint32_t)0x40000000)
#define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
#define GPIOA_BASE            (AHB1PERIPH_BASE + 0x0000)
#define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)

通过,预处理器宏在调试器中是不可见的——它只知道为编译器定义的对象(变量、函数、结构,)。 您可以通过将-g3 添加到编译器标志来解决此问题;或者,您可以“手动”展开宏:

print ((GPIO_TypeDef *) 0x40020000)->ODR

【讨论】:

  • Unfortunately, preprocessor macros are not visible in the debugger - 这不是事实。您需要在编译器配置中设置适当的调试级别。
  • @duskwolf 但是 GPIOA 指向一个包含 ODRBSRRMODER 等成员的结构...如何将结构定义为预处理器宏?跨度>
  • @Taako 结构未在此处定义。只有指向这个结构的指针。更准确地说,整数值被转换为这个结构指针。结构本身在其他地方进行了类型定义。我的建议 - 多学习 C 语言。
  • @PeterJ_01 那么GPIOA在哪里定义?如果 GPIOA->BSRR 未定义,LED 如何闪烁?除了头文件之外,我的代码中的其他任何地方都没有设置地址。
  • @Taako 我强烈建议阅读一本好的 C 书。你只是不懂编程语言,这很重要。 GPIOA 没有在任何地方定义。它不是 C 语言对象,只是 (GPIO_TypeDef *)0x40020000UL 的文本替换
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多