The source code for the SCU can be found in the following directory: gsi_scu/srclib/lm32/sys/FreeRTOS_LM32_SCU/port
The documentation of FreeRTOS can be found here.
The following figure shows the minimum number of items in a makefile for a simple FreeRTOS - application:
REPOSITORY_DIR = $(shell git rev-parse --show-toplevel)
MIAN_MODULE := lm32RtosDemo.c
SOURCE += $(SCU_LIB_SRC_LM32_DIR)/scu_std_init.c # Initializes the most important wishbone devices, this will be done by the startup code before the function main() is called.
SOURCE += $(SCU_LIB_SRC_LM32_DIR)/sys/ros_mutex.c # will need from mprintf() when it runs under FreeRTOS
# The following flag is essential so that the build system adds the
# FreeRTOS sources to this project.
USE_RTOS = 1
Heap model 1 will used
RTOS_USING_HEAP = 1
# Reducing the interrupt entry table to a minimum that decreases the interrupt latency time and reduces the memory consumption
DEFINES += MAX_LM32_INTERRUPTS=2
# FreeRTOS will handle the stack defined in lm32RtosDemoConfig.h.
# Therefore we can overwrite the default size of the base stack size (10k)
# into a smaller size.
STACK_SIZE := 256
include $(REPOSITORY_DIR)/makefiles/makefile.scu
The documentation about the FreeRTOS -heab model, selected in the makefile above by the variable "RTOS_USING_HEAP", can be found here.
All FreeRTOS projects needs a special header "FreeRTOSConfig.h" which includes the compiler switches and definitions of constants which will costomize the FreeRTOS kernel.
To avoid confusion the name for this file, corresponding to the project, has to be the following name convention:
< name of main module >Config.h
In our example the name of the config file will be:
lm32RtosDemoConfig.h
The makefile will create a symbolic link with the name "FreeRTOSConfig.h" which points to the file "lm32RtosDemoConfig.h".
The following section schows the content of "lm32RtosDemoConfig.h" which costomizes the FreeRTOS -kernel for this project.
#ifndef _LM32RTOSDEMOCONFIG_H
#define _LM32RTOSDEMOCONFIG_H
#define configUSE_PREEMPTION 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_TICKLESS_IDLE 0
#define configTICK_RATE_HZ 10000 /* Task frequency 10 kHz */
#define configMINIMAL_STACK_SIZE 256
#define configIDLE_SHOULD_YIELD 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
#define configQUEUE_REGISTRY_SIZE 10
#define configUSE_QUEUE_SETS 0
#define configUSE_TIME_SLICING 0
#define configUSE_NEWLIB_REENTRANT 0
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
#define configSTACK_DEPTH_TYPE uint32_t
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (4 * 1024)
#define configAPPLICATION_ALLOCATED_HEAP 1
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
/* Run time and task stats gathering related definitions. */
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 0
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
/* Co-routine related definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES 1
/* Software timer related definitions. */
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY 3
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
/* Interrupt nesting behaviour configuration. */
#define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
#define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
#define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]
/* FreeRTOS MPU specific definitions. */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
/* Optional functions - most linkers will remove unused functions anyway. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 0
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1
#endif /* ifndef _LM32RTOSDEMOCONFIG_H */
This file can be copy and paste be customized to your own project.
The following figure schows the LM32 Application which uses two independend FreeRTOS tasks:
#include <stdbool.h> #include <FreeRTOS.h> #include <task.h> #include <mprintf.h> void myTask1( void* pvParameters ) { mprintf( "Start of task %s, data: %d\n", __func__ , *((int*)pvParameters) ); /* * Main loop of myTask1 */ while( true ) { /* * Do something meaningful things by this task. :-) */ } } void myTask2( void* pvParameters ) { mprintf( "Start of task %s, data: %d\n", __func__, *((int*)pvParameters) ); /* * Main loop of myTask2 */ while( true ) { /* * Do something meaningful things by this task. :-) */ } } void main( void ) { BaseType_t xReturned; int taskData1 = 4711; xReturned = xTaskCreate( myTask1, /* Function that implements the task. */ "TASK 1", /* Text name for the task. */ configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */ (void*)&taskData1, /* Parameter passed into the task. */ ,tskIDLE_PRIORITY + 1 /* Priority at which the task is created. */ NULL /* Used to pass out the created task's handle. */ ); if( xReturned != pdPASS ) { mprintf( "Error %d: by creating task 1!\n", xReturned ); while( true ); } int taskData2 = 42; xReturned = xTaskCreate( myTask2, /* Function that implements the task. */ "task 2", /* Text name for the task. */ configMINIMAL_STACK_SIZE, /* Stack size in words, not bytes. */ (void*)&taskData2, /* Parameter passed into the task. */ tskIDLE_PRIORITY + 1, /* Priority at which the task is created. */ NULL /* Used to pass out the created task's handle. */ ); if( xReturned != pdPASS ) { mprintf( "Error %d: by creating task 2!\n", xReturned ); while( true ); } vTaskStartScheduler(); mprintf( "Error: This point shall never be reached!\n" ); while( true ); }
A code example which is a bit complexer for using of FreeRTOS on the SCU can be found here.
Further code examples by using FreeRTOS running on the SCU can be found here.
-- UlrichBecker - 09 Jan 2024