Search for the lost CultureInfo

In the .NET world if we want to localize an application we usually make use of resources. We can create a resource (a dictionary of words) for every language and .NET would figure out which resource to load.

This way the application is translated to every language by just adding a resource file to the application.

The CultureInfo

The way .NET knows which resource to use is by looking at the CultureInfo stored in the current Thread, so .NET is looking at the following static property   Thread.CurrentThread.CurrentUICulture.

Before .NET Framework 4.6 the CultureInfo was not passed to child threads. This is a problem of windows itself because the CultureInfo is not a part of the thread. In .NET Framework 4.6 they changed the behavior so that the CultureInfo is passed to the child threads. Also they introduced the property  CultureInfo.DefaultThreadCurrentUICulture, this property is pretty self-explanatory, it controls the default CultureInfo for every new thread.

The async problem

When creating a WPF application and setting the CultureInfo to a specific culture at first it looks like it works as expected but after a sometime the CultureInfo is set back to the default value (in my case en-US). This only happens when we mark the method  OnStartup async.

This is the code used in the App.xaml.cs (the WPF startup file).

In the sample we first get a specific culture and then set it on the CurrentUICulture and on the  DefaultThreadCurrentUICulture, this should make sure that the resource used by .NET Framework is the resource for nl-NL. After setting the CultureInfo we call Show on the MainWindow. The MainWindow looks like this.

The only thing that the MainWindow does is log the CultureInfo of the current thread.

This is the log that is produces by the code.

You can see that after the line  [App] Culture nl-NL, the following lines tells us that the CultureInfo is now en-US. The line [App] is produced at the end of the OnStartup method.

The explanation

The strange sequence produced by the log is actually explainable. A part of the change in .NET Framework 4.6 is also a change in the behavior of Task/Async. The change in behavior is that the CultureInfo of a thread will be captured when thread is started and then restored afterwards. In this sample the method OnStartup is async so the CultureInfo will be captured at the start of the method, at that moment the CultureInfo is still the default value en-US and is restored at the end of the method. So regardless of what I do in the async method, it will always be restored to the previous value.

So in the end we have found the lost CultureInfo…….

Fast GPIO with C++

After fiddling a few weeks with the Onion Omega2+ I wanted to see how I can use the GPIO pins of the Omega2. So for this weeks challenge I will try to pulse a LED with the help of C++ code.

If you don’t know how to compile C++ code for the Omega2 please read this post.

The bug

My first attempt failed because there is a bug in the Omega2 firmware. The bug still exist in the latest build (as of writing b156). The bug is fixed in the latest version 0.1.10.

The current version has the bug that it does not expose the /dev/mem file which we need to write directly to the registers of the Omega2.

So before we can start to code we need to fix our environment by downloading b137. Use the following command to downgrade if needed. Be sure to check if the latest version doesn’t already fix it, if the latest versions does fix it follow the instructions here to upgrade. After using the command wait for the Omega2 to stop blinking.

Using Fast-GPIO

The guys at Onion have done a great job with providing us a C++ library on GitHub here, this is actually the command line tool for controlling the pins. You can use the following command to set pin 1 to high.

We are going to use this code so we don’t have to figure out ourselves where the registers live in memory.

We can use the following command to pull the package to our PC, just remember where you put it we need it later on.

Setting up the IDE

For the IDE I use visual studio code, which is a free IDE from Microsoft, it is available here. To make it easy to work with c++ we are going to install the C/C++ extension for the IDE. Press the shortcut CTRL + P and enter following command to install the extension.

When your finished restart the IDE.

The code

You can find all the source code on the github repository here, but you can also type along.

First up we need a directory to work in, so setup a directory and create a file called main.cpp and put the following code in it. This will simply pull the pin high and low 15 times.

You’ll see a green squiggle line on the #include line, this happens because vscode doesn’t know where to find the header file. If you set the cursor on the line a lightbulb will appear, click on the lightbulb and choose Add include path to settings, it will then add the file c_cpp_properties.json to the .vscode folder. Point in the file to the include directory of  the fast gpio library downloaded earlier. Mine looks like this.

But you must replace the path to with the path where you placed it.

Automation

We programmers love automation because it enables us to do less 😀 luckily vscode allows us to do just that. Vscode has a feature that allows us to define tasks, we will define two tasks. One task for compiling our code and other for copying our executable to the Omega2.

Task 1

To create the first task we can use the shortcut CNTR + SHIFT + P and type task, select the entry Configure Task Runner. This creates a new file in the folder .vscode named tasks.json. Be sure to replace the paths with ones pointing to the location of the fast-gpio library on your PC.

By setting the property isBuildCommand to true it enables us to trigger this task with the shortcut CNTR + B.

Tip: When building the project with CNTR + B does not work after setting up the task, be sure you have configured the environment as shown in earlier in this post.

Task 2

The next task is enabling us to copy the executable to the Omega2. You can add the following task to the tasks array and of course replace the IP/username/password with your own.

To let this work we need to install sshpass in our ubuntu environment, we need this program so it can enter our password when asked. Use the following command to install it in our environment.

You can trigger the task by using the shortcut CNTR + P and type task copy. If everything is working, you can now use ssh to connect to the Omega2 and execute the application to let our LED flash.

Compiling Rust for the Omega2

After receiving my Onion Omega2 from Indiegogo perk, I really wanted to see what was possible with it. So this would be a great opportunity for me to learn Rust and see what it takes to get it running on the Omega2.

I found a good blog from Shane Logsdon explaining how to get it to work with MacOS. I thought I create a simple guide how to compile Rust for the Omega2 on Linux (or windows WSL)

