目录

一、创建移植区域

二、移植核心文件

三、移植移植层文件

四、移植配置文件

五、移植堆管理方案

六、修改CMakeLists文件

七、修改配置文件FreeRTOSConfig.h

八、修改中断相关代码

九、示例测试程序(与移植无关)


        本文只说明在CLion环境下移植FreeRTOS,默认已经配置好CLion开发HAL库或标准库环境,只做FreeRTOS源码的移植。

一、创建移植区域

        使用STM32CubeMX生成相关配置文件,在当前工程文件夹下新建一个FreeRTOS文件夹。在FreeRTOS文件夹下再新建两个文件夹,分别命名为Inc和Src,Inc用于存放.h文件,Src用于存放.c文件。

        

  

        

二、移植核心文件

将FreeRTOS-kernel文件夹下的.c文件移植到Src文件夹中。将Include文件夹中的.h文件移植到Inc文件夹中。

三、移植移植层文件

从路径\FreeRTOSv202406.04-LTS\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\portable\GCC\ARM_CM3目录下找到.c和.h文件,分别移入Src和Inc文件夹。port.c主要存放FreeRTOS相关函数

四、移植配置文件

从路径\FreeRTOSv202406.04-LTS\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\examples\template_configuration文件夹中找到.h文件,移植到Inc文件夹中。此文件用于进行FreeRTOS的定制化配置。

五、移植堆管理方案

从路径\FreeRTOSv202406.04-LTS\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\portable\MemMang中找到堆管理方案文件heap_4.c,移植到Src文件夹中。

六、修改CMakeLists文件

将以下内容添加到CMakeLists文件中,确保FreeRTOS文件夹中的内容被正确编译:

cmake_minimum_required(VERSION 3.22)

#
# This file is generated only once,
# and is not re-generated if converter is called multiple times.
#
# User is free to modify the file as much as necessary
#

# Setup compiler settings
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)


# Define the build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE "Debug")
endif()

# ==================== 自动化修改部分开始 ====================
# 自动获取当前 CMakeLists.txt 所在的最内层文件夹名称(如 2.4exmp_LED)
get_filename_component(PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
set(CMAKE_PROJECT_NAME ${PARENT_DIR})
# ==================== 自动化修改部分结束 ====================

# Enable compile command to ease indexing with e.g. clangd
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)

# Core project settings
project(${CMAKE_PROJECT_NAME})
message("Build type: " ${CMAKE_BUILD_TYPE})

# Enable CMake support for ASM and C languages
enable_language(C ASM)

# Create an executable object type
add_executable(${CMAKE_PROJECT_NAME})

# Add STM32CubeMX generated sources
add_subdirectory(cmake/stm32cubemx)

# ========== FreeRTOS 配置 ==========
set(FREERTOS_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/FreeRTOS)
set(FREERTOS_SRC_DIR ${FREERTOS_BASE_DIR}/Src)
set(FREERTOS_INC_DIR ${FREERTOS_BASE_DIR}/Inc)

# 收集所有 .c 源文件
file(GLOB FREERTOS_SOURCES ${FREERTOS_SRC_DIR}/*.c)

# 创建静态库
add_library(freertos_kernel STATIC ${FREERTOS_SOURCES})

# 添加头文件路径(FreeRTOS 自己的头文件)
target_include_directories(freertos_kernel PUBLIC
        ${FREERTOS_INC_DIR}
)

# 继承 stm32cubemx 提供的 HAL、CMSIS 等配置
target_link_libraries(freertos_kernel PUBLIC stm32cubemx)

# Link directories setup
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user defined library search paths
)

# Add sources to executable
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user sources here
)

# Add include paths
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user defined include paths
)

# Add project symbols (macros)
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user defined symbols
)

# Remove wrong libob.a library dependency when using cpp files
list(REMOVE_ITEM CMAKE_C_IMPLICIT_LINK_LIBRARIES ob)

# Add linked libraries
target_link_libraries(${CMAKE_PROJECT_NAME}
        stm32cubemx
        freertos_kernel
        # Add user defined libraries
)

七、修改配置文件FreeRTOSConfig.h

在CLion环境下打开工程找到文件目录下的FreeRTOSConfig.h文件

FreeRTOSConfig.h文件中找到以下定义进行配置修改:

#define configKERNEL_INTERRUPT_PRIORITY          (15<<4)
#define configMAX_SYSCALL_INTERRUPT_PRIORITY     (uint32_t)(5 << 4)
#define configUSE_TIME_SLICING                     1
#define configCPU_CLOCK_HZ    ( ( unsigned long ) 8000000 )
#define configTICK_TYPE_WIDTH_IN_BITS              TICK_TYPE_WIDTH_32_BITS
#define configCHECK_FOR_STACK_OVERFLOW        0

八、修改中断相关代码

方法一:中断函数重定向

stm32f1xx_it.c文件中注释掉或改为弱定义以下三个中断函数:

void SVC_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);

FreeRTOSConfig.h文件中添加中断重定向:

#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

方法二:修改启动文件

startup_stm32f103xe.s文件中将中断函数替换为port.c中的实现。

在CubeMX中将TimeBaseSource切换为其他定时器,以确保HAL库功能正常。

九、示例测试程序(与移植无关)

根据电路图配置两个LED灯,创建两个任务,使LED1以1s为周期闪烁,LED3以200ms闪烁。

在main.c中,编写任务函数和创建任务函数等,

/* USER CODE BEGIN 0 */
//任务模板
void vLED1Task(void *pvParameters) {
  while(1) {
    HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin, GPIO_PIN_SET);
    vTaskDelay(pdMS_TO_TICKS(1000));
    HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin, GPIO_PIN_RESET);
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
  vTaskDelete(NULL);
}

void vLED3Task(void *pvParameters) {
  while(1) {
    HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin, GPIO_PIN_SET);
    vTaskDelay(pdMS_TO_TICKS(200));
    HAL_GPIO_WritePin(LED3_GPIO_Port,LED3_Pin, GPIO_PIN_RESET);
    vTaskDelay(pdMS_TO_TICKS(200));
  }
  vTaskDelete(NULL);
}
/* USER CODE END 0 */

在main()中,

/* USER CODE BEGIN 2 */
  //主函数中创建函数模板
   xTaskCreate(vLED1Task, "LED1", 128, NULL, 1, NULL);
   xTaskCreate(vLED3Task, "LED3", 128, NULL, 1, NULL);

   vTaskStartScheduler();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

运行编译通过,烧录后显示到预期效果。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