Wednesday, June 27, 2012

Bare metal development for ARM Cortex M microcontrolllers

What is bare metal?

Bare metal means running software directly on hardware, instead of running it on top of an Operating System (OS).

And why would you do that? Because sometimes OSes take way too much resources (RAM + Flash), especially when the target device is a low cost microcontroller (uC). Or maybe the application is not very complex and an OS is overkill. Also many OSes are created to run on targets that have a Memory Management Unit (MMU), and your target device might not have one.

Now, using an OS is not a bad thing, quite the opposite it has many advantages. It's highly probable that you are viewing this blog using a device that's running an OS (PC, laptop, smartphone, tablet, etc). And thanks to the OS you can do multitasking in that device, also you can easily add, remove or run software on that device. It's also (almost?) impossible to break or hang the device while developing/running applications, because the OS won't grant other applications access to core/low-level areas of the device.

If you have worked on 8-bit uC from Microchip (a PIC16F877A was my first contact with the world of embedded systems) or AVR (e.g. Arduino) then you have already done bare metal development and have (hopefully) enjoyed the process of controlling at 100% the hardware of a microcontroller.

The ARM world

Today, we have access to more powerful uCs like the ARM-based microcontrollers. Many companies have developed microcontrollers based on the ARM Cortex-M architecture, so there are hundreds of differents uCs, some with more peripherals, others are lower power, but all of them are unified by the ARM architecture, which simplifies the development on these devices.

Specifically, I'm working with the STM32F407VE uC, based on the Cortex-M4 architecture, that has an integrated FPU, which makes operating floating point numbers a snap. Trying to do a multiplication of floats in a 8-bit uC takes way too much Flash and runs way slower. Forget about doing many trigonometric operations or multiplying matrices.

Around 550 bytes needed to mutiply two floats in a 8-bit uC.

Bare metal development on ARM

If you have used IDEs like MPLABX, AVRStudio, etc. Then you have skipped  the (fun) part of setting up the memory distribution, and went straight to code up your application in the main function, after that you clicked the build button to create a hex file or similar, which later you flashed onto your uC to blink a LED, move a motor, etc.

Before jumping into the development, I want you to understand some basics. First, the ARM processor only knows binary (1011...), and in this case that binary is stored in an ELF file. To build this binary from source code (C/C++), which is more human readable, we need a toolchain and a linker script.

The toolchain, contains tools like the compiler and the linker to build the binary; and also provides a debugger, which allow us to run the program in the uC step by step, while observing the inner variables and registers of the uC.

The linker script is basically a map that tells the toolchain how to distribute the memory of the uC, and you can take a glimpse of it's implementation in the following image.

A small part of a linker script.

Obviously, we also need some hardware to flash the ELF file into the uC, and to debug the program in the uC. This hardware needs some connection to the uC, in the case of the ARM microcontrollers this can be via a JTAG or a SWD header. This hardware can be parallel port based or USB based, the latter is far more popular and is sometimes called JTAG dongle.

For example, I started with ARM uCs using a Bus Blaster (JTAG dongle) and a STM32F4Discovery, today I use a custom board for the F4 and a custom JTAG adapter for my projects. (you can see a picture of my hardware, in this post about Kicad)

I have created an Eclipse project template named bareCortexM that wraps all the needed tools, and the source code is available in this repository, go there for hands on experience in bare metal development. The project makes use of the following tools:

+ Eclipse, the IDE that wraps all the tools.
+ GNU Tools for ARM Embedded Processors, the toolchain.
+ openOCD, the glue between the JTAG dongle and the host PC.

On the following image you can see the full setup.

Debugging a STM32F407VE uC using bareCortexM.

Notice that a multiplication of floats takes only 5 instructions, 20 bytes, in constrast with the 500+ bytes of the  multiplication algorithm of the 8-bit uC.

Now that you know how to do bare metal development, you can go ahead and build your own OS or grab a peripheral library and start developing projects. I'll release a template peripheral library for the STM32 microcontrollers later this week. Check my post about libstm32pp, a template peripheral library.

Hands on experience

If you have a STM32 microcontroller + JTAG dongle or a development board like the STM32F4DISCOVERY, then go to this post for a detailed tutorial on how to set up the bareCortexM environment and the libstm32pp peripheral library and start developing on ARM right away.

Saturday, June 23, 2012

3D and footprint libraries for KiCad

KiCad is a Free Open Source Software (FOSS) suite for Electronics Design Automation (EDA). It contains various tools that facilitate the creation of schematics and the design of Printed Circuit Boards (PCB).

In Ubuntu you can get Kicad using the following command:

sudo apt-get install kicad