The Onion OS on the Omega2 is a modified version of the LEDE project and the microcontroller used in the Omega2 is the MediaTek Ralink MIPS MT7688. So our goal is to cross-compile rust for the MIPS platform.

This guide continues from on a previous guide where I explain how to compile LEDE (on windows).

Installing Rust

To install and configure rust we need to tell it how to install it and what targets it should support.

The IDE

For the IDE I use visual studio code, which is freely available from here, the following blog shows you how to configure the IDE to run and debug rust. But instead of the RustyCode extension I use the Rust extension which is more actively maintained and installs the dependencies needed automatically.

Tip: If you are unable to debug after following every instruction make sure you have configured rust to use GCC instead of MSVC (MSVC is default). There is a stackoverflow answer here.

We are now going to configure in visual studio code a task that enables us to compile a Rust application, the task is going to use the WSL to compile in Linux with the GCC compiler from the LEDE project we created in the previous guide.

Use CTRL + SHIFT + P and type task, select Configure TaskRunner and then select Other. Replace the existing content with the configuration below, be sure to replace the path with your location.

From now on its possible to execute CTRL + P and type the following to create a build ready for upload to the Omega2.

Now you are able to compile from within windows through the Linux Subsystem for the Omega2.

Creating a rust project and compile

We are almost ready to compile our program to run on the Omega2, first we need to create a rust project. Execute the following command to create a hello_world project in rust.

Next up is to create a config file for rust so that rust knows which linker to use for out target. Creating a directory .cargo and placing a file named config

The configuration will contain the following, replace <user> with your user of course.

Make sure you are in the directory of the project and execute the following to compile the application.

Copy and run it on the Omega2

I use scp to copy it to the /root/ directory on the Omega2, of course replace <ipadres> with the one of your Omega2.

Then use SSH to connect to the omega and give our hello_world executable rights by using the following command

And this will print “Hello, world from rust!”

 

Compiling LEDE on Windows 10

After receiving my Onion Omega2 from my Indiegogo perk, I really wanted to see what was possible with it. I thought this would be a great opportunity for me to try to compile something and see what it takes to get it running on the Omega2. I always develop on windows and that is a challenge when trying to work with IOT.

Before we can compile anything for the Omega2 we need an environment where we can cross compile our sources. The Onion OS on the Omega2 is a modified version of the LEDE project and the microcontroller used in the Omega2 is the MediaTek Ralink MIPS MT7688. So our goal is to compile LEDE, that gives us as result a GCC compiler capable of compiling source to MIPS that we can run on the Omega2.

Windows On Linux (Beta)

In windows 10 pro version 1607 there is a feature called Windows Subsystem for Linux. The Linux subsystem enables native ELF binaries to run under windows and thus enabling us to compile using GCC without the need to have a virtual machine running. There is a good video from one of the architects giving a presentation at blackhat if you want to know more about the system.

As of writing I’m using Windows Insider Build of the Creators Update Build 15031. You can get this build by enabling the Windows Insider Program under Settings –> Update & security –> Windows Insider Program (can take a couple of hours before you are able to see the updates) or you can download the ISO and run it as an update, if you are not willing to wait a few hours.

Setting up the WSL environment

Before this feature is available you need to enable developer mode on windows 10. Which is found in Settings –> Update & security –> For developers. After enabling you are able to turn the feature on.

After you have restarted, we are going to execute the following command, this will be our gateway to the Linux Subsystem.

Windows asks a few question for you to answer, after you have answered those,  you see the bash environment we will be working in. We are almost ready to install the needed dependencies. Before we continue we first update our environment so we have the latest version of our environment.

Next up is editing the file ~/.bashrc and append a line to it so at start the ~/.profile is also loaded, the WSL doesn’t do that.

We also need to edit the ~/.profile file when left as it is will load the ~/.bashrc file and cause an infinite loop. To prevent that from happening we need to remove the following lines from the file ~/.profile.

Downloading source code of LEDE

We need the LEDE sources so we can build a compiler that emits MIPS code that will run on the Omega2. We will start with the download of the sources to your home directory, thanks to WereCatf for the source. Do not work on the windows drives in /mnt/[c-d]. Every mount under /mnt points to the windows mounts, these mounts work with the DriveFs System and has some deadlock issues for now. If that happens then the only way to get WSL working again is to restart windows.

Installing dependencies

Before we continue with compiling LEDE, we first need to install some dependencies. Use the following command to install the dependencies.

Configuring and compiling LEDE

We need to configure the LEDE project before we compile the toolchain. Set the following options.

  • Target System: MediaTek Ralink MIPS
  • Subtarget: MT7688 based boards
  • Target Profile: Onion Omega2 or Onion Omega2+

Use the following command to configure the options for LEDE.

Tip: If navigating with arrows don’t seem to work try using +- and use <TAB> for navigating the bottom menu.

After you have configured LEDE you are ready to compile, use the following command. Compiling LEDE can take more than an hour to complete.

Tip: If the compilation fails try to remove the j4 argument, this argument tell how many hardware threads to use for the compilation.

After the compilation completes, we have the following directory containing the tools needed to compile our sources for the Omega2.

That is all to it, now we can use the mipsel-openwrt-linux-gcc to compile c code or we can use mipsel-openwrt-linux-g++ to compile our c++ code.

Adjust our environment

Now if we edit our ~/.profile again and add some extra paths, then we can compile without having to reference the complete path to our compiler.

We now have a working environment where we can compile c and c++ code.