I presented in the previous post my adventures with porting .NET nanoFramework to Linux and NuttX. In this article I will document how you can run .NET nanoFramework applications using the Linux port.

.NET nanoFramework Solution (Linux Mono)

You can use any solution created by the .NET nanoFramework extension for Visual Studio. Unfortunately, there is not yet a template for the dotnet CLI (to be independent of VS 2019 for example). For this case, I created an example that you can clone the repository.

⚠️ For the following steps we will use commands that are part of Mono. Make sure you have the latest mono-complete package installed on your Linux distro.

Follow the steps with a terminal opened:

1- Clone the repository of examples:

git clone https://github.com/dotnuttx/nanoFrameworkPOSIX-samples.git

2- Go to the CSharpHelloWorld folder:

cd nanoFrameworkPOSIX-samples/CSharpHelloWorld

For this example we will compile the following Program.cs:

using System.Diagnostics;
using System.Threading;
using nanoFramework.Runtime.Native;

namespace CSharpHelloWorld
{
    public class Program
    {
        public static void Main()
        {
            Debug.WriteLine($"Hello from nanoFramework on {SystemInfo.OEMString}!");

            Thread.Sleep(Timeout.Infinite);
        }
    }
}

3- Download the NuGet packages listed in packages.config, run:

nuget restore

⚠️ The v2.6.4.6 version of the interpreter for Linux needs exactly the 1.10.5-preview.18 version of the nanoFramework.CoreLibrary package

4- Compile the solution, run:

msbuild

After the build you should have the following files with the .pe extension in the project's bin/Debug/ folder:

ls -l bin/Debug/*.pe

-rw-r--r-- 1 castello castello   456 Jun 22 17:17 bin/Debug/CSharpHelloWorld.pe
-rwxr--r-- 1 castello castello 31668 Jun 19 07:25 bin/Debug/mscorlib.pe
-rwxr--r-- 1 castello castello  1496 Jun 19 07:46 bin/Debug/nanoFramework.Runtime.Native.pe

These are the Portable executables/assemblies that the .NET nanoFramework interpreter knows how to read and execute. If you have them listed in the bin/Debug/ folder, congratulations 🎉 you have successfully compiled the application.

nanoFramework Runtime (Linux x86-64)

You can download pre-compiled Linux interpreter binaries here: https://github.com/dotnuttx/nf-Community-Targets/releases

For Linux x86-64 architecture we have two flavors of the binary:

⚠️ The .debug version of the binary is compiled with debug symbols and some trace by print enabled. It will be useful if you are working on interpreter development.

To install the runtime, download the binary, add execute permissions and move to /usr/bin/:

wget https://github.com/dotnuttx/nf-Community-Targets/releases/download/v2.6.4.6/dotnet-nf.x86-64-Linux.2646
chmod +x dotnet-nf.x86-64-Linux.2646
sudo mv dotnet-nf.x86-64-Linux.2646 /usr/bin/dotnet-nf

Now we can finally use the runtime, to run our compiled application in the first steps. The binary takes as argument the path of a folder where it will load all listed .pe files. Go to the CSharpHelloWorld/ folder of the example repository and run:

dotnet-nf bin/Debug/

If you have something like the following output:

⚠️ The SystemInfo.OEMString property on POSIX platforms will present the same information as the uname -a command, probably this info will be different on your Linux.

Congratulations 🎉! You've run your first .NET nanoFramework application on Linux.

Conclusion

Having nanoFramework running on Linux is a nice option, for anyone who wants to study the internals of nanoCLR, to test and debug using the penguin system 🐧.

⚠️ Remembering that this is something I am working on weekends and during my free time. It's 'EXTREMELY EXPERIMENTAL' and I'm not being funded by any group or institution for do it.

Did you like the possibility? If this is in any way helpful, or makes sense to you, let me know. Send me a hello on Twitter @math_castello or Linkedin 👍