KiCad can be used without restrictions on PCB size and it's free for non-commercial and commercial purposes. I have used KiCad for a few projects and I'm satisfied with the results.

One of the downsides of KiCad is the small library that comes with it. Luckily, there are quite a few libraries available on the net. Of these libraries, the most helpful one IMO is the Walter Lain's library that contains hundreds of footprints and 3d models.

The aforementioned library comes in two flavors: one for Windows and one for Linux, but I noticed that this wasn't necessary, so I modified the structure of the library to make it work under Windows and Linux at the same time. I have named this modified library "libKiCad" and it's available in the following repository.

For now libKiCad contains the same footprints and 3d models that the original library, but I'll be adding more components as per my needs and as time permits.

Now for the schematics symbols, I think the best place to start is the latest KiCad official library and then create the additional components you need.

I'll try to contact with the maintainers of the KiCad official library and see if I can contribute some schematics symbols I have created.

Monday, June 18, 2012

Ubuntu: Opening/using serial ports as a normal user (without sudo)

A really quick post on how to open/use serial ports without root privileges.

You need to add your user to the dialout group, using the following command:

sudo adduser yourusername dialout

Replace "yourusername" with your username... (e.g. jorge)

You need a reboot to apply the changes.

That's all!

Ubuntu: Hacking the HC-06 bluetooth module

A detailed post about a cheap BlueTooth <-> UART module, often called HC-06, BC417, BT0417C, EGBT-046S, Bluetooth bee, etc.

