Svd2db-v1 README

Note

This Readme is the latest version. The release PDF may become out of date.

Svd2db was featured in Hackaday:

https://hackaday.com/2022/11/21/making-svd-files-searchable-with-svd2db/

Abstract

Svd2db is made to assist designers who may use Gcc, Assembly, Forth, PicoLisp etc, or any new embedded language that does not come with ready made libraries, includes or header files.

In many cases this means the STMicro Technical Reference Manual PDF is the main designer resource.

However using the Reference Manual for programming consumes a great deal of time and is very error prone by way of typos, not to mention the temptation to abbreviate the cannonical CMSIS-SVD Peripheral_Register_Bitfield names making them non standard.

Svd2db is a bit like a Unix MAN Page for embedded and is designed for fast searching and listing. Svd2db gets its data from the same place that the Technical Manual does, namely the mcu CMSIS-SVD file.

Svd2db creates a Sqlite database and a CLI reader named ‘readdb’ (to quickly search and list the database information) is included in this release.

Download

https://sourceforge.net/projects/mecrisp-stellaris-folkdoc/files/svd2db-v1.2c2d-26.09.22.zip Also contains sample SVD’s and Databases so you don’t have to build any to test this release.

https://sourceforge.net/projects/mecrisp-stellaris-folkdoc/files/svd2db-v1.pdf (this is in the release above also)

Database Reader

Readdb is a CLI based program and entering ‘./readdb’ will print instructions and help.

Alternate DB Readers

However the Svd2db database does not not require readdb because it is a Sqlite database and there are many other free alternatives such as:

Readdb Example

List all bitfields containg ‘sleep’ in the description field of the PWR peripheral.

‘Ar’ means Access Rights, ‘bw’ is BitWidth and ‘bo’ is BitOffset. ‘Address’ is the absolute memory location of the PWR_CR register.

./readdb -p pwr -b lpds -T
name                            address     ar  bw  bo  description
------------------------------  ----------  --  --  --  --------------------------------------------------
PWR_CR_LPDS                     0x40007000  rw  1   0   Low Power Deep Sleep

Database Information

  • The MCU model the database was built for.

  • CMSIS-SVD compliant Peripheral_Register_Bitfield names.

  • Absolute Memory Register Addresses. Theae are not available in the Reference Manual.

  • Description Field.

  • Bitfield attributes:

    • BitOffset (bo)

    • BitWidth (bw)

    • Access type

      • read-only (ro)

      • write-only (wo)

      • read-wrote (rw)

Database Creation

There are two types of database that can be created, the first uses ‘0x’ as the hexadecimal prefix, and the second is ‘$’.

Syntax

The commands below are entered in the release directory. The only difference between the two database types is the hexadecimal prefix as above. These are supplied as a programmer convenience.

0x Prefix

make ARGS=STM32F051.svd

This will create a database named:

svd2db-STM32F051.db

$ Prefix

make forth ARGS=STM32F051.svd

This will create a database named:

svd2db-STM32F051.F.db

Supported Mcu’s

Any STM32 Cortex-M MCU with a SVD file.

Dependencies

