Sunday, November 6, 2016

Cross Compile for Raspberry PI on Windows 10

Cross Compiling for Raspberry PI or other ARM based devices capable of running Linux, on Windows 10 using the "Window subsystem for Linux" (aka Bash on Windows) is now as simple as cross compiling on native Linux.

To learn more about the Windows subsystem for Linux and how to activate it you can follow the instructions here.

Once you have completed that you can follow these steps to install the toolchain required to cross compile for the Raspberry PI.

Step 1 - Make sure your environment is up to date
$ sudo apt-get update
$ sudo apt-get upgrade 
Step 2 - Install the development tools
$ sudo apt-get install -y build-essential gcc-arm-linux-gnueabi g++-arm-linux-gnueabi 
For the very basics, that is it...

Let's try build some code and get it to run on the Raspberry PI

Step 3 - Create a source directory

In the bash shell you can create a "source" folder in the user directory and switch to the directory by issuing the following commands
$ mkdir ~/source
$ cd ~/source
The first command will create a "source" directory in the current users home directory, the second will change the current directory to the newly created "source" directory.

Step 4 - Write some code

First we will launch the nano text editor, in the Windows bash shell, by issuing the following
$ nano test.cpp 
This command will open the nano editor and set the file name to "test.cpp". Enter the following code in the editor window
#include <iostream>
int main() 
{
 
   std::cout << "Hello from your Raspberry PI!" << std::endl;
 
   return 0; 

Press "Ctrl-X" followed by "y" followed by "enter". 

Now you should be back at the command prompt in the source directory we created earlier. Issuing the "ls" command should show that we have a new file called "test.cpp". 

Step 5 - Compiling using the cross compiler

Next, we can compile the code for the Raspberry PI using the following command  
$ arm-linux-gnueabi-g++ test.cpp -o test 
This will start the compiler, which will compile the test.cpp file and if you have entered the code correctly, create an executable binary file called "test". If you have any errors you can go back to step 4 above and use the same commands to edit the file and fix any errors you might have encountered. 

Assuming you had no errors, you should now have a binary file on your machine called "test". This is the executable that is ready to run on an ARM based device running Linux, like your Raspberry PI. We can confirm that it is indeed not compatible with the x64 architecture of your Windows machine by trying to execute the code as follow. 
$ ./test 
The application should fail to execute and give a messages along the lines of 


bash: ./test: cannot execute binary file: Exec format error. 

This is because the binary is not in the correct format for the platform you are trying to execute it on. We need to copy the binary over to your Raspberry PI and try execute the binary there.

Step 6 - Copy the binary to the Raspberry PI

I am going to assume that you already have your Raspberry PI on the network and have identified the IP address, if not you can use Google or Bing to go get to that point.

In my case, my Raspberry PI is on the network and has been assigned an IP address of 192.168.0.50.

  Note:You need to replace the IP addresses below with the IP address of  your Raspberry PI.

To copy the binary from your windows machine to the Raspberry PI we can use secure copy (scp), this is a Unix/Linux command to securely copy files between two machines using a secure shell. The Windows subsystem for Linux makes these commands available to you "natively" from within the bash shell.

Enter the command below to copy the file from the Windows machine to your Raspberry PI (remember to change the IP address to the IP of your Raspberry PI)
$ scp test pi@192.168.0.50:/home/pi 
If this is the first time you are setting up a secure connection to the Raspberry PI from bash, either using scp or ssh you will be prompted to confirm that you trust the target machine, you can enter "yes" to have the host signature entered into your local known hosts file.

Note: If you took too long to confirm the host, the underlying connection might have been broken, in that case you can just reissue the scp command above.

Next you will need to enter the password, the default password for the "pi" user is "raspberry" which you can enter in response to the password prompt. When the command completes without errors, the binary should be copied over to your Raspberry. Let's go check...

Step 7 - Executing the binary on the Raspberry PI

From within the bash shell on your Windows machine, you can now ssh to to the Raspberry PI. If you prefer you could use Putty, but since we have the capability to use the Windows bash shell to do this I am going to stick with that. The next command will open a ssh session to your Raspberry PI, again, remember to use the IP address for your Raspberry and not the IP address in the example (unless of course your IP matches the on in the example :) )
$ ssh pi@192.168.0.50
Next, you will be prompted for the password for the user "pi", enter "raspberry" and you should now have an interactive secure session with your Raspberry PI. You can identify that you are interacting with the Raspberry and not the local shell by looking at the prompt, it should be a bright green prompt with the following text.
pi@raspberrypi:~ $ 
If you see the above, you know you are now remotely interacting with the Raspberry. Entering "ls" command should list the "test" file, also in bright green, that you copied from the Windows machine.

Lets try executing the binary and see if we have more luck than we did when executing it earlier on the Windows machine.

At the prompt enter "./test", you should then see the following

pi@raspberrypi:~ $ ./test
Hello from your Raspberry PI! 

If you see that then it worked! You compiled a source file on your Windows machine, using the ARM tools to target an ARM based Linux distribution, copied the file to the target device and executed it. How awesome is that???

There is still much more to this, but this should get you started cross compiling on Windows for your Raspberry PI. Best of all, this will also work for other ARM based devices capable of running Linux, like the BeagleBone Black for example.

For a more complete experience, take a look at:

VisualGDB - Use Visual Studio to target a range of embedded devices and Linux devices
Visual C++ for Linux development - Use Visual Studio to compile and deploy to ARM based Linux devices