(Windows user? I have a dedicated post for you, however it only covers the PC-side of the communication. Keep reading this post, and I'll tell you when to switch.)

If you are looking for a cheap and simple way to communicate wirelessly a microcontroller to a PC or to a smartphone, then you should definitively look at the HC-05/HC-06 bluetooth modules, these module are widely available at eBay and DealExtreme, so you can get one shipped to wherever you are.

Both modules have the same hardware, but different firmware. The HC-06 is a slave device, i.e. it can't start the communication (this process is know as pairing in bluetooth jargon) with another device, it needs a master (PC/Smartphone) that pairs with it. On the other hand, the HC-05 is a master/slave device, i.e. it's capable of peer to peer communication with other HC-05 modules, it can be the master of an HC-06 module, it can be a slave of a PC/Smartphone, etc.

Both modules are 3.3V powered and have an 3.3V UART interface, to which we can hook any 3.3V microcontroller or an USB->UART device. 

HC-06 setup and configuration

This time, I'll show you how to interface a Ubuntu PC to a HC-06 a.k.a. "linvor" module, which I got from DealExtreme.

Recommended HC-06 Setup (Datasheet)

Upon powering on the module, the LED will start blinking (if there is another bluetooth device in automatic search mode), telling you that the module is alive.

We can now do some configuration via the UART pins (in my case the default baud rate was 9600, in other modules it might be 38400) sending AT commands, the complete list is shown below:

Command Response Comment
AT OK Does nothing!
AT+VERSION OKlinvorV1.5 The firmware version
AT+NAMExyz OKsetname Sets the module name to "xyz"
AT+PIN1234 OKsetPIN Sets the module PIN to 1234
AT+BAUD1 OK1200 Sets the baud rate to 1200
AT+BAUD2 OK2400 Sets the baud rate to 2400
AT+BAUD3 OK4800 Sets the baud rate to 4800
AT+BAUD4 OK9600 Sets the baud rate to 9600
AT+BAUD5 OK19200 Sets the baud rate to 19200
AT+BAUD6 OK38400 Sets the baud rate to 38400
AT+BAUD7 OK57600 Sets the baud rate to 57600
AT+BAUD8 OK115200 Sets the baud rate to 115200
AT+BAUD9 OK230400 Sets the baud rate to 230400
AT+BAUDA OK460800 Sets the baud rate to 460800
AT+BAUDB OK921600 Sets the baud rate to 921600
AT+BAUDC OK1382400 Sets the baud rate to 1382400

The AT commands are NOT "NULL" terminated neither need a "RETURN" character at the end. They must be sent as shown in the table, i.e. "AT" command are 2 characters, "AT+VERSION" command are 10 characters, and so on.

If you are using a USB->UART device + minicom or similar to send the AT commands, you are going to run into problems, as the HC-06 expects a full command in less than a second, i.e. you need to type "AT+VERSION" in less than a second. I recommend qSerialTerm instead of minicom, as you can send a full string at once.

OK, that's all we can do with an unpaired module. Let's proceed to pair it with an Ubuntu PC and establish a virtual serial port between the PC and the module.

(Windows users: Go to this post, for a proper configuration on the PC).

Pairing with an Ubuntu PC

First, let's find out the MAC address of the device, using the following command on the terminal:

hcitool scan

The output will look like this:

11:22:33:44:55:66       linvor

Where linvor would be the name of your HC-06 and 11:22:33:44:55:66 would be it's MAC address.

We must now add this information to the rfcomm.conf file, rfcomm is a protocol of serial port emulation of the Bluetooth standard. To do so, type the following command in your terminal:

gksudo gedit /etc/bluetooth/rfcomm.conf

In the text editor that appeared, insert the following text (don't copy the line numbers):

Instead of 11:22:33:44:55:66 use the MAC address of your HC-06 module. You can also use any other rfcomm port like the rfcomm1, rfcomm2, etc.

You should reboot your PC to make all the changes to the rfcomm.conf file effective.

After the reboot you can pair your PC to the HC-06 module, using the following command:

sudo rfcomm bind rfcomm0

Where rfcomm0 is the port you configured in the rfcomm.conf file.

This will pair your PC to the HC-06, you can now use rfcomm0 as a serial port, via minicom or qSerialTerm (more details below), to send/receive data to/from the HC-06 module. As soon as you open the rfcomm, the HC-06 led will stop blinking, and stay ON. On this point, the communication becomes a transparent asynchronous serial communication.

Check this post on how to open/use serial ports without sudo.

When you are done with the communication and have closed the rfcomm port, you can use the command:

sudo rfcomm release rfcomm0

To unpair the module and the PC, otherwise the link will stay up until the next shutdown, reboot, logout.

Using rfcomm on qSerialTerm

qSerialTerm relies on the QtSerialPort library, and uses two of it's classes: SerialPort and SerialPortInfo. The SerialPortInfo contains methods that detect the available ports, however it doesn't detect the rfcomm ports at this point. The SerialPort works flawlessly with the rfcomm ports, although some manual configuration is needed as the SerialPortInfo class isn't providing information about these ports.

qSerialTerm (rfcomm branch)

I have modded the qSerialTerm to add support for the rfcomm ports, all the new source code is available in the rfcomm branch (Repository). (The SerialPortInfo issue has been fixed, and the rfcomm branch has been deleted, use the master branch instead)

Now, I'll take a deeper look at the SerialPortInfo class issue. See you later.

I have commited a fix to the QtSerialPort library. Let's see if the reviewers accept the commit.

My commit has been accepted by the reviewers, after lot of nagging from both sides. Now, the master branch of qSerialTerm works with rfcomm devices.

Here is my full testing setup of the HC-06.

HC-06 testing setup. The HC-06 module's Tx/Rx pins are shorted (yellow wire).

Here is my testing session of qSerialTerm with the aforementioned fix applied to the QtSerialPort library.

Testing the qSerialTerm (master branch).

Saturday, June 16, 2012

qSerialTerm: A Qt-based serial port terminal emulator

The asynchronous serial communication is one of the most used communication protocols in microcontrollers(uC), especially when interfacing a uC to a PC. 

Years ago, the RS232 standard with its bulky DB9 connector was pretty much the only medium available to interface a uC to a PC, nowadays we have more interesting options like USB->UART devices (FTDI) and Bluetooth modules(HC-05/HC-06) which look like a serial port to the PC and can be interfaced via asynchronous serial communication by the uC.

For quite some time, I have been using minicom (and I still use it sometimes) as a serial port terminal emulator to receive/send data from/to a uC. But lately, I have run into the need for a more flexible and prettier user interface. So I created qSerialTerm.

 Interfacing a HC-06 Bluetooth module using qSerialTerm. (In Ubuntu)

 Interfacing a HC-06 Bluetooth module using qSerialTerm. (In Windows)

qSerialTerm was developed using the Qt framework, which means it's a cross-platform application. I have released the source code under the GNU GPL, you can get the source from this repository. (Check this post about installing Qt creator, my preferred IDE for Qt development)

I'm currently building a data logger on top of this application, you can get a peek of the current status in the following image.

This data logger still needs some tuning, I'll be releasing the source after that.
Check this post about using qSerialTerm for data plotting.

But right now, I'll continue playing with the Bluetooth module. :)

Friday, June 15, 2012

Ubuntu Tip 02: Octave 3.6.1 in Ubuntu 12.04

UPDATE: Ubuntu 12.10 comes with Octave 3.6 and also the extra packages are in the repositories. It's better if you install directly from the repositories instead of using this steps, because it's easier to remove the extra packages later.

Last time I showed you how to get octave to run on the guake terminal at startup. For that tutorial, Octave 3.2, which is available in the universe repository, was used. This time, I'll show you how to install the version 3.6.1.

Normally installing Octave would require compiling from the source, which can take a few hours. Luckily, picaso has already done the hard job and has packed the compiled source in a nice PPA (

The installations steps are shown below, the first step is for those who have already installed octave 3.2

sudo apt-get remove octave # If you have installed octave 3.2
sudo apt-add-repository ppa:picaso/octave
sudo apt-get update
sudo apt-get install octave

Congratulations, you have installed a newer version of octave and have access to the core functions of Octave.

 If you are interested in more advanced functions for image processing, signal processing, control systems, etc. Then you need to get additional "packages" from here (

These extras packages must be compiled into our new Octave installation, and to compile them we need the "pkg" commands, which can be obtained using the following command.

sudo apt-get install liboctave-dev

(Note: Thanks to picaso for pointing out that octave-pkg-dev is deprecated, and that liboctave-dev should be used instead)

Using an example, I'll show the installation process of an Octave package.

 Let's say we want to install the "signal" package. First check the details of the package here. You'll notice that there are many dependencies that must be installed in the following order:

After downloading all the necessary packages, we proceed to compile them in octave:

sudo octave
# The following commands must be executed inside a rooted octave
cd /path/to/the/downloaded/packages
pkg install miscellaneous-1.1.0.tar.gz -auto
pkg install struct-1.0.10.tar.gz -auto
pkg install optim-1.2.0.tar.gz -auto
pkg install specfun-1.1.0.tar.gz -auto
pkg install control-2.3.51.tar.gz -auto
pkg install signal-1.1.3.tar.gz -auto
pkg install image-1.0.15.tar.gz -auto

(Note: The -auto modifier, tells the package manager to load that specific package when octave starts. For more information check "help pkg" in octave)

We're done, now we can start using the advanced features of octave (You might need to restart octave to enable the just installed packages).

Tuesday, June 5, 2012

Ubuntu Tip 01: Octave on Guake Terminal at Startup

UPDATE: I recommend using Screen to manage multiple applications in a terminal, you can use it with Guake as well. Check this post.

The Guake Terminal

Are you heavy user of the Command Line Interface (CLI)? Yes? Have you heard of guake? No? Well, guake is a nice program that allows you to invoke and hide the gnome terminal with one key stroke.

Using guake saves time on launching/closing the gnome terminal multiple times, because guake always uses the same instance of the gnome terminal.

Installing guake is easy, it's in the ubuntu universe repository, only type the following command in your terminal.

sudo apt-get install guake

You can now launch guake via dash (super key) or via command (Alt + F2).

Guake is now running, you can show/hide it using the F12 key. Other useful shortcuts are (Ctrl + Shift + T) which opens a new tab in the terminal, (Ctrl + PgUp/PgDown) which cycles through the tabs and F11 which toggles on/off the full-screen mode.

OK, time to do some customization, launch guake preferences (via dash), you can modify various settings like background color, font color, transparency, windows height, etc. Be creative!

In case you are wondering, the default background color of the gnome terminal (which I'm using) is #300A24.

Let's move to octave now!


GNU Octave is a high-level language, very useful for numerical computations in engineering and science. If you have used MATLAB before, Octave is pretty much the same, only that it's open source.

You can get octave (version 3.2, which is kind of old) from the universe repository, using the following command.

sudo apt-get install octave

Octave runs from the Command Line, so let's call it from the guake terminal.

Now we have an easy access to a powerful calculator, let's make a script that launches guake with octave inside it at startup.

Putting them together at startup

Type the following commands in the gnome terminal.

cd ~
mkdir scripts
cd scripts

On the text editor that popped paste the following code (don't copy the line numbers):

Save the .sh file, and let's make it executable using the following command.

cd ~/scripts
chmod 755

Let's add this script to the startup applications. Launch startup applications from dash.

Click on the add button, add some description and browse to the script file.

We're done. Reboot and start using octave as a calculator, plotter, etc.

MUST SEE: How to augment Octave capabilities using Vim.

Monday, June 4, 2012

Hello World!

Hi there and welcome to my personal blog.

My name is Jorge Aparicio and currently I'm a mechatronics engineering undergraduate at National University of Engineering.

The main purpose of this blog is to share my experiences with embedded systems, hardware and software-wise, while I improve my writing skills and my knowledge of HTML and JavaScript.

Currently I'm working with ARM-based microcontrollers, namely the STM32F1 and STM32F4 families, and I have assembled a cross-platform toolchain and an efficient (I think) template library, which I'll open source really soon.

I'm an Ubuntu user, so I'll be posting some nice tips weekly.

Stay tuned.