{"id":995,"date":"2019-09-23T18:14:02","date_gmt":"2019-09-23T17:14:02","guid":{"rendered":"https:\/\/mightydevices.com\/?p=995"},"modified":"2019-09-24T09:23:21","modified_gmt":"2019-09-24T08:23:21","slug":"building-bare-metal-stm32l4-firmware-using-clang-llvm","status":"publish","type":"post","link":"https:\/\/mightydevices.com\/index.php\/2019\/09\/building-bare-metal-stm32l4-firmware-using-clang-llvm\/","title":{"rendered":"Building bare-metal STM32L4 firmware using Clang\/LLVM"},"content":{"rendered":"\n<p>In this tutorial I&#8217;ll show you how to build a basic bare-metal application for Cortex-M4F micro-controller using LLVM without having to resort to building the LLVM toolchain itself which can be tedious and time consuming. All in all LLVM is recognized for it&#8217;s ability to compile for different architectures (a.k.a cross-compile) so we should be good even using the most <em>default<\/em> of packages.<\/p>\n\n\n\n<p>The following steps were done on Alpine Linux image using Windows -hosted Docker (image <code>alpine:latest<\/code>) but all of it shall be applicable to other operating systems.<\/p>\n\n\n\n<p>From this point on I&#8217;ll assume that you have Docker installed and ready. So let&#8217;s begin by building the image with all tools necessary for development. Get the Dockerfile that I&#8217;ve prepared for this tutorial from here:  <a href=\"https:\/\/github.com\/MightyDevices\/docker-llvm-arm-none-eabi-builder\">https:\/\/github.com\/MightyDevices\/docker-llvm-arm-none-eabi-builder<\/a>  Open up the command prompt in the directory where you&#8217;ve put the Dockerfile and type in the following command to build the image:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker build -t arm-build .<\/code><\/pre>\n\n\n\n<p>Image will go by the name <code>arm-build<\/code>. This process may take a while as couple of things needs to be done. Firstly clang\/llvm toolchain is installed which is followed by GNU make installation. Then we download the <code>arm-none-eabi<\/code> toolchain so that we have libraries (like <code>libm<\/code> for math) for our projects.<\/p>\n\n\n\n<p>After the image build is done we can start the container in interactive mode with \/bin\/sh interpreter running. Docker also allows us to use a directory that will be shared between the Host OS (In my case: Windows) and Guest OS (Alpine) so let&#8217;s have that one as well and use it to store the project files. The command for all of that should look like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir share\ndocker run -it -v\"%cd%\/share\":\/share arm-build sh<\/code><\/pre>\n\n\n\n<p>Here I&#8217;ve used the Windows magical <code>%cd%<\/code> in order to get the full path to the current directory. Docker on Windows has a hard time with relative paths. After executing the command you&#8217;ll be left with the Alpine Linux shell.<\/p>\n\n\n\n<p>Let&#8217;s now get the source files for the test project and try to adapt them to this build environment. How about we use something simple, like this one:  <a href=\"https:\/\/github.com\/MightyDevices\/startup-stm32l433\">https:\/\/github.com\/MightyDevices\/startup-stm32l433<\/a>. Let&#8217;s clone it into the &#8216;share&#8217; directory. In the Alpine Shell type in following commands<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd \/share\ngit clone https:\/\/github.com\/MightyDevices\/startup-stm32l433\ncd startup-stm32l433<\/code><\/pre>\n\n\n\n<p>This project was prepared to be build either with GCC or with LLVM. In order to build with LLVM Toolchain one needs to use the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make TOOLCHAIN=llvm<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"1836\" height=\"958\" src=\"https:\/\/mightydevices.com\/wp-content\/uploads\/2019\/09\/error.gif\" alt=\"\" class=\"wp-image-1013\"\/><\/figure>\n\n\n\n<p>If you do that you&#8217;ll notice an error that is caused by the lack of include files\/ libraries. The LLVM is a great for cross-compiling but it comes with no prebuild libraries and header files, and since we want to avoid the need of building these let&#8217;s use the libraries from the official ARM GCC Toolchain.<\/p>\n\n\n\n<p>In the project&#8217;s Makefile look for the lines that contain the <code>INC_DIRS<\/code> and <code>LIB_DIRS<\/code>.  Since the docker image build process took care of downloading the  ARM GCC Toolchain let&#8217;s now point the Clang to proper directories that contain all the necessary files. For the includes append the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INC_DIRS += \/gcc-arm-none-eabi-8-2019-q3-update\/arm-none-eabi\/include\nINC_DIRS += \/gcc-arm-none-eabi-8-2019-q3-update\/lib\/gcc\/arm-none-eabi\/8.3.1\/include<\/code><\/pre>\n\n\n\n<p>and for the libraries use the paths below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>LIB_DIRS += \/gcc-arm-none-eabi-8-2019-q3-update\/arm-none-eabi\/lib\/thumb\/v7e-m+fp\/hard\/\nLIB_DIRS += \/gcc-arm-none-eabi-8-2019-q3-update\/lib\/gcc\/arm-none-eabi\/8.3.1\/thumb\/v7e-m+fp\/hard\/<\/code><\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter is-resized\"><img loading=\"lazy\" src=\"https:\/\/mightydevices.com\/wp-content\/uploads\/2019\/09\/Makefile.gif\" alt=\"\" class=\"wp-image-1007\" width=\"419\" height=\"462\"\/><\/figure><\/div>\n\n\n\n<p>This complex path name comes from the fact that we use a Cortex-M4F micro-controller which has the <code>armv7e-m<\/code> core with hardware floating point unit (FPU), hence the <code>hard<\/code>at the end of the path. If you were to build a project for different core\/FPU these would need to be altered accordingly. After all that you should end up with a working binary image, again, by issuing the <code>make<\/code> command<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>make TOOLCHAIN=llvm<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"1836\" height=\"958\" src=\"https:\/\/mightydevices.com\/wp-content\/uploads\/2019\/09\/ok.gif\" alt=\"\" class=\"wp-image-1014\"\/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial I&#8217;ll show you how to build a basic bare-metal application for Cortex-M4F micro-controller using LLVM without having to resort to building the LLVM toolchain itself which can be tedious and time consuming. All in all LLVM is recognized for it&#8217;s ability to compile for different architectures (a.k.a cross-compile) so we should be&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[6,5],"_links":{"self":[{"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/posts\/995"}],"collection":[{"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/comments?post=995"}],"version-history":[{"count":15,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/posts\/995\/revisions"}],"predecessor-version":[{"id":1016,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/posts\/995\/revisions\/1016"}],"wp:attachment":[{"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/media?parent=995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/categories?post=995"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mightydevices.com\/index.php\/wp-json\/wp\/v2\/tags?post=995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}