Chapter 5: Practical BeagleBone Programming

Chapter 5: Practical BeagleBone Programming

/Chapter 5: Practical BeagleBone Programming
Chapter 5: Practical BeagleBone Programming2019-01-11T16:13:53+00:00


This is the chapter web page to support the content in Chapter 5 of the book: Exploring BeagleBone – Tools and Techniques for Building with Embedded Linux. The summary introduction to the chapter is as follows:

This chapter describes several different programming options for the BeagleBone, including scripted and compiled languages. An LED flashing example is provided in all of the languages so that you can investigate each language’s structure and syntax. The advantages and disadvantages of each language are discussed along with example uses. The chapter then focuses on the C/C++ programming languages, describing the principles of these languages, and why object‐oriented programming (OOP) is appropriate and necessary for the development of scalable embedded systems applications. Finally, the chapter details how you can interface directly to the Linux kernel using the GNU C Library. A single chapter can only touch the surface of programming languages, but this one is focused on programming the BeagleBone. I have made my module notes about OOP available at ee402.eeng.dcu.ie to support this chapter.

Learning Outcomes

After completing this chapter, you should be able to:

  • Describe the multitude of issues that would impact on your choice of programming languages to use in building applications for the BBB.
  • Write basic scripting language program code on the BBB that interfaces to the on‐board LEDs.
  • Compare and contrast scripting, hybrid, and compiled programming languages, and their application to the BBB.
  • Write C code examples that interface to the BBB’s on‐board LEDs.
  • Wrap C code in C++ classes to provide greater program structure.
  • Write advanced C/C++ code that is capable of interfacing to Linux operating system commands.

Source Code Examples

As described in the book, here are source code examples for flashing a sysfs-mapped user LED using different languages with markup highlighting. Essentially, each code example is performing the same task. The code appears to become more complex as you move across the tabs (moving from left to right), but the functionality that is available in the code examples is also enhanced (e.g., the OOP examples are applied to all LEDs rather than a single LED). Note: these code examples, and all code on this website, are pulled live from the exploringBB GitHub repository.

Additional Materials

A Further Note on Setting the BBB CPU Frequency

There is a short section on “Setting the BBB CPU Frequency” on Page 153 of the book. This note provides some additional information, and was prompted by reader questions. As described, the ondemand governor sets the CPU frequency depending on the current demand. If the CPU frequency is currently 300MHz and the average CPU usage between governor samplings is above the threshold (called the ‘up_threshold’) then the CPU frequency will be automatically increased. The ‘up_threshold’ can actually be adjusted using sysfs as follows:

If you decide that you would like to change the default operation of the BeagleBone you can do so by editing the file /etc/init.d/cpufrequtils and changing the entry GOVERNOR="ondemand" to a different governor, such as conservative, userspace, powersave or performance. For example, you could set it to high-performance mode using the settings:

See https://www.kernel.org/doc/Documentation/cpu-freq/governors.txt for more information on the governors.

Accessing Environment Variables in a C/C++ Program

It can be useful to access environment variables from within your C/C++ programs — for example, you could determine the user’s home directory location, the shell type, or the user’s path settings. To achieve this there are two different ways that are presented in the code example, Listing 5.A1 below and in /chp05/extras/environment/environment.cpp:   Listing 5.A1: A C++ example to access the available environment variables

When this is built and then executed on the BBB it will result in the following output:

System Uptime by Reading /proc/uptime

Here is an example to use /proc to read a system state, which is the system up-time in this example. This can be performed from other languages including sandboxed languages, such as Java. However, as discussed in the book, care must be taken in reading /proc entries as they can change their state as you are reading them (i.e., reads may not be atomic).

Listing 5.A2: An example to determine the system uptime using /proc entries

You can execute this example as follows and it will give the output (yes, really five days!) :

This example works by parsing the /proc/uptime entry. You can view this directly, where the first value is the uptime in seconds. The second is the idle time in seconds.

You could use a similar framework to parse other /proc file entries, such as:

The /proc file system provides useful information about the system, and using it you can even change configuration settings. For example, while logged in as root, you can change the IP forwarding state:

