Develop your Embedded Linux application from the comfort of your desktop PC

So, there is a new guy at the office. He has an electronics background, but he is not very familiar with Embedded Linux applications. He is developing a module to communicate a Raspberry Pi via i2c with another chip.

For context, the Raspberry Pi is running Raspbian Lite (so no GUI).

He connected his laptop to the Raspberry Pi’s serial interface using one of those cheap FTDI dongles. In his laptop he opened the Raspberry Pi terminal using the typical screen tty baudrate command.

So far, so good. This is a super convenient way of accessing an Embedded Linux device.

The problem is that he was writing the code of his application in this terminal using nano :rofl:.

Also, if you are familiar with the screen program, you would know that it has some problems with certain inputs. Every time he scrolled using his mouse wheel, the terminal filled with garbage :rofl:.

After a couple of minutes of friendly mockery, I showed him how to code his application in his laptop using Netbeans but compiling and running directly in the Raspberry Pi.

I decided to post this simple “tutorial” in case someone finds it useful. I made it for a Raspberry Pi, but it should work with any Embedded Linux device (Or anything running Linux for that matter).

There are four prerequisites:

  1. You should be able to SSH into your Embedded Linux device.
  2. Your application should be in C or C++ (if your application is for an embedded system, it should be in C or C++).
  3. Your Embedded Linux device should have the necessary binaries and libraries to compile your application.
  4. You need Netbeans (It should be possible with another IDE, but Netbeans is the one I am familiar with).

The first step is to setup your SSH. So connect your Embedded Linux device to your local network and assign a static IP (outside the IP address range that your DHCP server assigns).

Then, from your PC, generate your SSH keys (in case you do not have them already). Open a terminal and type:

ssh-keygen

This command generates two files in $HOME/.ssh/: id_rsa (private key) and id_rsa.pub (public key). The private key should never leave your PC and should never be shared. The public key is meant to be shared and it should be put in your devices and servers to authenticate your login from your PC. Check this document from SSH.com for a detailed description of SSH key pairs.

If you open the id_rsa.pub file with a text editor, you should see something like this:

ssh-rsa afddklfheuldfafhrjdlshf2342345w3452== my_key

id_rsa.pub is basically a CSV file separated by whitespaces of just one record. The first column is the type of key, the second column is the key itself and the third column is a label used to easily identify the key.

The id_rsa file should not be readable by any other user in your PC. SSH will not allow the use of the key if its permissions are “too open”. So restrict them. In the terminal type:

chmod 400 id_rsa

Then, logon into your Embedded Linux device and create the .ssh/authorized_keys file in the main user’s home directory (/home/pi/ in the Raspberry Pi). The purpose of this file is to contain the public keys of those users that will be able to login to this device. So copy the contents of your id_rsa.pub key into the .ssh/authorized_keys file.

If properly done, you should be able to login into your Embedded Linux device from your PC using SSH without the need of entering the device user’s password.

The next step is to setup your project in Netbeans. So create a directory for your project somewhere in your PC (or clone the project repository in case you are using git or something similar).

Assuming you are starting from scratch, inside this directory, create an empty file with the name Makefile. Your project’s directory should look like this:

Open Netbeans and create a new project. This project should be C/C++ Project with Existing Sources:

Select the directory that you created before as the source directory and let Netbeans handle the configuration:

Click Finish. Netbeans will setup the project and try to “Clean and build”. An error will prompt, because the Makefile is empty and there are no source files, but is ok, you will add them later.

Next, in Netbeans, go to the Services section and select C/C++ Build Hosts. By default you should see the localhost host (your PC).

Screenshot from 2020-07-29 23-37-03

Right click on C/C++ Build Hosts and select Add new host. Enter your Embedded Linux device’s IP (10.255.255.20 in my case) and click Next.

Enter your Embedded Linux device’s username (pi in the Raspberry Pi), select your private key for the SSH authentication and click Next.

On success, a summary dialog will be shown. Netbeans can access the Embedded Linux device files using samba or sftp. Choose sftp, it just works better and you do not need to install anything else in your device.

Now that your Embedded Linux device is a “Build Host”, go to your project properties. In the Build section, select your Embedded Linux device as the Build Host. Click Apply and Ok.

And that’s it. Now just add your source files and edit your Makefile.

Just for reference, I created this main.c file:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) 
{
    printf("Hello from Linux running in a 2 dollars chip");
    return (EXIT_SUCCESS);
}

And this super simple Makefile:

OBJS=main.o
CC=gcc
DEBUG=-ggdb
CFLAGS=-Wall -c $(DEBUG) 
LFLAGS=-Wall $(DEBUG)
BIN=example
SRCDIR=./src

