The Molcajete project: where Arduino meets FreeRTOS

It’s ready the bundle in which you can program your Arduino apps using the FreeRTOS kernel. You can download it from

The Molcajete project

The Molcajete project by Xavier R

OVERVIEW

The aim of this project is to program Arduino apps using the world’s most downloaded real time kernel, FreeRTOS, in a terminal through Arduino-mk makefile.

In fact, this project is kind of a FreeRTOS port for the ATMEGA328 chip so that it can be used in the Arduino platform. The client of this project MUST provide the several hooks that FreeRTOS needs to run. It’s assumed that the client has knowledged of what FreeRTOS is about, and in general, what a kernel is, and why and how it’s used.

Two examples are provided: The classical one that implements two tasks in a dynamic fashion in order to test the system. The other example does the same but with static tasks.

This port uses the standard malloc and free implementations for AVR when using dynamic tasks. For reliable embedded systems it’s recommended not to abuse in the creation and deletion of tasks in the heap. If the client chooses this way it’s recommended to create all tasks at once at the global space and to avoid any task deletion. Even better if static tasks are used as they are already enabled in the kernel (since FreeRTOS 9.0).

The system tick is fixed at 1 millisecond after the AVR’s T0 timer. Tickless and/or low-power modes have not been tested yet.

SKETCHES

I don’t provide any sketches. Everything I do I do it in a terminal. But you can contribute with some!

OPERATING SYSTEM

For now this project only works on 64 bits Linux boxes. Later I’ll try to create a patch file so you can apply it to your already Arduino installation.

CONFIGURATION

Two files need to be edited in order to configure each project:

  1. Makefile. There is one makefile per project. In this the client configures stuff related to Arduino.
  2. FreeRTOSconfig.h. There is one FreeRTOS configuration file for ALL projects. In this the client configures stuff related to FreeRTOS. Having one global FreeRTOS configuration file is a bad idea. However, due to my lack of knowledge about paths and makefiles, this undesired behavior is all I have by now. Hope to fix it ASAP.

STACK SIZE

The stack size assigned to each task depends on many factors. FreeRTOS includes some schemes so that the client can choose the number that fits the most each project’s tasks. Such a number can also be chosen by heart, provided a good understanding of the task’s job.

As mentioned earlier, the RAM should be asked for and given globally at the very start of the application. This is also true for static tasks. If dynamic tasks are used, then it’s recommended not to delete them; the heap might fragment and such situation isn’t good for reliable embedded systems.

PRIORITY LEVELS

Priority levels in FreeRTOS are implemented using a linked list. The more the priority levels, the more RAM it uses and more time is spent looking for the next task. Some projects use one priority level per task, while others share a priority level among several tasks. It depends totally on the project requirements.

I’ve written an article on how three priority levels fulfill the needs for a small systems using event-driven programming. The article can be reached at: https://bit.ly/2qoE2Kn

HOOKS

Some hook functions might be required for each project. The client MUST provide them. The number of hook functions, if some, depends on the FreeRTOS configuration.

MODIFIED FILES

I modified some files so that FreeRTOS can work along Arduino. If you are interested in study them, these are the files:

  • FreeRTOS side
    • port.c
  • Arduino side
    • wiring.c

Side effects

I’ve modified a little bit the optiboot bootloader, and this change is included in the bundle. If you don’t use it, then you have nothing to worry about. If you’re planning to burn the bootloader into your chips, you might want to check my modifications.

LICENSES

Each entity in this project might have its own licensing scheme. For details visit:

CONTRIBUTIONS

All contributions are welcome: examples, sketches, testing in boards other than UNO or Leonardo, testing in OSs other than Linux, etc. I’m NOT asking for money. I’ve done this little contribution due to my love for embedded systems and my beliefs on the open source and open hardware movement.

You can reach me at fjrg76 at hotmail dot com and ingenieria at fjrg76 dot com.

Building a solution from the command line

The Arduino’s IDE is just awful. Period. To write sketches is awful as well. Scketches make me sick. Hopefully we can build our solutions from the command line, directly from the main() function, even using our favorite code editor, VIM for me. A more-in-depth tutorial on this topic can be found here.

Installing Arduino

We need to download the latest Arduino‘s release, as for this writing, 1.8.5. Decompress it wherever you want. Then enter into the uncompressed folder and install it with:

./install.sh

Note: Uninstall any previous installation. Older releases will work,  but they won’t compile my tweakings.

Installing Arduino.mk

In order for me to work I’d rather install this tool from the Linux Mint repositories:

sudo apt install Arduino.mk

I guess that’s all for the needed tools. If any missing I’ll update this section.

Makefile for our solution

We need to write a Makefile for each of our projects:

ARDUINO_DIR = /your/home/dir/arduino-1.8.5
BOARD_TAG = uno
ARDUINO_PORT = /dev/ttyUSB*
ARDUINO_LIBS =
CFLAGS_STD = -std=c99 -Wall
CXXFLAGS_STD = -std=gnu++11 -Wall -DUNO
include /usr/share/arduino/Arduino.mk

The flag ‘-DUNO’ isn’t needed at all, but as I’m using the Leonardo and Uno boards, I need it to make the difference between them as easy as possible.

Test it!

Before we can upload our executable we must add our user to the dialout group so the serial port is available to us as humans:

$sudo adduser <your_user> dialout

Then log out and log in into your session again.


Last step is to write a test program. Let’s call it main.cpp:

#include <Arduino.h>

int main(void)
{
 init();
 // initialize the Arduino's environment

 pinMode(LED_BUILTIN, OUTPUT);

 while( 1 )
 {
   digitalWrite( LED_BUILTIN, LOW );
   delay( 100 );
   digitalWrite( LED_BUILTIN, HIGH );
   delay( 100 );
 }

 return 0;
}

For compiling write in the console:

make

and for uploading it:

make upload

And the serial monitor?

We have two options:

  • The arduino.mk includes one: make monitor (to exit ctrl-a + ctrl-k).
  • But if you don’t like it, then you might use one of the many serial monitors available in Linux. I like GtkTerm because you can close and open the USB port on demand (for when you’re going to upload the code, for example) without leaving it.

Greetings!