手动移植FreeRTOS到stm32

手动移植FreeRTOS

stm32cubemx内置了freertos,如果不想手动移植,可以参考这个视频:

https://www.bilibili.com/video/BV1To4UeVEHA/

但手动移植可以加深自己的理解,可以参考下面这个视频:
https://www.bilibili.com/video/BV1vUpje9Ej2?p=11

以下内容是手动移植的过程记录

使用stm32cubemx创建裸机项目

注意:在SYS设置timebase source时(即HAL_Delay的时钟源),不能使用SysTick,因为SysTick被FreeRTOS使用了,可以使用其他的(如TIM1、TIM2……)

另外,假设使用了TIM1作为timebase source,记得修改其优先级为较高或最高,比如0或1

Systick的优先级由FreeRTOS设置,我们不用管

移植FreeRTOS

主要包含以下几个步骤:

  1. 下载FreeRTOS

    (我这里选择了9.0.0版本)

  2. 将必要的源码复制到自己的裸机项目中,包括

    • 内核源码(位于FreeRTOS\Source)
    • port代码(位于FreeRTOS\Source\portable)
    • 内存管理代码(位于FreeRTOS\Source\portable\MemMang)
    • FreeRTOSConfig.h头文件(从Demo中寻找适合自己开发板的)
  3. 修改 FreeRTOSConfig.h 文件

  4. 修改 stm32f1xx_it.c文件

接下来依次介绍

第一步,下载,本项目下载的是V9.0.0版本

第二步,在裸机项目目录中新建文件夹FreeRTOS,然后把下面的文件都复制过去
image-20240922200302641

进入【复制的portable文件夹】内,保留2个文件夹,一个是MemMang文件夹,另一个根据自己的编译工具选择,如果是gcc则保留GCC,如果是keil则保留RVDS(注意Keil的移植代码放到RVDS里了),本项目使用GCC编译,所以保留了GCC和MenMang文件夹,其他的都删除了
image-20240922201041846

再进入GCC文件夹内,选择适合自己开发板芯片的部分保留,其他都删除,比如本项目用的是STM32f103,是ARM_Cortex3架构的,所以保留ARM_CM3

然后MemMang文件夹内把heap_4.c保留,其他都删除

最后,还有一个FreeRTOSConfig.h头文件,FreeRTOS内置了很多代码示例,在Demo文件夹内,适配了很多不同的芯片,选择适合自己芯片的示例,进去后找到FreeRTOSConfig.h头文件并把它复制到自己的项目中,我这里是复制到了Core/Inc文件夹下

第三步,修改 FreeRTOSConfig.h 文件

主要是下面2个地方
image-20240922201844776

image-20240922201945892

关于FreeRTOSConfig.h可以从官方文档了解:定制 - FreeRTOS™

修改后的FreeRTOSConfig.h完整代码如下:

/*
    FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
    All rights reserved

    VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.

    This file is part of the FreeRTOS distribution.

    FreeRTOS is free software; you can redistribute it and/or modify it under
    the terms of the GNU General Public License (version 2) as published by the
    Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.

    ***************************************************************************
    >>!   NOTE: The modification to the GPL is included to allow you to     !<<
    >>!   distribute a combined work that includes FreeRTOS without being   !<<
    >>!   obliged to provide the source code for proprietary components     !<<
    >>!   outside of the FreeRTOS kernel.                                   !<<
    ***************************************************************************

    FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  Full license text is available on the following
    link: http://www.freertos.org/a00114.html

    ***************************************************************************
     *                                                                       *
     *    FreeRTOS provides completely free yet professionally developed,    *
     *    robust, strictly quality controlled, supported, and cross          *
     *    platform software that is more than just the market leader, it     *
     *    is the industry's de facto standard.                               *
     *                                                                       *
     *    Help yourself get started quickly while simultaneously helping     *
     *    to support the FreeRTOS project by purchasing a FreeRTOS           *
     *    tutorial book, reference manual, or both:                          *
     *    http://www.FreeRTOS.org/Documentation                              *
     *                                                                       *
    ***************************************************************************

    http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading
    the FAQ page "My application does not run, what could be wrong?".  Have you
    defined configASSERT()?

    http://www.FreeRTOS.org/support - In return for receiving this top quality
    embedded software for free we request you assist our global community by
    participating in the support forum.

    http://www.FreeRTOS.org/training - Investing in training allows your team to
    be as productive as possible as early as possible.  Now you can receive
    FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
    Ltd, and the world's leading authority on the world's leading RTOS.

    http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
    including FreeRTOS+Trace - an indispensable productivity tool, a DOS
    compatible FAT file system, and our tiny thread aware UDP/IP stack.

    http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
    Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.

    http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
    Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS
    licenses offer ticketed support, indemnification and commercial middleware.

    http://www.SafeRTOS.com - High Integrity Systems also provide a safety
    engineered and independently SIL3 certified version for use in safety and
    mission critical applications that require provable dependability.

    1 tab == 4 spaces!
*/

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* Library includes. */
// #include "stm"