Unix, Gema (http://gema.sourceforge.net/new/index.shtml), Make, xmllint, xsltproc, getopt. These should all be available in any unix repo.

SVD

The CMSIS System View Description format (CMSIS-SVD) formalizes the description of the system contained in Arm Cortex-M processor-based micro controllers, in particular, the memory mapped registers of peripherals. The detail contained in system view descriptions is comparable to the data in device reference manuals. The information ranges from high level functional descriptions of a peripheral all the way down to the definition and purpose of an individual bit field in a memory mapped register.

  • Are XML text files detailing all peripheral registers for ARM MCU families.

  • May be downloaded from https://github.com/posborne/cmsis-svd/archive/master.zip (39MB) and elsewhere.

  • Keil, now owned by ARM, have SVD PACKS for all the MCU’s which may be downloaded from their site.

  • Do not contain ARM specific information such as SYSTICK etc.

License

MIT, please see COPYING

Author

Terry Porter 2022

Details and Usage

Number Bases

Number Base

Prefix

Hexadecimal

0x or $

Decimal

None

Examples

SD Card Reader

You’re designing a SD card reader and need to set the SPI BAUD RATE bitfield, what is it ?

Sure, you’ll still probably need to consult the ref manual to find the three bit code for the Baudrate you need, but you can code the rest first using Svd2db.

Enter

./readdb -p spi1 -d baud -T

Output

name                            address     ar  bw  bo  description
------------------------------  ----------  --  --  --  --------------------------------------------------
SPI1_CR1_BR                     0x40013000  rw  3   3   Baud rate control

Display all the Peripherals

./readdb -L

Output

ADC1    CRC     EXTI    GPIOC   IWDG    RTC     TIM1    USART1  WWDG
AFIO    DBG     FLASH   GPIOD   NVIC    SDIO    TIM2    USART2
BKP     DMA1    GPIOA   I2C1    PWR     SPI1    TIM3    USART3
CAN     DMA2    GPIOB   I2C2    RCC     SPI2    TIM4    USB

Display all the Register Data

./readdb -p pwr -T

Output

name                            address     ar  bw  bo  description
------------------------------  ----------  --  --  --  --------------------------------------------------
PWR                             NULL        --  --  99  STM32F103xx: Power control Peripheral
PWR_CR                          0x40007000  --  --  98  Reset:0x00000000  Address: 0x40007000
PWR_CR_CSBF                     0x40007000  rw  1   3   Clear STANDBY Flag
PWR_CR_CWUF                     0x40007000  rw  1   2   Clear Wake-up Flag
PWR_CR_DBP                      0x40007000  rw  1   8   Disable Backup Domain writeprotection
PWR_CR_LPDS                     0x40007000  rw  1   0   Low Power Deep Sleep
PWR_CR_PDDS                     0x40007000  rw  1   1   Power Down Deep Sleep
PWR_CR_PLS                      0x40007000  rw  3   5   PVD Level Selection
PWR_CR_PVDE                     0x40007000  rw  1   4   Power Voltage DetectorEnable
PWR_CSR                         0x40007004  --  --  98  Reset:0x00000000  Address: 0x40007004
PWR_CSR_EWUP                    0x40007004  rw  1   8   Enable WKUP pin
PWR_CSR_PVDO                    0x40007004  ro  1   2   PVD Output
PWR_CSR_SBF                     0x40007004  ro  1   1   STANDBY Flag
PWR_CSR_WUF                     0x40007004  ro  1   0   Wake-Up Flag

Display All Register Names

Ignore any “NULL” names

./readdb -p pwr -R

register = CR
register = CSR
register = NULL

Display Contents of named Register in a Peripheral, sorted by BitOffset

Same as in the Reference Manual.

./readdb -p pwr -r cr -M
name                            ar  bw  bo  description
------------------------------  --  --  --  --------------------------------------------------
PWR                             --  --  99  STM32F0xx: Power control Peripheral
PWR_CR                          --  --  98  Reset:0x00000000  Address: 0x40007000
PWR_CR_FPDS                     rw  1   9   Flash power down in Stopmode
PWR_CR_DBP                      rw  1   8   Disable backup domain writeprotection
PWR_CR_PLS                      rw  3   5   PVD level selection
PWR_CR_PVDE                     rw  1   4   Power voltage detectorenable
PWR_CR_CSBF                     rw  1   3   Clear standby flag
PWR_CR_CWUF                     rw  1   2   Clear wakeup flag
PWR_CR_PDDS                     rw  1   1   Power down deepsleep
PWR_CR_LPDS                     rw  1   0   Low-power deep sleep

Forth Blinky

\ ***********************************************************
\ filename: main.fs
\ For Mecrisp-Stellaris by Matthias Koch
\ by: Terry Porter 2022, released under the GPL License
\ Demo of SVD2DB and READDB https:\mecrisp-stellaris-folkdoc.sourceforge.io/readdb.html
\ CPU: STM32F051 running at default 8MHz clock
\ SVD: STM32F051.svd
\ BLUE LED = PC8, blinks about once per second.
\ ***********************************************************

constant $40021000 RCC_CR
constant $40021014 RCC_AHBENR
constant $48000800 GPIOC_MODER
constant $48000818 GPIOC_BSRR

: init ( -- )
   1 19 lshift RCC_AHBENR bis!     \ I/O port C clock enable
   %01 16 lshift GPIOC_MODER bis!   \ set Port C, bit 8 Mode to 01: General purpose output mode
:

: delay ( -- )
   800000 0 do loop
;

: main ( -- )
   init
     begin
     1 8 lshift GPIOC_BSRR !    \ SET PC8 high. led ON
     delay
     1 25 lshift GPIOC_BSRR !   \ CLR PC8, led OF
     delay
   again
:

Forth Write-only Blinky

Kidding. A real write-only would be ‘magic number’ source only with no comments.

: init ( -- )
    1 19 lshift $40021014 bis!  \ I/O port C clock enable
  %01 16 lshift $48000800 bis!  \ set Port C, bit 8 Mode to 01: General purpose output mode
;

: delay ( -- )
   800000 0 do loop
;

: main ( -- )
   init
     begin
     1 8 lshift $48000818 !     \ SET PC8 high. led ON
     delay
     1 25 lshift $48000818 !    \ CLR PC8, led OF
     delay
   again
;

How were the addresses and bitfields derived ?

Comments show how:

\ ./readdb -p rcc -r ahbenr -M
\ --->  RCC_AHBENR  --  --  98  Reset:$00000014  Address: $40021014

constant $40021014 RCC_AHBENR

\ ./readdb -p gpioc -r moder -M
\ --->  GPIOC_MODER --  --  98  Reset:$00000000  Address: $48000800

constant $48000800 GPIOC_MODER

\ ./readdb -p gpioc -r bsrr -M
\ --->  GPIOC_BSRR --  --  98  Reset:$00000000  Address: $48000818

constant $48000818 GPIOC_BSRR


: init ( -- )
   \ ./readdb -p rcc -r ahbenr -T
   \ --->  RCC_AHBENR_IOPCEN $40021014  rw  1   19  I/O port C clock enable

   1 19 lshift RCC_AHBENR bis!     \ I/O port C clock enable

   \ ./readdb -p gpioc -r moder -T
   \ --->  GPIOC_MODER_MODER8 $48000800  rw  2   16  Port x configuration bits (y =0..15)

   %01 16 lshift GPIOC_MODER bis!   \ set Port C, bit 8 Mode to 01: General purpose output mode
:

: delay ( -- )
   800000 0 do loop
;

: main ( -- )
   init

   begin
     \ ./readdb -p gpioc -R
     \ --->  register = BSRR
     \ ./readdb -p gpioc -r bsrr -M
     \ --->  GPIOC_BSRR_BS8 wo  1   8   Port x SET BIT y (y=0..15)

     1 8 lshift GPIOC_BSRR !    \ SET PC8 high. led ON
     delay

     \ --->  GPIOC_BSRR_BR8 wo  1   24  Port x RESET BIT y (y =0..15)

     1 25 lshift GPIOC_BSRR !   \ CLR PC8, led OF
     delay
   again
:

C Blinky

// ***********************************************************
// filename: main.c
// Original Author: Frank Duignan http://eleceng.dit.ie/frank/arm/BareMetalSTM32F0Discovery/
// Many changes by: Terry Porter 2022, released under the MIT License
// Demo of SVD2DB and READDB https://mecrisp-stellaris-folkdoc.sourceforge.io/readdb.html
// This demo uses no libraries or headers whilst creating a Blinky for a STM32F0 Discovery board
// CPU: STM32F051 running at default 8MHz clock
// SVD: STM32F051.svd
// BLUE LED = PC8, blinks about once per second.https://dpaste.com/2BCNX3LZX
// ***********************************************************


volatile int count;

#define  REGISTER_32(ADDRESS) (*((volatile unsigned int *)(ADDRESS)))
#define RCC_AHBENR     REGISTER_32(0x40021014)
#define GPIOC_MODER    REGISTER_32(0x48000800)
#define GPIOC_BSRR     REGISTER_32(0x48000818)


void init(void)
{
   RCC_AHBENR |= 1 << 19;       // I/O port C clock enable
   GPIOC_MODER |= 0x01 << 16;   // set Port C, bit 8 Mode to 01: General purpose output mode
}

void delay(void)
{
 count = 4;
// large for visible blinking
// count = 800000;
while(count--);
}


int main()
{
   init();

   while(1)
   {
   GPIOC_BSRR = 1 << 8;                 // SET PC8 high. led ON
   delay();
   GPIOC_BSRR = 1 << 24;        // CLR PC8, led OFF
   delay();
   }
   return 0;
}

How ?

volatile int count;

#define  REGISTER_32(ADDRESS) (*((volatile unsigned int *)(ADDRESS)))
 // ./readdb -p rcc -r ahbenr -M
 // --->  RCC_AHBENR  --  --  98  Reset:0x00000014  Address: 0x40021014
#define RCC_AHBENR     REGISTER_32(0x40021014)
 // ./readdb -p gpioc -r moder -M
 // --->  GPIOC_MODER --  --  98  Reset:0x00000000  Address: 0x48000800
#define GPIOC_MODER    REGISTER_32(0x48000800)
 // ./readdb -p gpioc -r bsrr -M
 // --->  GPIOC_BSRR --  --  98  Reset:0x00000000  Address: 0x48000818
#define GPIOC_BSRR     REGISTER_32(0x48000818)


void init(void)
{
   // ./readdb -p rcc -r ahbenr -T
   // --->  RCC_AHBENR_IOPCEN 0x40021014  rw  1   19  I/O port C clock enable
   RCC_AHBENR |= 1 << 19;       // I/O port C clock enable

   // ./readdb -p gpioc -r moder -T
   // --->  GPIOC_MODER_MODER8 0x48000800  rw  2   16  Port x configuration bits (y =0..15)
   GPIOC_MODER |= 0x01 << 16;   // set Port C, bit 8 Mode to 01: General purpose output mode
}

void delay(void)
{
   // small for gdb testing
   count = 4;
   // large for visible blinking
   // count = 800000;
   while(count--);
}


int main()
{
   init();

   while(1)
   {
   // ./readdb -p gpioc -R
   // --->  register = BSRR
   // ./readdb -p gpioc -r bsrr -M
   // --->  GPIOC_BSRR_BS8 wo  1   8   Port x SET BIT y (y=0..15)
   GPIOC_BSRR = 1 << 8;                 // SET PC8 high. led ON
   delay();
   // --->  GPIOC_BSRR_BR8 wo  1   24  Port x RESET BIT y (y =0..15)
   GPIOC_BSRR = 1 << 24;        // CLR PC8, led OFF
   delay();
   }
   return 0;
}