So my first post on here concerns setting up a minimalist environment for embedded development with the ARM toolchain (we’ll also be looking at the AVR toolchain before too long). Luckily, this is incredibly easy. Like you might imagine from the title of my blog, I’m not big on fluffy bullshit and even more so, I despise using tools that are designed to make me dependent on a certain (usually proprietary) framework. So don’t expect any IDE tutorials or examples of how to develop on Windows. I am strictly a Linux/VIM/GNU man, and I’m sure as hell not going to pay for anyones framework when I have quality tools for free. Sure, I’m probably not as “productive” as the Keil fanboys but at the very least, I know that my code isn’t dependent on a specific framework that might not be here one day. I also get the satisfaction of having complete control over my environment, which appeals to my inner control freak.
Anyways, I’m currently running Ubuntu 16.04 and I’m assuming if you are reading this, you are also on some sort of Linux distro and you know how to get vim and arm-none-eabi-gcc etc. from the terminal. However, believe it or not, I actually do all of my embedded development remotely by ssh-ing into my Raspberry Pi 3, which serves as my swiss army knife programmer/debugger via its very convenient GPIO pins and access to OpenOCD. Personally, I recommend following my lead so as not to have to buy any messy programmers (which may or may not have the nasty surprise of working only on Windows).
Luckily on the Raspbian OS that I am running on my Raspberry Pi 3, it isn’t difficult to get the arm-none-eabi toolchain setup using the usual
sudo apt-get install arm-none-eabi-gcc
which also conveniently installs the arm-none-eabi-binutils package as well. I can’t quite recall if my RPi3 came preloaded with vim and GNU Make but it should be fairly obvious how to acquire those programs. Now in order to utilize the RPi3 as a programmer/debugger for an ARM board, we need to get a program called OpenOCD. Unfortunately, it isn’t as simple as
sudo apt-get install openocd
since the default configuration doesn’t suit our purposes. In order to customize the package to suit our needs, we are going to have to compile it from the source, which is much less intimidating than it sounds.
In fairness, I totally ripped this setup off of Ryan at MOVr0 so credit him with the legwork on this one. First we need a few packages
sudo apt-get install git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev telnet
and then to compile from the source we simply run
git clone git://git.code.sf.net/p/openocd/code openocd
which gives us a nice little folder aptly titled “openocd” and from there we can compile
cd openocd ./bootstrap
which will download a few dependencies after which we can configure our build with
./configure --enable-maintainer-mode --enable-bcm2835gpio --enable-sysfsgpio
after which we can sit back and enjoy after we run
and finally we can install it with
sudo make install
Now that our OpenOCD build is taken care of, we’ll step back to setting up our environment for our first project. Right now, I have an STM32-L452RE Nucleo board that I’m experimenting with and I’ve quickly discovered that STM really likes to get their hooks into you with their fancy Hardware Abstraction Library. Well the last thing I’m interested in is being abstracted away from the hardware, so I’m definitely not going to be using it. I wAnyill however succumb to the use of the CMSIS library since it is standardized across all of the ARM providers and provides all of the register definitions which saves a ton of work. Anyways, since we are still just experimenting, I usually just do something like
mkdir armfun cd armfun
and create a few essential files right off the bat
vim makefile vim main.c vim aux.c vim main.h vim aux.h
Unfortunately, before we can even begin to write any code, we have to go to the STM website and get the “STM32CubeL4” and extract the relevant files. Personally, I just take all of the files I’ll need and put them into my directory. The files we need are in
and the files we need are
cmsis_gcc.h //CMSIS/Include core_cm4.h //CMSIS/Include core_cmFunc.h //CMSIS/Include core_cmInstr.h //CMSIS/Include stm32l4xx.h //Device/ST/STM32L4xx/Include stm32l452xx.h //Device/ST/STM32L4xx/Include system_stm32l4xx.h //Device/ST/STM32L4xx/Include system_stm32l4xx.c //Device/ST/STM32L4xx/Source/Templates startup_stm32l452xx.s //STM32Cube_FW_L4_V1.11.0/Projects/NUCLEO-L452RE-P/Templates/SW4STM32 STM32L452RETx_FLASH.ld //STM32Cube_FW_L4_V1.11.0/Projects/NUCLEO-L452RE-P/Templates/SW4STM32/STM32L452RE_NUCLEO
which gives us all the files we need to utilize the CMSIS library. Take a look at the “startup_stm32l452xx.s” file and ponder what makes this file so special as to be the lone assembly program included. Just a little hint: C requires a stack to be initialized. Can you see where the startup file does this? In my next post, we’ll create a makefile for our mini-project and start actually writing some code.