/*-----------------------------------------------------------
 * Application specific definitions.
 *
 * These definitions should be adjusted for your particular hardware and
 * application requirements.
 *
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. 
 *
 * See http://www.freertos.org/a00110.html.
 *----------------------------------------------------------*/

#define configUSE_PREEMPTION        1
#define configUSE_IDLE_HOOK         0
#define configUSE_TICK_HOOK         0
#define configCPU_CLOCK_HZ          ( ( unsigned long ) 72000000 )  
#define configTICK_RATE_HZ          ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES        ( 5 )
#define configMINIMAL_STACK_SIZE    ( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE       ( ( size_t ) ( 4 * 1024 ) )
#define configMAX_TASK_NAME_LEN     ( 16 )
#define configUSE_TRACE_FACILITY    0
#define configUSE_16_BIT_TICKS      0
#define configIDLE_SHOULD_YIELD     1
#define configUSE_MUTEXES           1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet       1
#define INCLUDE_vTaskDelete             1
#define INCLUDE_vTaskCleanUpResources   0
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay              1

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY         255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15


#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define INCLUDE_xTaskGetSchedulerState          1

#endif /* FREERTOS_CONFIG_H */


第四步,修改 stm32f1xx_it.c文件

首先找到PendSV_Handler和SVC_Handler这2个函数并注释掉(这两函数由FreeRTOS帮我们写好了),然后找到SysTick函数,修改为如下:

void SysTick_Handler(void)
{
    if (xTaskGetSchedulerState != taskSCHEDULER_NOT_STARTED)
    {
        xPortSysTickHandler();
    }
}

创建自己的task

在项目根目录下新建application文件夹,添加led.h和led.c这2个文件,内容分别如下:

led.h

#ifndef LED_H__
#define LED_H__

void task_led(void *argument);

#endif

led.c

#include "led.h"
#include "main.h"
#include "stm32f1xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"

void task_led(void *argument){
    // taskENTER_CRITICAL();  进入临界区的代码会被保护(不会被打断)
    while(1){
        HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_RESET);
        vTaskDelay(pdMS_TO_TICKS(500));  // 500ms
        
        HAL_GPIO_WritePin(Led_GPIO_Port, Led_Pin, GPIO_PIN_SET);
        vTaskDelay(pdMS_TO_TICKS(500));
    }
}

main.c的main函数如下

// include ...
#include "FreeRTOS.h"  // 必须在include "task" 前面
#include "task.h"
#include "led.h"

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();

    // 创建任务
    xTaskCreate(task_led, "ledTask", 128, NULL, 2, NULL);

    // 启动任务调度器,调度器自己会管理要运行哪个任务
    // 启动rtos调度器后将不会退出了
    vTaskStartScheduler();   
}

cmakelists修改

  1. 通过 target_sources 添加.c源码文件,主要是FreeRTOS的代码和自己创建的代码文件

    # Add sources to executable
    file(GLOB src_rtos FreeRTOS/*.c)
    target_sources(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user sources here
        ${src_rtos}
        FreeRTOS/portable/MemMang/heap_4.c
        FreeRTOS/portable/GCC/ARM_CM3/port.c
        application/led.c
    )
    
  2. 通过 target_include_directories.h 头文件所在目录添加进来,主要是FreeRTOS的头文件和自己创建的头文件

    # Add include paths
    target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
        # Add user defined include paths
        FreeRTOS/include
        FreeRTOS/portable/GCC/ARM_CM3
        application
        
    )
    
  3. 生成hex文件

    add_custom_command(
        TARGET ${CMAKE_PROJECT_NAME}  POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -O ihex "${CMAKE_PROJECT_NAME}.elf" "${CMAKE_PROJECT_NAME}.hex"
    )
    

完整cmakelists.txt如下:

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()

# Set the project name
set(CMAKE_PROJECT_NAME 1_rtos_led2)

# Include toolchain file
include("cmake/gcc-arm-none-eabi.cmake")

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

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

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

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

# Add STM32CubeMX generated sources
add_subdirectory(cmake/stm32cubemx)

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

# Add sources to executable
file(GLOB src_rtos FreeRTOS/*.c)
# aux_source_directory(src_rtos FreeRTOS)
message(${src_rtos})
target_sources(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user sources here
    ${src_rtos}
    FreeRTOS/portable/MemMang/heap_4.c
    FreeRTOS/portable/GCC/ARM_CM3/port.c
    application/led.c
)

# Add include paths
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
    # Add user defined include paths
    FreeRTOS/include
    FreeRTOS/portable/GCC/ARM_CM3
    application
    
)

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

# Add linked libraries
target_link_libraries(${CMAKE_PROJECT_NAME}
    stm32cubemx

    # Add user defined libraries
)

add_custom_command(
    TARGET ${CMAKE_PROJECT_NAME}  POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -O ihex "${CMAKE_PROJECT_NAME}.elf" "${CMAKE_PROJECT_NAME}.hex"
)

这样就完成了,可以进行编译了。

image-20240922212320683

完整项目下载

https://gitcode.net/m0_46079750/stm32_freertos_led

posted @   aJream  阅读(682)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示