While reading an article online (https://nullprogram.com/blog/2023/04/29/) I learned that it is possible to dial up debug information levels with gcc. Previously, I would use a build command of the following form:
arm-none-eabi-gcc -static -mthumb -g -mcpu=cortex-m0 *.c -T linker_script.ld -o main.elf -nostartfiles
This worked fine but when it came to inspecting things like I/O ports defined by macros it left me with lots of work to do in a gdb debug sesssion.
Consider the following definition
typedef struct { /*!< (@ 0x48001400) GPIOF Structure */
__IOM uint32_t MODER; /*!< (@ 0x00000000) GPIO port mode register */
__IOM uint32_t OTYPER; /*!< (@ 0x00000004) GPIO port output type register */
__IOM uint32_t OSPEEDR; /*!< (@ 0x00000008) GPIO port output speed register */
__IOM uint32_t PUPDR; /*!< (@ 0x0000000C) GPIO port pull-up/pull-down register */
__IM uint32_t IDR; /*!< (@ 0x00000010) GPIO port input data register */
__IOM uint32_t ODR; /*!< (@ 0x00000014) GPIO port output data register */
__OM uint32_t BSRR; /*!< (@ 0x00000018) GPIO port bit set/reset register */
__IOM uint32_t LCKR; /*!< (@ 0x0000001C) GPIO port configuration lock register */
__IOM uint32_t AFRL; /*!< (@ 0x00000020) GPIO alternate function low register */
__IOM uint32_t AFRH; /*!< (@ 0x00000024) GPIO alternate function high register */
__OM uint32_t BRR; /*!< (@ 0x00000028) Port bit reset register */
} GPIO_Type; /*!< Size = 44 (0x2c) */
#define GPIOA_BASE 0x48000000UL
#define GPIOA ((GPIO_Type*) GPIOA_BASE)
This allows me to write lines of code like this:
GPIOA->MODER |= (1 << 6); // Make bit 3 an output
In a GDB debug session it is nice to be able to look at the various registers in a port structure. Previously I would have done something like this:
print/x *((GPIO_Type *)0x48000000
This is cumbersome and requires you to know the correct names of the data structures and the various addresses they live at in memory. The blog entry mentioned above however pointed at a better way. The build command is changed as follows:
arm-none-eabi-gcc -static -mthumb -g3 -mcpu=cortex-m0 *.c -T linker_script.ld -o main.elf -nostartfiles
Note the “g3” i.e. turn up debugging information to the max.
Now, when I run a GDB session I can issue commands like this:
print/x *GPIOA
The extra debugging information allows GDB to work through all the macro definitions and show the contents of the port structure. Autocomplete even works :)))