In the previous lesson from this guide, you have learned the basics of how to build and customize an Embedded Linux image with the Yocto Project/OpenEmbedded, by adding a simple hello-world application to one of Toradex's Reference Images for Yocto Project.
In this lesson, you will learn how to generate and use a custom standard SDK for cross-development. You will:
- Build a standard SDK with the Yocto Project/OpenEmbedded.
- Install and setup the SDK on your PC.
- Configure the Eclipse IDE for cross-compilation and debugging on the target device.
Keep in mind that this is an introductory tutorial and after you finish it we recommend you to refer to the Yocto Project Documentation, especially the section Yocto Project Application Development and the Extensible Software Development Kit (eSDK).
Typographic Conventions
Throughout the Toradex documentation, the following typographic conventions are used:
$ (dollar sign) Command in the host computer (e.g. your PC)
$ Command in your PC
$$ (double dollar sign) Command in a container in the host computer (e.g. your PC)
$$ Command inside a container in your PC
# (hashtag) Command in the target device/board (e.g. Linux terminal)
# Command in the target board, e.g. Colibri iMX6
## (double hashtag) Command inside a container in the target device (Torizon)
## Command inside a container in Torizon
> (greater-than sign) Command in the bootloader (e.g. U-Boot console)
> Command in the Bootloader
No symbol: Command output
$ Command waiting for output
Output
Tip: the conventions were introduced with Torizon. You may find old documentation that does not comply with it.
For this Quickstart Guide:
For this lesson:
Setup the Yocto Project/OpenEmbedded development environment as described in the previous lesson, if you haven't already done so:
Build an SDK:
For instance, if your custom image is named custom-multimedia-hello-image.bb
:
$ bitbake custom-multimedia-hello-image -c populate_sdk
Install the SDK:
Build the Hello World from the previous lesson using the command-line. First, go to the directory where the C source-code resides:
$ cd <path to your Yocto Project build>/layers/meta-customer/recipes-customer/hello-world/hello-world
Then build as explained below:
From the Linux terminal, find the board IP:
Copy the binary to the board, under /home/root
, using scp:
Execute the binary on the board to confirm that it has been successfully built and deployed:
# /home/root/hello
Install the latest Eclipse on your PC. There may be alternative methods, such as downloading from the Eclipse website, or installing a community version from using either your distro package manager or a Snap.
If you download for the official Eclipse website, an installer gives you the option to install the Eclipse IDE for C/C++ Developers and the Eclipse IDE for Embedded C/C++ Developers:
-
Eclipse Installer
In this guide we don't compare the different setups, you must do it by yourself and choose the one that is most appropriate for you.
Note: the Eclipse IDE for Embedded C/C++ Developers seems to come with most of the required plugins already installed.
Note: there once was an Eclipse Yocto plugin. It has been removed from the Yocto Project since release 2.7.
On the terminal with the exported SDK environment, write down the name of the cross GDB. You will need it when configuring Eclipse in the next steps:
$ echo $GDB
aarch64-tdx-linux-gdb
In the example above it is aarch64-tdx-linux-gdb
.
If you have opened Eclipse after installing it, close it.
Warning: you must start Eclipse from the command-line, from the same terminal where you have sourced the SDK environment.
From the same terminal where you have sourced the Yocto Project SDK environment in the previous steps, open Eclipse from the command-line. This will allow you to use most of the environment variables exported by the SDK in the Eclipse configuration:
$ cd <path where Eclipse is installed>
$ ./eclipse
Configure a new project:
In summary, you will:
- Create a new empty project
- Configure the Cross GCC compiler
Copy the hello world source code created in the previous lesson into the project directory and refresh the project configuration.
Build the project. You can use the shortcut Ctrl + B
, select Project
--> Build All
or right-click the project and click Build Project
.
Create a debug configuration for your project:
You will have to adapt the following steps from the instructions above:
- You don't need to have the Remote System Explorer configured.
- In the
Main
tab of the C/C++ Remote Application
debug configuration:
- Leave the fields
Project
and C/C++ Application
with the default values.
- Create a new
Connection
, selecting an SSH
connection.
- As
Host
, use the previously found board IP
- The
User
is root
- You must select
Password based authentication
and leave an empty password.
- On the
Remote Absolute File Path for C/C++ Applications
, you can click the Browse
button and then the Ok
button, leaving the default value, which will look like /var/rootdirs/home/root/hello-world
depending on your project/binary name.
- In the
Debugger
tab of the C/C++ Remote Application
debug configuration:
- On
GDB Debugger
you can use name found on previous steps when you executed echo ${GDB}
. In the example it was aarch64-tdx-linux-gdb
.
- Leave the
GDB command file
empty, unless of course, you want to use a file.
Right-click the printf("Hello world!\n");
line number and select Toggle Breakpoint
- or just double-click the line number. A blue dot will indicate that you have successfully added the breakpoint:
-
Add a Breakpoint
Click the Debug
button and the debug will start. Keep in mind that Eclipse will switch to the Debug
perspective, but you may switch to other perspectives anytime, including the C/C++
perspective.
If Eclipse throws the error Algorithm negotiation failed
, it is most likely because you have skipped a step on the previous lesson from this guide. See How to setup environment for Embedded Linux application development - Eclipse IDE to learn how to fix it.
Development using an IDE is handy and the Yocto Project provides an SDK that makes it easy to use it with the Eclipse IDE. Keep a few things in mind:
- You have generated an SDK that includes the development packages (headers and shared libraries) for the packages included by default in the Reference Multimedia Image. Your application will possibly require other packages that you will have to include in your custom image and then rebuild your custom SDK.
- As you might have noticed as you followed the article, the compiler options are setup in the SDK environment file that you must export before opening Eclipse. It is up to you to decide the best options and flags for your project.
- Once the application development is done, you must integrate your final changes in your Yocto Project recipe. While you can begin with what was presented in the previous lesson, it may involve writing a more complex recipe and you will possibly have to either read the Yocto Project documentation or search for similar existing recipes as a starting point.
Can I use other programming languages?
Yes, you can. For instance, Python, Java, and Node.js are languages that may be of interest:
In the end, remember that the target is an ARM-based system that runs Linux. If there is a compiler or interpreter for the desired programming language, you may give it a try.
When it comes to Yocto, searching on layers.openembedded.org is a good idea.
How to know what environment variables are set by the SDK?
You can manually inspect (and even customize) the SDK setup script using your favorite text editor:
gedit /usr/local/oecore-x86_64/environment-setup-armv7at2hf-neon-angstrom-linux-gnueabi
After the script is sourced, you can verify that the variables are set using the printenv command:
printenv
How can I set or modify compiler flags?
You can use the default flags provided by the setup script, e.g.:
${CC} ${CFLAGS} -Wall hello-world.c -o hello-world
Or modify the default flags, e.g.:
export CFLAGS=" -Wall -O3"
${CC} ${CFLAGS} hello-world.c -o hello-world
And even modify the setup script, e.g.:
/usr/local/oecore-x86_64/environment-setup-armv7at2hf-neon-angstrom-linux-gnueabi
...
export CFLAGS=" -Wall -O3"
...
For projects with specific flags, you may want to set the parameters directly in the Eclipse IDE instead of using the variables exported by the setup script. For that, please see the question How can I directly set the compiler flags in the Eclipse IDE from this FAQ.
Just keep in mind that the best scenario is you have the project configuration included in a source control system, as Git.
How can I directly set the compiler flags in the Eclipse IDE?
Instead of using an exported variable, you can directly set the options in the Eclipse IDE. E.g. instead of setting the Cross GCC Compiler command to:
${CC}
You could set it to e.g.:
aarch64-tdx-linux-gcc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=$SDKTARGETSYSROOT
aarch64-tdx-linux-gcc -O3 -feliminate-unused-debug-types --sysroot=/usr/local/tdx-xwayland/5.2.0/sysroots/aarch64-tdx-linux
The same logic applies to other settings, such as C flags, C++ compiler, among others.
Which version of the Eclipse IDE should I use?
This tutorial was tested for the Eclipse 2021-03 release, using the Eclipse IDE for Embedded C/C++ developers. You can try any version you want, although steps may vary from version to version. Consult the Eclipse website for information about new releases and features.
Debugging behavior is erroneous
Many reasons may lead to an erroneous behavior. You can browse our community for similar issues and, if none found, ask a specific question.
A common issue observed among customers is:
In the previous lesson, the CFLAGS were set using the variable CFLAGS exported by the SDK. Its default value is:
-O2 -pipe -g -feliminate-unused-debug-types
This means that the application was being shipped with debug symbols and code optimization. You may try to reduce the optimization level to -O0 or -Og, e.g.:
-Og -pipe -g -feliminate-unused-debug-types
or
-O0 -pipe -g -feliminate-unused-debug-types