adventures of a random geek


If you debug embedded inferiors with GDB you might want to check the state of some register of some peripheral. You can do this by hand by just reading the memory where the register is mapped. This includes consulting the data sheet to get the address which is pretty slow if you need to do this often.

There is a GDB plugin called PyCortexMDebug, which enables you to read or write registers, show descriptions and list peripherals of micro controllers. The peripheral and register information are loaded from a System View Description file (SVD) You can find many svd files from different vendors in this repository: cmsis-svd.

Unfortunately the plugin only worked if your inferior is written in C/C++ because the method of actually reading/writing memory uses c-style type casts. This doesn't work if you debug a rust inferior like I did. GDBs python API provides methods to directly read or write a specific address in the inferiors memory. So let's use them: https://github.com/wose/PyCortexMDebug

A pull request will be made after I tested it a little more.

After the plugin installation you can add something like the following to your .gdbinit of your project to activate the plugin and load a specific svd file.

source gdb.py
svd_load STM32F103xx.svd

gdb.py is the one which is part of PyCortexMDebug. You'll have to specify the path where you've put it or copy it next to your .gdbinit.

After connecting to your target you can use the svd command:

>>> svd
Available Peripherals:
        FSMC:    Flexible static memory controller
        PWR:     Power control
        RCC:     Reset and clock control
        GPIOA:   General purpose I/O
        GPIOB:   General purpose I/O
        GPIOC:   General purpose I/O
        GPIOD:   General purpose I/O
        GPIOE:   General purpose I/O
        GPIOF:   General purpose I/O
        GPIOG:   General purpose I/O
        AFIO:    Alternate function I/O
        EXTI:    EXTI
        DMA1:    DMA controller
        DMA2:    DMA controller
        SDIO:    Secure digital input/output interface
        RTC:     Real time clock
        BKP:     Backup registers
        IWDG:    Independent watchdog
        WWDG:    Window watchdog
        TIM1:    Advanced timer
        TIM8:    Advanced timer
        TIM2:    General purpose timer
        TIM3:    General purpose timer
        TIM4:    General purpose timer
        TIM5:    General purpose timer
        TIM9:    General purpose timer
        TIM12:   General purpose timer
        TIM10:   General purpose timer
        TIM11:   General purpose timer
        TIM13:   General purpose timer
        TIM14:   General purpose timer
        TIM6:    Basic timer
        TIM7:    Basic timer
        I2C1:    Inter integrated circuit
        I2C2:    Inter integrated circuit
        SPI1:    Serial peripheral interface
        SPI2:    Serial peripheral interface
        SPI3:    Serial peripheral interface
        USART1:  Universal synchronous asynchronous receiver transmitter
        USART2:  Universal synchronous asynchronous receiver transmitter
        USART3:  Universal synchronous asynchronous receiver transmitter
        ADC1:    Analog to digital converter
        ADC2:    Analog to digital converter
        ADC3:    Analog to digital converter
        CAN:     Controller area network
        DAC:     Digital to analog converter
        DBG:     Debug support
        UART4:   Universal asynchronous receiver transmitter
        UART5:   Universal asynchronous receiver transmitter
        CRC:     CRC calculation unit
        FLASH:   FLASH
>>> svd/x I2C1
Registers in I2C1:
	CR1:    0x00000001  Control register 1
	CR2:    0x00000018  Control register 2
	OAR1:   0x00000000  Own address register 1
	OAR2:   0x00000000  Own address register 2
	DR:     0x000000B0  Data register
	SR1:    0x00000001  Status register 1
	SR2:    0x00000003  Status register 2
	CCR:    0x00000078  Clock control register
	TRISE:  0x00000019  TRISE register
>>> svd I2C1 SR1
Fields in SR1 of peripheral I2C1:
	SMBALERT:  0  SMBus alert
	TIMEOUT:   0  Timeout or Tlow error
	PECERR:    0  PEC Error in reception
	OVR:       0  Overrun/Underrun
	AF:        0  Acknowledge failure
	ARLO:      0  Arbitration lost (master mode)
	BERR:      0  Bus error
	TxE:       0  Data register empty (transmitters)
	RxNE:      0  Data register not empty (receivers)
	STOPF:     0  Stop detection (slave mode)
	ADD10:     0  10-bit header sent (Master mode)
	BTF:       0  Byte transfer finished
	ADDR:      0  Address sent (master mode)/matched (slave mode)
	SB:        1  Start bit (Master mode)