Wolfmans Howlings

A programmers Blog about Programming solutions and a few other issues

Building a SVD microchip documentation database

Posted by Jim Morris on 2026-01-20 15:33:58 +0000

Overview

While I was doing the baremetal RP2350 Risc-V project, and my attempts to write peripheral drivers for my Mecrisp-Forth projects I spent a lot of time searching through the various document for the chips I was using. Mainly the RP2350 and STM32H7xx, whose documents are pretty extensive and it really is time consuming to find what you need.

Then I came across this work by Terry Porter svd2db. This inspired me and I decided to write my own which was a command line lookup tool that let me find the registers and fields of any register for any of the microcomputers I was using. SVD is an XML file provided by most chip manufacturers that documents all the registers and bit fields for their MCUs.

XML to Database

The first thing I needed to do was convert the SVD XML file to a database, just as Terry had done, however having had some SQL experience in the past I wanted to refactor the database and normalize it as far as possible. I chose to use sqlite3 as the database (although pretty much any SQL database would do). I wrote the initial code in Ruby as that has a nice library called Sequel with which I was quite familiar with in the past (having used it to write this blog engine and various other ruby on rails projects I did over 10-20 years ago). Needless to say I had mostly forgotten everything I had done back then so had some catching up to do.

The Ruby project is here and the new GO based one is here. I'll talk more about the GO version later (or in a separate blog post).

Having written Ruby code to convert the SVD XML file to a sqlite3 database, I went about writing a command line program to query that database. I won't go into the details of the database schema needless to say it uses plenty of foreign keys and has_many and many_to_many relationships, which is part of the normalization and refactoring, making the database file about 5x smaller than Terry's.

SVD Lookup command line tool

I wanted to do several things with the command line tool

  1. Display the names of all the peripherals
  2. Display the names of all the registers for a given peripheral
  3. Display the bit fields for a specific register

These are all in human readable format, and would save having to delve through several hundred pages of reference manual.

Then for the assembly projects I wanted to output .EQU statements for peripherals, registers and their bit fields. For Forth projects I wanted to output constant words for the peripherals, registers and their bit fields.

for example...

> lookup-svd -l
MPU: RP2350, Available Peripherals:
ACCESSCTRL
ADC
BOOTRAM
BUSCTRL
CLOCKS
CORESIGHT_TRACE
DMA
EPPB
GLITCH_DETECTOR
HSTX_CTRL
HSTX_FIFO
I2C0
I2C1
... etc ...

> lookup-svd --regs -p uart0
MPU: RP2350, Registers for uart0:
UARTCR
UARTDMACR
UARTDR
UARTFBRD
UARTFR
UARTIBRD
UARTICR
UARTIFLS
... etc ...


> lookup-svd -p uart0 -r UARTCR
UART0 base address: 0x40070000

Register UARTCR offset: 0x00000030, reset: 0x00000300
UARTCR_UARTEN: number bits 1, bit offset: 0, mask: 00000001
UARTCR_SIREN: number bits 1, bit offset: 1, mask: 00000002
UARTCR_SIRLP: number bits 1, bit offset: 2, mask: 00000004
UARTCR_LBE: number bits 1, bit offset: 7, mask: 00000080
UARTCR_TXE: number bits 1, bit offset: 8, mask: 00000100
UARTCR_RXE: number bits 1, bit offset: 9, mask: 00000200
UARTCR_DTR: number bits 1, bit offset: 10, mask: 00000400
UARTCR_RTS: number bits 1, bit offset: 11, mask: 00000800
UARTCR_OUT1: number bits 1, bit offset: 12, mask: 00001000
UARTCR_OUT2: number bits 1, bit offset: 13, mask: 00002000
UARTCR_RTSEN: number bits 1, bit offset: 14, mask: 00004000
UARTCR_CTSEN: number bits 1, bit offset: 15, mask: 00008000

These are the 'human readable' forms (YMMV)

For the assembly output forms...

> lookup-svd --asm -p uart0 -r UARTCR
.equ UART0_BASE, 0x40070000
  .equ _UARTCR, 0x00000030
    .equ b_UARTCR_UARTEN, 1<<0
    .equ b_UARTCR_SIREN, 1<<1
    .equ b_UARTCR_SIRLP, 1<<2
    .equ b_UARTCR_LBE, 1<<7
    .equ b_UARTCR_TXE, 1<<8
    .equ b_UARTCR_RXE, 1<<9
    .equ b_UARTCR_DTR, 1<<10
    .equ b_UARTCR_RTS, 1<<11
    .equ b_UARTCR_OUT1, 1<<12
    .equ b_UARTCR_OUT2, 1<<13
    .equ b_UARTCR_RTSEN, 1<<14
    .equ b_UARTCR_CTSEN, 1<<15

Which can be pasted directly into your source code file (I have a sublime-text macro that does this for instance). The Forth output is similar but generates forth words.

To make things easier, as I use several different MCUs, I can put the database file in the root directory of the project I am working on, by naming it default-svd.db the command line tool will search up the directories until it finds that database file and use that.

What's next?

In order to learn Go Lang (just for fun and something to do) I rewrote the Ruby code for the above in Go. The command line tool is somewhat similar as far as functionality, but uses subcomamnds for the basic output format selection.

> svd_lookup --help
Query a SVD database in various ways.
    Depending on the subcommand it can generate various code sequences to access the peripherals and registers
    or display the available peripherals and/or registers in a human readable way.

Usage:
  svd_lookup [command]

Available Commands:
  asm         Generate asm .equ directives defining registers and fields
  completion  Generate the autocompletion script for the specified shell
  convert     Convert a .SVD file to a database file
  display     Human readable display of the registers and fields for the specified peripheral
  dump        Dumps the SVD database
  forth       Generate forth words to access the specified peripheral
  help        Help about any command
  list        List all peripherals
  registers   List all the registers for the specified peripheral

Flags:
  -c, --curdir string     set the current directory for db search
  -d, --database string   use the named database
  -h, --help              help for svd_lookup
  -v, --verbose           verbose output

Use "svd_lookup [command] --help" for more information about a command.

To generate the assembly code output shown above I would do

> svd_lookup asm -p uart0 -r UARTCR
.equ UART0_BASE, 0x40070000
; Registers for uart0
  .equ _UARTCR, 0x00000030
; Bitfields for _UARTCR
  .equ b_UARTCR_UARTEN, 1<<0
  .equ b_UARTCR_SIREN, 1<<1
  .equ b_UARTCR_SIRLP, 1<<2
  .equ b_UARTCR_LBE, 1<<7
  .equ b_UARTCR_TXE, 1<<8
  .equ b_UARTCR_RXE, 1<<9
  .equ b_UARTCR_DTR, 1<<10
  .equ b_UARTCR_RTS, 1<<11
  .equ b_UARTCR_OUT1, 1<<12
  .equ b_UARTCR_OUT2, 1<<13
  .equ b_UARTCR_RTSEN, 1<<14
  .equ b_UARTCR_CTSEN, 1<<15

Integrating these into the editor of choice is relatively simple, and saves so much time.

FYI binaries for go version for various platforms can be found here and various databases can be found here although you can easily create your own by downloading the SVD XML from your favorite microchip vendors site and converting it using the command svd_lookup convert file.svd [outfile.db]

I plan on writing an updated version in Go that allows you to query the same kind of things but from a web site, so stay tuned.

Enjoy!

Posted in assembler,RISC-V,STM32,SVD  |  Tags risc-v,assembly,baremetal,stm32,svd  |  no comments

Comments

(leave email »)