Getting Started with nanoFramework – Build CLR (Part 1)

Introduction

If you were a fan of .NET Micro Framework like me, I’m sure you were deeply disappointed to see Microsoft slowly killing the NETMF platform. There might have been valid business reasons to do so, but then, for people who are passionate about .NET and C#, having the ability to use the same skills on an embedded platform was very exciting.

With Microsoft dumping the NETMF platform, the small number of hardware vendors also started to disappear (e.g. Netduino). It came to a point where practically no one (you might argue GHI Electronics still exists) was actually doing good business around the NETMF set of technologies. Things can only move up from here !

A group of people have started this new open source initiative called “nanoFramework” (“NF”) which is an attempt to re-create the NETMF magic without the dependency on Microsoft (I’m not an insider to the NF team so this is by best guess).

Who is this blog for

I’m a C# application developer and have worked on Netduino, G30 , Arduino, Windows 10 IoT core, Raspberry Pi etc. in my free time as a hobby. One day, I dream of have a viable business around these…but that’s another story 🙂

This blogs will walk you through the process of creating the “Booter” and the “CLR” that you can flash on an STM32 micro controller and then, use the Visual Studio IDE to write embedded C# code. Re-live your NETMF days !

Given that I’m an application developer, I do not understand many internal details of the implementation. My objective is to get you started with coding on a micro controller using C# as soon as possible. Having struggled for sometime in this process and then succeeding after great help from the folks at nanoFramework Github community I though of writing down the process…which is why this blog.

What will we accomplish

A bit of background first. In order for you to be able to write code in C# on a microcontroller, we need to understand (at a high level) , how this works. There are 4 logical components in this as shown below:

=====================================================
|                                        Your Application (Level 4)                        |
=====================================================
|                                           The CLR  (Level 3)                                    |
=====================================================
|                                            Booter  (Level 2)                                      |
=====================================================
|                                 The MCU Hardware (Level 1)                          |
=====================================================

At the highest level is your C# based application that needs to run on the MCU. Below that, you need the CLR. This CLR is fine-tuned to run on the MCU with it’s limited resources. The booter is a special piece of code, that starts the common language runtime when you switch on the MCU. Why we cannot have the booter within the CLR itself is something I do not understand. But again, since I’m not an expert on this subject and my focus is on application programming, I did not delve much into this topic (See response from from Christophe in the comments section). Finally, at the lowest level, we have the MCU.

The MCU is “off-the-shelf” (an STM32), therefore, we need a custom booter and a custom CLR for the MCU we have chosen.

This blog will focus on how to build the source code that produces the booter and the CLR. At the end of this exercise, you should see a bunch of files named nanoBooter.* and nanoCLR.* (where extension could be .s19, .hex and .bin).

These two files (either .s19/.hex/.bin) need to be burned/flashed/put into the MCU before we can write our C# application.

What will you need

Before you begin, you need the following ready with you:

  1. A windows 10 PC/laptop
  2. Visual Studio Code (I have V 1.17.1)

Code and tools downloads

Now, as a first step, create a folder where all required code artifacts and tools will be downloaded. Let’s assume, the root folder is D:/nanofw .

  1. Create a folder D:/nanofw/chibios_18.2.x . Download ChibiOS from here (NF uses ChibiOS RTOS, so this is required for the build)
  2. Create a folder D:/nanofw/cmake-3.7.2. Download CMake 3.7.2 from here (NF is built using the cmake tool)
  3. Create a folder D:/nanofw/gcc-gnu-7.2 . Download GNU GCC 7.2 from here  (The complier, linker and assembler to build code for the target MCU)
  4. Create a folder D:/nanofw/ninja-1.8.2 . Download ninja 1.8.2 from here (The build system to process the make files.)
  5. Create a folder D:/nanofw/src. Download the NF source from here . (The source for the NF booker and NF CLR.)
  6. Create a folder D:/nanofw/src/targets-community . Download source from here  . (The required customizations to port the NF code to specific boards. If you see, one sub-folder in this repository is named ST_NUCLEO64_F401RE_NF. This contains all required customizations to create a NF image that will run on STM32F401RE MCU)
  7. Create a folder D:/nanofw/build. This is the folder, where all files will be dumped during the build process. You should delete the contents of this folder before each build (I had issues when contents were not cleared).

NOTE: A lot of random build issues that I faced during the process, were resolved by just comparing the files in the Github repository and on the D:/ drive. Many a times, for some reason, files were not getting copied properly during an internet download or during extract. This was a major pain so be extra careful.

Environment variables setup

Add the following folders to your PATH environment variable

  1. D:/nanofw/cmake-3.7.2/bin
  2. D:/nanofw/gcc-gnu-7.2/bin

Visual Studio Code setup

Install the following extensions to your VS Code :

  1. CMake (I have V 0.0.17)
  2. CMake Tools (I have V 0.10.4)

Preparing for build

Open VS Code and open the folder D:/nanofw/src .

  1. Create a file named settings.json under .vscode folder. This file specifies the name of the tool that will act as the CMake generator. Remember, we downloaded the “ninja” tool for this. I was not able to use the Visual Studio make tool due to various errors, so based on suggestion from the feedback from good people at NF Github I used ninja tool. My settings.json file looks like this.
  2. You (perhaps) need a launch file. Create a file named “launch.json”. It contains instructions on how to launch the program after successful build. Given that I was not using VS code for launch and debug activities, I no longer use this (I did set this up though). Since I do not know how the build will behave if I do not have this (yet to experiment with this), go ahead and have a launch.json file. You can look at launch.TEMPLATE-ESP32.json and create your own. It requires path to OpenOCD debugger (if you plan to launch and debug from VC Code, but then, that is not our intention). If you want to know how to use VS Code for debugging NF code, read the details here.
  3. Create a file named cmake-variants.json in D:/nanofw/src folder. This file contains the instructions to build cmake files. For the STM32F401RE Nucleo board, my file looks like this. It contains entries for many boards (e.g. Netduino, STM32F091RC) including the target board STM32F401RE. You can read about the description of the keys here and here.

Building the code

You are now ready. From the bottom bar on VS Code, select a CMake configuration (e.g. release, debug) and wait for the system to generate appropriate files. When I select Release + STM32F401RE board configuration, the output on my VS Code is this .

Once you see the files are generated, the next step is to build. Simply click the labeled “build” at the bottom bar of VS Code. After a while, if all goes well, you should have the nanoBooter.hex and nanoCLR.hex files in your build directory. The build output should look like this.

Note: The nanoFramework image may be copyright of the respective owner(s). It is used only for easy identification of the platform.

3 thoughts on “Getting Started with nanoFramework – Build CLR (Part 1)

  1. Thank you for this nice blog post (and for the others !).

    Regarding your question about the booter, it is a very small piece of code that is handling actions that have to take place _before_ the CLR takes control and starts your C# application.
    It can do “nothing” and only start the CLR (and so start your C# program) but it could also wait for some update code as well, for example.

    _______
    Christophe

Leave a comment