Start a C program when BeagleBone boots

I’ve been spending some time lately trying to turn the BeagleBone into a “single-serving” system for my prototypes. Most of these prototypes require running some program whenever the system gets power. Before you continue, I strongly recommend you read my previous BeagleBone posts, if you start feeling a bit lost.

So here I have a very simple circuit… 5 LEDs connected to 5 different pins (P8_3,P8_4,P8_5,P8_11,P8_12). I would like these LEDs to display a perform a simple pattern whenever the BeagleBone is turned ON. Something like the following video.

The code for this circuit is pretty straight forward and looks like this:

To compile and run this code, download my BeagleBone_IO library, save the above code as main.c and type the following commands:

gcc -c BeagleBone_gpio.c
gcc BeagleBone_gpio.o main.c -o main
./main

What is neat about my code, is that it is able to trap a signal whenever the user types CONTROL+C and ends the program normally… after performing some generic BeagleBone GPIO cleanup.

Anyway, I would like this program to run whenever my BeagleBone starts up. BeagleBone’s default OS is Angstrom Linux which uses systemd as the initialization scheduler. I am still learning about this, but according to the wikipedia entry and also to Kezhong’s Weblog, this daemon is meant to efficiently express services dependencies, by allowing more services to be launched in parallel at system startup while reducing the need to mess around with many scripts. I used to do this on ubuntu… and it was a mess.

Anyway, I would like to declare my LED blinking program as a service. So I need to execute the following steps:

Step #1: Create a script that will call the program that you wish you launch at boot time
This means we need to create a file in the /usr/bin/ directory with any name. For example, assuming that our compiled LED program is in /home/root/main we can create an executable simple script called myScript.sh with the following lines of code.

echo “#!/bin/bash” > /usr/bin/myScript.sh
echo “/home/root/main” >> /usr/bin/myScript.sh
chmod u+x /usr/bin/myScript.sh

Step #2: Create the service file
Create the file /lib/systemd/myScript.service . Actually your service name can be anything you want… not restrained to myScript.service.

nano /lib/systemd/myScript.service

Step #3: Write the appropriate service settings
Your /lib/systemd/myScript.service can be for example:

[Unit]
Description=Run the LED pattern script
After=syslog.target network.target

[Service]
Type=simple
ExecStart=/usr/bin/myScript.sh

[Install]
WantedBy=multi-user.target

Step #4: Make a symbolic link

cd /etc/systemd/system/
ln /lib/systemd/myScript.service myScript.service

Step #5: Make systemd take notice of it, activate the service immediately and enable the service to be started on boot-up

systemctl daemon-reload
systemctl start myScript.service
systemctl enable myScript.service

After executing all commands on step 5, the LED program should immediately start. Try switching the BeagleBone power OFF & ON… and you will see the LED program.

How to terminate the script that is constantly running in the background?
If everything went okay, your script in constantly running in the background. To terminate it, you need to kill it. Use the top command and find out the process id (pid) of your looping program. As shown on the screenshot, my main pid is 13.



Listing all jobs

The following command will take care of terminating the job.

kill 113

How disable the script from starting up at the boot time?
Just type:

systemctl disable myScript.service

Thanks to Piranha at the official BeagleBoard forum for guidance.

12 Comments

  1. I’m just barely getting into systemd and found your post useful, but I wonder, why do you need to specify “After=syslog.target network.target” in the service? The C program doesn’t appear to need either syslog nor networking. The program could start before (or actually in parallel) to those services for a faster bootup.

    • I agree. This was just a very general example. For customized embedded solutions, you could potentially remove these services all together.

  2. Great work. I’ll have to spend some time playing with this. Just a word of warning (perhaps) – Those LEDs are probably drawing 20-30mA but by my reading, the limit stated in the datasheet for one of the GPIOs is 4mA. Maybe I’m wrong!

    • I don’t remember which resistor I used, but I think it was a 1K. Won’t the current through the LED be limited by the amount of current the GPIOs can deliver anyway? So even if I am drawing more current than provided, the LED will simply not be as bright. I wonder, since I am not doing any input, what is the harm of not limiting the current flow?

  3. Hello, did you have tryed a DS18B20 Temp-sensor by using the GPIO lib? i have tryed and connected on P8_15, but it does not works.would you pls help me?

  4. Step #4 is slightly wrong. Should have been
    ln /lib/systemd/system/myScript.service myScript.service

  5. I have this situation, but my C program should have a interchange with serial console by keyboard. How can I do that? Because as you as explain that services run in background, and I want run over console.

    • Not quite understand what you want to accomplish. Could you give me some more details?

  6. Thanks a lot!!!

  7. Hi Nuno. Thanks for sharing your Beaglebone_IO library. It is very useful. I have seen that in the last version only P9_12 can be an input port, I have comlpeted your code so any of the inputs can be used. I can send it to you if you want.

  8. I am not seeing just where you are calling out your C program. You never (I think) reeferd to it by its file name, but you did state where it would be located at.
    “assuming that our compiled LED program is in /home/root/main ”

    What is your compiled c program name for this example, and where do you place that file name in the other scrips?

    • I compiled it with this command “gcc BeagleBone_gpio.o main.c -o main” and it was stored in /home/root/main.