STM32 FreeRTOS

FreeRTOS Architecture

Official websitehttp://www.freertos.org/
FreeRTOS is a relatively small operating system compared to other operating systems. The minimal FreeRTOS core includes only 3 .c files (tasks.c, queue.c, list.c) and a few header files, totaling less than 9,000 lines of code, including comments and blank lines. A typical compiled binary is less than 10 KB. The FreeRTOS code can be divided into three main areas: tasks, communication, and hardware interfaces

  • Task: FreeRTOS is a relatively small operating system compared to other operating systems. The minimal FreeRTOS kernel includes only three .c files (tasks.c, queue.c, list.c) and a few header files, totaling less than 9000 lines of code, including comments and blank lines. A typical compiled binary is less than 10 KB. About half of the core FreeRTOS code deals with tasks, which are user-defined C functions with priorities. The task.c and task.h files are responsible for all the heavy lifting related to creating, scheduling, and maintaining tasks.
  • Communication: Tasks are important, but being able to communicate between tasks is even more important! This brings us to the second major topic of FreeRTOS: communication. About 40% of the core FreeRTOS code is dedicated to communication. The queue.c and queue.h files handle communication in FreeRTOS, allowing tasks and interrupts to send data to each other using queues, and using semaphores and mutexes to signal the use of critical sections.
  • Hardware Interface: The basic FreeRTOS kernel consists of nearly 9000 lines of code, which is hardware-independent. The same code can run on different hardware platforms with FreeRTOS. About 6% of the core FreeRTOS code serves as a shim between the hardware-independent core and the hardware-related code. In the next section, we will discuss the hardware-related code.

By using cloc to count the lines of code without comments or blank lines in directories such as include/*.c and portable/GCC/ARM_CM4F/ in FreeRTOS 8.0.0, a total of 6566 lines of code is obtained, while the part related to the platform (portable/GCC/ARM_CM4F/ directory) is only 435 lines. Therefore, the calculation shows that 435/6566 = 0.06625 = 6%, which is consistent with the description. However, the original statement of 9000 lines referred to the number of lines of code including comments (which is actually 8759 lines).

Source code download

Official websitehttps://sourceforge.net/projects/freertos

  • tasks.c: Main file that manages tasks.
  • queue.c: Manages communication between tasks using a message queue.
  • list.c: Provides the list data structure used in both system and application implementations.
  • portmacro.h: Defines variables related to hardware, such as data type definitions and function call names (named using portXXXXX), to standardize function calls across platforms.
  • port.c: Defines code implementations that are related to hardware.
  • FreeRTOSConfig.h: Defines various configurations such as clock speed, heap size, and mutexes. This file needs to be created by the user.

FreeRTOS Transplant

You can refer to the video ‘FreeRTOS–Lesson 2.2 Porting FreeRTOS on STM32F4‘ for the STM32F429 board. This mainly involves porting the FreeRTOS structure to the target board. Many internal supports are available, but it is not clear if the CubeIDE version is used.

  1. include .h file
    1. <FreeRTOS>/Source/include
    2. <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK(as it needs to be tailored to one’s own requirements).
    3. <FreeRTOS>/Source/portable/RVDS/ARM_CM4F(Determine the F4 board with M4 core to be used as the primary core.)
      Import the *.h files
  2. Add the *.c files to the project.
    1. <FreeRTOS>/Source/(Import all files.)
    2. <FreeRTOS>/Source/portable/MemMang/heap_1.c
    3.  <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c (Determine the F4 board with M4 core to be used as the primary core.)
  3. Open <FreeRTOS>/Demo/CORTEX_M4F_STM32F407ZG-SK/FreeRTOSConfig.h
    Add #include “stm32f4xx.h” to the file and change #define configCHECK_FOR_STACK_OVERFLOW 2 to #define configCHECK_FOR_STACK_OVERFLOW 0. Save and close the file.
  4. Open <FreeRTOS>/Source/portable/RVDS/ARM_CM4F/port.c and add #include “stm32f4xx.h” to the file.

Note

  1. Modify FreeRTOSConfig.h by removing #ifdef ICCARM and the corresponding #endif.
  2. Modify src/stm32f4xxit.c by adding __attribute((weak)) before the three functions SVCHandler(), PendSV_Handler(), and SysTick_Handler().
  3. Modify src/main.c by adding #include “FreeRTOS.h” and #include “task.h” at the beginning.
  4. Modify src/main.c by adding the three functions vApplicationMallocFailedHook(), vApplicationIdleHook(), and vApplicationStackOverflowHook(), which can be copied from FreeRTOS/Demo/CORTEX_M4F_STM32F407ZG-SK/main.c.
  5. Add the function vApplicationTickHook() in src/main.c with an empty body.
  6. Add the .c files from lib/FreeRTOS/src to the project for compilation. Note: only one heap_x.c file needs to be selected, such as heap_1.c.
  7. Modify main() by adding the line NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4).

In step 16, heap_x.c is one of the various memory management methods provided by FreeRTOS. If the memory configured in the system will not be released, heap_1.c can be used. Otherwise, other management methods should be selected. Step 17 of FreeRTOS Memory Management is to set the NVIC priority to NVIC_PriorityGroup_4 to work with FreeRTOS.

LED on-off test code

Using this sample code to check it is success or not

void LED_Init(void)
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit(&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

__INLINE void LED_On(void)
{
    GPIO_SetBits(GPIOA, GPIO_Pin_5);
}

__INLINE void LED_Off(void)
{
    GPIO_ResetBits(GPIOA, GPIO_Pin_5);
}

static void Blink_Task(void* pvParameters)
{
    TickType_t xLastFlashTime;

    LED_Init();

    xLastFlashTime = xTaskGetTickCount();

    while (1) {
        LED_On();
        vTaskDelayUntil(&xLastFlashTime, 500);
        LED_Off();
        vTaskDelayUntil(&xLastFlashTime, 4500);
    }
}

int main(void)
{
    // Initialize system
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    xTaskCreate(Blink_Task, "LED", configMINIMAL_STACK_SIZE, NULL,
                BLINK_TASK_PRIORITY, NULL);

    vTaskStartScheduler();

    while (1) {
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *

Shopping Cart