CLion环境下移植FreeRTOS
目录
本文只说明在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 */
运行编译通过,烧录后显示到预期效果。
更多推荐


所有评论(0)