STM32F107RBT6 transplant freeRTOS

When playing 32 boards, when encountering several projects that work at the same time, it is necessary to run on the system. In a small, lightweight, efficient and portable system, freertos is undoubtedly the best choice. Below, let’s transplant the freeRTOS system step by step.

First download the freertos system, the current version is v10.2.1. For porting, only files in FreeRTOS are useful, but not all.
The file structure in the source code is as follows:

Demon: Adapting the template project of each platform, you need the FreeRTOSConfig.h file in the CORTEX_STM32F103_Primer_GCC folder
License: Not used
Soure: The file structure

includes 7 c files, including list.c, Queue.c and tasks.c are the files needed for each project, and other suggestions are added.
The include folder contains the header files required by the system. The
portable folder contains interfaces for different platforms, and the files are required. Note: The MemMang folder is a file about freertos system memory, this can not be deleted.

Start the migration below:

  1. Run keil as administrator and create a blank project
    . See the following figure for the chip selection


  2. Copy the stm32 kernel file and standard peripheral files
    Create CMSIS, STM32F10x_StdPeriph_Driver and User folders in the project path
    CMSIS: Copy the relevant files in the history to this folder, and also copy the stm32f10x_conf.h file to this folder.
    STM32F10x_StdPeriph_Driver: Copy the header files and source code of the peripheral to this file.
    User: Create main.c file, copy
  3. Add the CMSIS, STM32F10x_StdPeriph_Driver and User groups to the keil and add the files added in the second step. The results of the engineering structure diagram are as follows:
  4. Set compilation options


  5. Compile

    No error, very good.

  6. Copy the freertos file
    Create a freeRTOS folder in the project path, copy the downloaded freertos source file souurce->include and some c files to it;
    source->portable->RVDS->ARM_CM3 corresponding port.c and portmacro Copy the .h file to it.
    Copy the heap_4.c file from source->MemMang to it.
    Copy FreeRTOSConfig.h of \FreeRTOSv10.2.1\FreeRTOS\Demo\CORTEX_STM32F107_GCC_Rowley\ to include.
  7. Create a freeRTOS group in the keil project and add all the c files in the freeRTOS folder and add their header files in the compilation path. Figure:
  8. Compile
    Compile error

    This is because the FreeRTOSConfig.h file copied from the source file Demon is not modified according to the actual situation.

    1. #define configUSE_TICK_HOOK 1 Change 1 to 0 here
    2. #define configCPU_CLOCK_HZ ( ( unsigned long ) 62500000 ) Change 62500000 to 72000000 here
    3. #define configCHECK_FOR_STACK_OVERFLOW 2 Here, change 2 to 0
      and compile, resulting in the following error: To
      Adapt_freeRTOS_for_STM32F107RBT6_11.pngsolve this problem, add the definition of ulRunTimeStatsClock in the tasks.c file in the freeRTOS source file, and add a line of code at the end of the file to

      compile. No errors. well.

  9. Modify the stm32 startup file, because the freeRTOS system scheduling needs to use the stm32 interrupt, so you need to replace some interfaces, as shown below: The

    new content is:
    IMPORT xPortPendSVHandler
    IMPORT xPortSysTickHandler
    IMPORT vPortSVCHandler
    new replacement content:
    DCD SVC_Handler -> vPortSVCHandler
    DCD PendSV_Handler -> xPortPendSVHandler
    DCD SysTick_Handler -> xPortSysTickHandler

After modifying the text, recompile the project.

Compile, no error. well.

At this point, the migration process has ended. The following is the application of the system.

freeRTOS application example:
Run three tasks in the system, simply use the serial port to print task_i2c, task_can, task_uart.
The main function is as follows:

#include "stm32f10x.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "uart.h"

#define         START_TASK_PRIO     ((unsigned portBASE_TYPE)2U)
#define         START_STK_SIZE      32
xTaskHandle     StartTask_Handler;

#define         I2C_TASK_PRIO       ((unsigned portBASE_TYPE)3U)
#define         I2C_STK_SIZE        64
xTaskHandle     i2cTask_Handler;

#define         CAN_TASK_PRIO       ((unsigned portBASE_TYPE)3U)
#define         CAN_STK_SIZE        64
xTaskHandle     canTask_Handler;

#define         UART_TASK_PRIO     ((unsigned portBASE_TYPE)3U)
#define         UART_STK_SIZE      64
xTaskHandle     uartTask_Handler;

void task_i2c(void)
        printf("\r\n task_i2c \r\n");

void task_can(void)
		    printf("\r\n task_can \r\n");

void task_uart(void)
        printf("\r\n task_uart \r\n");

void vStartTaskCreate(void *pvParameters)

    xTaskCreate((TaskFunction_t)task_i2c, (const char *)"task_i2c", I2C_STK_SIZE, (void *)NULL, I2C_TASK_PRIO, (xTaskHandle *)i2cTask_Handler);
    xTaskCreate((TaskFunction_t)task_can, (const char *)"task_can", CAN_STK_SIZE, (void *)NULL, CAN_TASK_PRIO, (xTaskHandle *)canTask_Handler);
    xTaskCreate((TaskFunction_t)task_uart, (const char *)"task_uart", UART_STK_SIZE, (void *)NULL, UART_TASK_PRIO, (xTaskHandle *)uartTask_Handler);



int main(void)
    printf("\r\n uartInit() ok!!! \r\n");
    xTaskCreate((pdTASK_CODE)vStartTaskCreate, (const char *)"vStartTaskCreate",
                (uint16_t)START_STK_SIZE, (void *)NULL, (portTickType)START_TASK_PRIO,
                (xTaskHandle *)&StartTask_Handler);



After burning into the board, the results are as shown in the following figure: The

system can schedule different tasks.

Orignal link: