0

I am trying to debug my STM32F446RE Nucleo board using OpenOCD and GDB (launched via VSCode as a visual debug interface) and i am having trouble accessing variables using print.

Here is my 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
}

I have two breakpoints, one at

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

and the other at:

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

And my code runs fine (the LED blinking is working) and i can successfully get into this main loop and stop at these points.

I am trying to use print GPIOA->ODR to print the output register for my LED to view it but whenever i do so i get and error:

No symbol 'GPIOA->ODR' in current context

Even though i have broken inside the main loop and can see the LED being turned on and off whenever i hit continue.

This same error occurs no matter what i type:

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

GPIOA->ODR is a derefence of the field ODR pointed to by GPIOA structure which should be the value stored at address 0x40020014. If i type x 0x40020014 in the debug console window to view that register it actually returns fine and i can even see it toggle on each breakpoint.

why won't print work and why does it not recognize GPIOA or any of its member variables/addresses?

Taako
  • 587
  • 2
  • 6
  • 21
  • `note that GPIOA->ODR is simply a useful define statement that eventually leads` - it is not. It is a derefernce of the fiels ODR in the structure pointed by the GPIOA pointer. – 0___________ Dec 12 '17 at 18:57
  • @PeterJ_01 you are correct; i have edited the original post – Taako Dec 12 '17 at 19:03

1 Answers1

1

STM32 peripherals like GPIOA are defined using chains of preprocessor macros -- for example:

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

By, preprocessor macros are not visible in the debugger -- it is only aware of objects which were defined for the compiler (variables, functions, structures, etc). You can fix this by adding -g3 to your compiler flags; alternatively, you can expand the macro "manually":

print ((GPIO_TypeDef *) 0x40020000)->ODR
  • `Unfortunately, preprocessor macros are not visible in the debugger` - it is not the truth. You need to have a proper debug level set in the compiler configuration. – 0___________ Dec 12 '17 at 19:01
  • @duskwolf but GPIOA points to a structure that holds members such as `ODR`, `BSRR`, `MODER`, etc... how can a structure be defined as a preprocessor macro? – Taako Dec 12 '17 at 19:05
  • @Taako Structure is not defined there. There is only pointer to this structure. More precisely the integer value is casted to this structure pointer. The structure itself is typedef-ed somewhere else. My advice - study a bit more the C language. – 0___________ Dec 12 '17 at 19:11
  • @PeterJ_01 then where is GPIOA defined? How does the led blink if GPIOA->BSRR isn't defined? The addresses aren't set up anywhere else in my code except the header file. – Taako Dec 12 '17 at 19:20
  • @Taako I would strongly advice reading a good C book. You just do not know the programming language and it is essential . GPIOA is not defined anywhere. It is not the C language object only the text replacement for `(GPIO_TypeDef *)0x40020000UL` – 0___________ Dec 12 '17 at 19:39
  • @PeterJ_01 okay then a better question: how do i get gdb to replace the text GPIOA with the same thing? – Taako Dec 12 '17 at 19:44
  • @PeterJ_01 WHOA! I didn't realize that fixed it -- thanks! I've updated my answer accordingly. –  Dec 12 '17 at 20:38
  • I do not write something I did not test – 0___________ Dec 13 '17 at 09:22