## Friday, November 21, 2014

### STM32F4 with ERIKA Enterprise RTOS OSEK

This blog has been moved: http://scholtyssek.org/blog/2014/11/21/stm32f4-with-erika-enterprise-rtos-osek/

Erika Enterprise is an open source OSEK compliant real time operating system (RTOS) that support the STM32F4-Discovery controller. There is a eclipse tool chain integration available, so it is possible to develop software directly in this IDE. Combined with the GNU ARM Eclipse Plugin, the stlink debugger and programmer and the GNU Tools for ARM Embedded Processors, eclipse is a great tool for developing, flashing and in-circuit-debugging applications based on the ERIKA real time kernel for STM32F4 devices. The OS can be downloaded here, if there are any questions about the installation, please have a look at the wiki or the forum on the ERIKA website.

The OS comes with an oil-file, which is a configuration file for the kernel. In this file, there are several options to config the kernel and to define dependencies for used libraries, e.g. the Cortex Microcontroller Software Interface Standard (CMSIS).
The ERIKA kernel supports several classes of tasks (basic and extended tasks). Compared to the basic tasks, the extended tasks support synchronization via system events. This nice feature allows to activate a task by sending an event within the software. To learn more about the operating system, please have a look at the official documentation.

The following section describes the usage of ERIKA Enterprise with extended tasks and event based scheduling on the STM32F4 controller. To use this kernel configuration, there are some necessary options that can be set in the oil-file. A configuration for the controller looks like this:

CPU mySystem {
OS myOs {
CPU_CLOCK = 168.0;
MODEL = M4;

APP_SRC = "src/code.c";
APP_SRC = "src/pwm.c";
COMPILER_TYPE = GNU;
MULTI_STACK = TRUE {
IRQ_STACK = TRUE {
SYS_SIZE = 512;
};
};

EE_OPT = "DEBUG";
CFLAGS = "-std=c99";
};

MCU_DATA = STM32 {
MODEL = STM32F4xx;
};

The STM32F4-Discovery has an ARM Cortex-M4 cpu which works with a frequency of 168 MHz, so the CPU_CLOCK parameter is set to an appropriate value. The cpu clock depends on the exact model, in this example I used the STM32F407VG. The APP_SRC parameter is used to list every *.c file that should be compiled with the kernel. To use multiple files, the parameter can be repeated. The development is based on the GNU ARM compiler and debugger, so the COMPILER_TYPE is used to declare the GNU toolchain. To use extended tasks, it is necessary to specify a MULTI_STACK and with a static size. The last block defines the CPU model. It is set to the STM32F4 processor family.
To integrate external libraries, like the  ARM specific CMSIS, there is a possibility to add some libraries to the kernel. The following configuration shows how to defines the usage of the additional libraries:

EE_OPT = "__USE_CMSIS_ALL__";
EE_OPT = "__USE_SPD_ALL__";
EE_OPT = "__USE_SYSTICK__";

LIB = ENABLE {
NAME = "ST_CMSIS";
};

LIB = ENABLE {
NAME = "STM32F4XX_SPD";
STM32F4XX_SPD = ENABLE {
USETIM = TRUE;
USEI2C = TRUE;
USEMISC = TRUE;
USESPI = TRUE;
USEUSART = TRUE;
};
};

LIB = ENABLE {
NAME = "STM32F4_DISCOVERY";
};

These parameter are processor specific for the STM32F4 controller. The next configuration part describes the options to configure the ERIKA kernel scheduling. The kernel supports four conformance classes, that can be set (BCC1, BCC2, ECC1, ECC2). The BCC classes support basic tasks during the ECC classes support extended tasks. Extended tasks are necessary for event driven scheduling. To read more about the conformance classes, please have a look at the ERIKA reference manual. The  conformance class can be set with the following parameter:

KERNEL_TYPE = ECC1;


The next step is to configure events and tasks. In this example there will be one task that is triggered by one event. This task will be called setPwmTask and it reacts on a pwmEvent. Tasks can react on a set of events, these have to be assigned in the configuration file. Accordingly a configuration for one task that reacts on one event looks like this:

EVENT pwmEvent {
};

PRIORITY = 0x03; /* lower priority */
AUTOSTART = FALSE;
STACK = PRIVATE {
SYS_SIZE = 512;
};
ACTIVATION = 1;  /* only one pending activation */
SCHEDULE = FULL;
EVENT = pwmEvent;
};


The next step is to declare them in the implementation, so that it could be activated by the software:

DeclareTask(setPwmTask);
DeclareEvent(pwmEvent);

while (1) {
if(WaitEvent(pwmEvent) == E_OK){
/* error handling */
}
getEvent(setPwmTask, &current); /* save event */
ClearEvent(pwmEvent);

/* do some fancy task work */
}
TerminateTask(); // never reached
}

The last step is the initialization of the kernel. After this, the task can be activated by setting the pwmEvent event. The following snippet shows how to initialize the kernel and then activate the setPwmTask periodically:

#include "ee.h"
#include "ee_api.h"
#include "kernel/oo/inc/ee_oo_api.h"

int main(void) {
/* Initialize Erika related stuff */
EE_system_init();

while (1) {
Delay(MILLISECONDS_TO_TICKS(100, SystemCoreClock));
}
}

With ERIKA Enterprise comes a very nice open source real-time OS that can easily be integrated in the eclipse IDE. It runs on the STM32F4-Discovery controller, so that all the nice features of a RTOS are available.

#### 1 comment:

1. Hello Marco,

What RT-Druid version which you are using ?

I'm using "EE_RT-Druid-2.4.0-juno-win32-x86_64". In OIL file, when I change KERNEL_TYPE = BCC2 to
KERNEL_TYPE = ECC2, I got the following error message :

C:\gnu\ARM\bin\arm-none-eabi-ar.exe: creating libee.a
LD
libee.a(ee_altick.o): In function EE_oo_run_next_task':
C:\ERIKA_~1\eclipse\plugins\COE07D~1.201\ee_files\pkg/kernel/oo/inc/ee_oo_internal.h:564: undefined reference to EE_hal_stkchange'
libee.a(ee_evwait.o): In function EE_oo_reschedule_on_block':
C:\ERIKA_~1\eclipse\plugins\COE07D~1.201\ee_files\pkg/kernel/oo/inc/ee_oo_internal.h:753: undefined reference to EE_hal_stkchange'
libee.a(ee_evwait.o): In function EE_oo_run_next_task':
C:\ERIKA_~1\eclipse\plugins\COE07D~1.201\ee_files\pkg/kernel/oo/inc/ee_oo_internal.h:564: undefined reference to EE_hal_stkchange'
collect2.exe: error: ld returned 1 exit status
make: *** [c_mX.elf] Error 1