$(BIN) : $(OBJS)	
	$(CC) $(OBJS) $(LFLAGS) -o $(BIN)

$(OBJS):
	$(CC) $(CFLAGS) -I$(SRCDIR) $(SRCDIR)/*.c

clean:
	rm -f *.o *~ $(SRCDIR)/*~ $(BIN)

Click Clean and Build and if everything is ok, Netbeans will show something similar to this:

Netbeans, automatically copies the project files to the Embedded Linux device and compiles the project in the Embedded Linux device. It is awesome!

Click Run and you will see something like this:

That output comes from the Raspberry Pi.

If you SSH into your Embedded Linux device and run an ls -al in the user’s home directory (/home/pi for the Raspberry Pi), you will see a .netbeans directory:

Inside that .netbeans directory are your project files and executable.

8 Likes

Good write up. May be this can be stickyed somewhere.

1 Like

Ayeeee, sounds scary.

Do they have any programming experience, or Linux experience? Are they expected to be writing drivers?

1 Like

He is an intern. He is still in school.

He has some experience with microcontrollers and he knows how i2c works, he is just not familiar with Linux.

He will learn a lot with this assignment. Today he made a led blink and he was quite happy.

We, all, have been him at some point.

1 Like

Ah cool! Looks like a steep learning curve - for an intern I like it.

The term “Embedded Linux” drew my attention, … “huh is this a new distro?” I thought.

Most folks would just connect a keyboard, mouse and monitor to a pi, and code on it directly, or would cross compile. This is an interesting tool chain, easy to get started in.

If they’re new to Linux it’d be useful to grab these two in addition to all the usual programming courses for your language of choice.

  • “The Unix Internals” - it’s old but it’s fundamentals.
  • “The Linux Programming Interface” - useful modern reference (e.g. what’s a pty? session vs process group, epoll …)

There was also a thing about Linux Driver Development, not sure if that’s like a perpetually updated book or how that works it was a good read when I was kid 15 years ago writing my first driver for some data logging equipment used for some physics and geology experiments.

Also, if you can’t do Linux on your device (ram/flash/power), but want something comfortable to program in, FreeRTOS is very nice, it’s got tasklets instead of processes - it’s a lot like kernel programming in some ways - way better than bare metal and having to figure out your own concurrency and timer interrupt stack handling and all that stuff.

2 Likes

The Linux Programming Interface, the one by Kerrisk, is an excellent resource. Unfortunately I lend my copy a couple of years ago and it never came back.

It is easier to just connect a monitor and a keyboard to the Raspberry Pi, but for our use case, I try to threat this devices as “headless” and use the serial interface or SSH to access them.

The Raspberry Pi may have a GUI, but in future projects, we may use another device that does not.

We develop custom boards depending on the project, so our production volume is really low and we do not have devices in stock.

Also, for “in site” diagnosis and problem solving is easier to access the device through a serial connection.

I totally agree, that it is a really sharp learning curve (/dev/mem is a scary beast). But, for this type of development, you need a balance between a software developer and someone with digital electronics background.

Most software developers do not have any digital electronics background, and most of them may not even know what a serial interface is.

On the other hand, someone with digital electronics background surely knows C and can make something like reading a sensor relatively fast. But when you ask: “Ok, now send that sensor value to a server via an HTTPS request presented in JSON”, that is when the electronics guy struggles.

The steep learning curve will be there at the beginning. For the software developer, will be the electronics and low level communication protocols; And for the electronics guy will be Linux and the OSI application and presentation protocols.

In the end, I think this assignment will be very useful for him. He will become familiar with new concepts and he will know where and how to search for references and documentation.

2 Likes

I have been trying to get my hands dirty with FreeRTOS but I could not find the time. I even purchased one of those Launchpad development boards from Texas Instruments. Hopefully in the next few weeks I can start making some tests.

1 Like

I’ve had experiences with electronics guys not knowing what a ring buffer is / or how to use a conditional variable to build a queue (different people). Somehow these gaps happen.

You can also use your $2/$3 ESP32 boards. YouTube’s full of tutorials on “how to use the second core” with a bunch of mindblown people creating a new tasklet.

There’s also platformio.org (https://github.com/platformio) It’s useful if you often mix and match controllers and peripherals… or if you have multiple projects and just want to make reusable libraries; it makes managing the toolchain for each of these platforms easier. It’s not useful for your 8051 or similar super tiny uC, or if you want to run Linux on your device, but it’s great for anything in between.

2 Likes