Svd2gas - The Freedom To Assemble¶
Computer programming takes many forms, from the low level languages, to the HLL’s, from machine code to LISP and everywhere inbetween.
Machine Code¶
The lowest level is called ‘Machine Code’ which are hexadecimal numbers and the only language that the CPU understands, so all programming languages eventually distill down to this, so that the CPU can understand what it has to do.
While the CPU understands Machine Code perfectly, to us it looks like the streaming screens of glyphs, or green rain which featured so prominently in the film ‘The Matrix’.
Partial hexdump of mecrisp-stellaris-stm32f051.bin (Can you see the Woman in the Red Dress ?)
0000000 0330 2000 376d 0000 35fd 0000 35fd 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 3627 0000
0000030 0000 0000 0000 0000 3627 0000 35db 0000
0000040 3627 0000 3627 0000 3627 0000 3627 0000
0000050 3627 0000 364b 0000 366f 0000 3695 0000
0000060 3627 0000 3627 0000 3627 0000 3627 0000
0000070 36b7 0000 36db 0000 36ff 0000 3721 0000
0000080 3745 0000 3627 0000 3627 0000 3627 0000
0000090 3627 0000 3627 0000 3627 0000 3627 0000
Assembly Language¶
One step above Machine Code is a programming language called Assembly Language which is far more friendly to Humans. Here hecadecimal numbers are replaced by Mnemonics which are a tool to help us remember them, it’s similar to how a web url is easier to remember than a IP address, or used to be before machine generated URL’s became 500+ characters long.
Mecrisp-Stellaris Forth is written in Assembly code, here is a snippet from the STM32F051 Cortex M0 terminal.s file.
@ GPIO register map is similiar to STM32F4 chips.
.equ GPIOA_BASE , 0x48000000
.equ GPIOA_MODER , GPIOA_BASE + 0x00
.equ GPIOA_AFRH , GPIOA_BASE + 0x24
@ Set PORTA pins 2 (TX) and 3 (RX) in AF1 for USART2
ldr r1, = GPIOA_MODER
ldr r0, = 0xA0
str r0, [r1]
@ Set alternate function 1 to enable USART1 pins 9 AND 10 on Port A
ldr r1, = GPIOA_AFRH
ldr r0, = 0x110 @ Alternate function 1 for TX and RX pins of USART1 on PORTA
str r0, [r1]
This is far more readable than Machine Code and far easier to write if you’re a Programmer. You don’t have to continually consult a opcode manual to find what the Hex number is for ‘ldr’ (load register) for example.
Assembly Language is far less error prone than Machine Code. The first commercial embedded project I made (1985), was a bottle filling controller, which filled 5000 bottles of hospital saline solution a day and consisted of about 1500 lines of machine code. If I recall correctly, that meant I also made about 1500 errors writing and debugging that code ;-)
A good Assembly Language programmer can generally write the fastest and smallest programs possible when compared to any other programming language.
Assembly Language programs are reasonably easy to read when commented well like the example above and this reads to a programmer like ‘go to the shop and buy 2 litres of chocolate ice-cream’ reads to non programmers.
This article isn’t actually about how to use the GNU Assembler because that alone would require vast amounts of your time, but a basic background helps to explain why I wrote svd2gas.
In the Mecrisp-Stellaris Forth Assembly Language snippet above, you can see the words ‘GPIOA_MODER’ and ‘GPIOA_AFRH’ which are STM32F MCU ‘Registers’, and these are just two of the hundreds, perhaps even thousands or Registers inside STM32F MCU’s depending on the model.
When the code says ‘ldr r1, = GPIOA_MODER’ it means ‘load r1 with the memory address of GPIOA_MODER.
We know that GPIOA_MODER lives at the memory location 0x48000000 from the ‘Equate Statement’ ‘.equ GPIOA_MODER , GPIOA_BASE + 0x00’ and so on.
Having armed yourself with the GNU AS (assembler) manual, you’re now ready to start programming, or are you ? Is there a list of all the Equate Statements available, or will you have to write them all yourself by referring to the STM32F Cortex M0 manual ?
svd2gas¶
Svd2gas will automatically generate files containing Assembly Language Equate and helpful Bitfield Statements using only the freely available CMSIS-SVD file for your STM32F Cortex M MCU. This provides a consistent naming strategy throughout your program, making code reuse and sharing that little bit easier.
I wrote svd2gas after hacking the Mecrisp-Stellaris assembly source and noticing that there didn’t seem to be a freely available list of equate statements for Cortex M available on the Internet.
Note
Did you know that the complete equate statements file, (including bitfields) for a low end STM32F0xx Cortex M0 is 3987 lines long or that the same thing for a high end STM32F7x Cortex M4 is 17838 lines long ?
CMSIS¶
Cortex Microcontroller Software Interface Standard (CMSIS)
The CMSIS enables consistent and simple software interfaces to the processor for interface peripherals, real-time operating systems, and middleware. It simplifies software re-use, reducing the learning curve for new microcontroller developers and cutting the time-to-market for devices.
CMSIS-SVD¶
System View Description for Peripherals.
Describes the peripherals of a device in an XML file and can be used to create peripheral awareness in debuggers or header files with peripheral register and interrupt definitions.
Assembler Toolchain¶
To assemble any code for Cortex-M you’ll require the arm-none-eabi-binutils package from your Linux or *bsd repository, Or you can install from a Tarball.
arm-none-eabi-binutils GNU binutils for bare metal arm cross-development
svd2gas README¶
SVD2GAS, Copyright Terry Porter 2017 "terry@tjporter.com.au"
This program auto generates equate statements for all registers in a STM32XX for arm-none-eabi-as using CMSIS-SVD
Licensed under the GPL, see http://www.gnu.org/licenses/
Developed on FreeBSD but also tested on a Linux Ubuntu 16.04.1 x64 VM
Howto
=====
* Untar this tarball to a directory
* Save your STM32Fxx.svd in it
* Edit the makefile line "FOLDED_SVD =" to suit your STM32xx.svd
* Run make, and the following files will be created
a) STM32xx.svd.uf.svd, created from STM32xx.svd
b) template.xml, which is a list of all the registers in your MCU.
c) STM32Fxx.svd.inc containing bit definitions for fields of width 1, or shifts amounts for fields with a width greater than 1 bit.
Comment out the registers you don't want in template.xml and run make again to recreate the STM32Fxx.svd.inc file.
==================================================================================================================
How to comment out registers in template.xml ?
==============================================
Not commented out: <name xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">RCC</name>
Commented out: <!-- <name xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">RCC</name> -->
Release contents
================
Makefile
mk.template.xsl
README.txt
svduf.xsl
svd2gas.xsl
Dependencies
============
make or gmake
xsltproc
vim (or any editor, change it in the Makefile)
Where to get STM32F SVD files ?
===============================
1) https://github.com/posborne/cmsis-svd
2) arm.com (free account required)
Getting svd2gas¶
Demo Assembly Blinky¶
This is a demo Blinky written in pure assembly language by the author of Mecrisp-Stellaris