Just remember that you may have difficulty with the non-atomic nature of these file entries — it is much safer to use the system call framework that is described on pages 195-197.

Using a System Call to use the chmod command

Towards the end of the chapter, in the section on “GLIBC and Syscall” there is a reference to a source code example (/chp05/syscall/callchmod.cpp). The example uses the syscall() function to set the permissions of a file called “test.txt” in the repository directory to be rwxrwxrwx. This could also be performed using the chmod() function, which is defined in sys/stat.h. Type man 2 chmod for more information.

Listing 5.A3: A Linux example that uses syscall() to change file access permissions

You can reset the permissions of the test.txt file by typing chmod 644 test.txt. So, for example:

Tracing System Calls

One command that is very useful in helping you to understand what system calls your application is performing is the strace command. You can execute your application using the strace command, which then provides a full trace of the system commands and signals that your application performs. For example, we can install strace on the BBB and then test it on a simple “hello world” C program as follows:

Each command is shown in the form of a function call, where the return value from each function call is displayed on the right-hand side of the equals symbol. For example, towards the bottom of this output you can see the line: write(1, “Hello world!”, 12Hello world!) = 12 which writes to a file descriptor and results in the output on the Linux terminal. You can use man 2 write to get further information about this system call:

The first argument is the file descriptor, which refers to a file. It is 1 in this case, which refers to the standard output, stdout (0 is stdin, and 2 is stderr). The second argument is the buffer pointer to the string data. The third argument is the number of bytes to write to the file that is described by the file descriptor. In this case the value will be read as 12. The return value of 12 above for ssize_t indicates that 12 bytes were successfully written to the standard output (stdout).  A value of zero would indicate that nothing was written, and a value of -1 would indicate that there was an error.

Clearly, the strace command is a valuable tool in understanding what is happening “under the hood” on Linux systems when you develop programs that interact with the operating system.

Installing the Java Runtime Environment (JRE) on the BBB

The Java Embedded Runtime Environment (virtual machine) is not available on the BBB by default; therefore, several steps are involved in installing the official Oracle Java Standard Edition (SE) Runtime Environment (JRE):

Open a browser and go to java.oracle.com. Find the link for Products ⇒ Java Embedded. Choose Oracle Java SE Embedded (Java SE, not Java ME). Choose a version for ARM, Linux. Headless means that you do not intend on building graphical user interface (GUI) applications. The JRE version 8 allows you to decide on the profile after it is installed. You just need to choose a version with hard floating-point numbers. On the BBB Debian image for the BBB, the version “ARMv7 Linux VFP, HardFP ABI Little Endian” will work correctly. Accept the license agreement and download the .gz Transfer this file to your BBB into the root account home (e.g., using psftp from Chapter 2). Follow the next steps on the BBB, where you should change the filenames according to your filenames.

Next, you need to add two environment variables so that the JRE can be found in your PATH and so that the JRE will be able to find the location of its installation files, JAVA_HOME, which contains the runtime libraries:

Oracle Java 8 embedded has an interesting feature in that you can recreate the JRE to be customized to your application using one of four profiles: compact1, which is the smallest JRE, is headless; compact2, which has debug support, JDBC, and RMI support; compact3, which has JNDI and JMX support; and the full SE API, which has headful support (AWT/Swing). This enables you to reduce the overhead of Java on your BBB to the minimum possible for your application. For example, with the environment variables set, you can do the following (this takes a few minutes on the BBB):

The JRE is now set up on the BBB in the directory /usr/java/jre. Unfortunately, the environment variables will be lost on a reboot. To set these settings permanently, add the lines:

to the user’s .profile file (a file beginning with a . indicates a hidden file) in the user’s home directory using nano, for example:

Please note that the code example below was compiled on a desktop computer and then transferred to the BBB as a .class file.

Installing a Java Compiler on a Linux Desktop Machine

You can download the JDK using a web browser from within Linux. If you do not have a web browser, you can install the open-source Chromium browser under Debian as follows:

Go to oracle.java.com and select Downloads⇒ Java for Developers ⇒ Java Platform JDK 8. Accept the license agreement and download the Linux x64 version jdk-8-linux-x64.tar.gz:

Set the Java environment variables for the desktop as before: