FREERTOS——移植

1、源码获取

freeRTOS官网: https://www.freertos.org/zh-cn-cmn-s

 得到的代码展示:

打开FreeRTOS的内核:

打开FreeRTOS的资源文件:

打开portable文件夹:该文件夹是硬件和FreeRTOS连接的桥梁:

2、移植FreeRTOS源码

2.1 添加FreeRTOS源码,将FreeRTOS源码添加到基础工程

在工程中新建个文件夹

 把FreeRTOS的资源文件里面部分内容copy到新建的文件夹中。

在 portable 文件夹,我们只需要copy keil、MemMang 和 RVDS这三个文件夹。

把include 文件夹,把所有头文件都copy 进去。

 2.2 打开程序工程,新建分组 FreeRTOS_CORE 和 FreeRTOS_PORTABLE,然后向这两个分组中添加文件

 2.3 添加完 FreeRTOS 源码中的 C 文件以后还要添加 FreeRTOS 源码的头文件路径,头文件路

 3. 添加FreeRTOSConfig.h头文件

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include <stdio.h>
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif
/***************************************************************************************************************/
/*                                        断言                                                                 */
/***************************************************************************************************************/
/* 断言 */
#ifdef DEBUG
    #define FREERTOS_PRINTF printf
#else
    #define FREERTOS_PRINTF(format, ...)
#endif
#define vAssertCalled(char,int) FREERTOS_PRINTF("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)
/***************************************************************************************************************/
/*                                        FreeRTOS基础配置配置选项                                              */
/***************************************************************************************************************/
/* 置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片)
 * 
 * 注:在多任务管理机制上,操作系统可以分为抢占式和协作式两种。
 * 协作式操作系统是任务主动释放CPU后,切换到下一个任务。
 * 任务切换的时机完全取决于正在运行的任务。
 */
#define configUSE_PREEMPTION                    1 
/* 1使能时间片调度(默认式使能的) */
#define configUSE_TIME_SLICING                    1 
/* 某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务:
 * 通用方法和特定于硬件的方法(以下简称“特殊方法”)。
 * 
 * 通用方法:
 *      1.configUSE_PORT_OPTIMISED_TASK_SELECTION 为 0 或者硬件不支持这种特殊方法。
 *      2.可以用于所有FreeRTOS支持的硬件
 *      3.完全用C实现,效率略低于特殊方法。
 *      4.不强制要求限制最大可用优先级数目
 * 特殊方法:
 *      1.必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。
 *      2.依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。
 *      3.比通用方法更高效
 *      4.一般强制限定最大可用优先级数目为32
 * 一般是硬件计算前导零指令,如果所使用的,MCU没有这些硬件指令的话此宏应该设置为0!
 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION    1 
/* 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行
 * 假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用以下办法解决
 * 
 * 下载方法:
 *      1.将开发版正常连接好
 *      2.按住复位按键,点击下载瞬间松开复位按键
 *     
 *      1.通过跳线帽将 BOOT 0 接高电平(3.3V)
 *      2.重新上电,下载
 *    
 *             1.使用FlyMcu擦除一下芯片,然后进行下载
 *            STMISP -> 清除芯片(z)
 */
#define configUSE_TICKLESS_IDLE                    0    
/*
 * 写入实际的CPU内核时钟频率,也就是CPU指令执行频率,通常称为Fclk
 * Fclk为供给CPU内核的时钟信号,我们所说的cpu主频为 XX MHz,
 * 就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期;
 */
#define configCPU_CLOCK_HZ                        (SystemCoreClock)       
/* 时钟节拍频率,这里设置为1000,周期就是1ms */
#define configTICK_RATE_HZ                        ( ( TickType_t ) 1000 ) 
/* 可使用的最大优先级 */
#define configMAX_PRIORITIES                    (32)                    
/* 空闲任务使用的堆栈大小 */
#define configMINIMAL_STACK_SIZE                ((unsigned short)128)   
/* 任务名字字符串长度 */
#define configMAX_TASK_NAME_LEN                    (16)                    
/* 系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形 */
#define configUSE_16_BIT_TICKS                    0       
/* 为1时空闲任务放弃CPU使用权给其他同优先级的用户任务 */
#define configIDLE_SHOULD_YIELD                    1
/* 为1时开启任务通知功能,默认开启 */
#define configUSE_TASK_NOTIFICATIONS            1
/* 定义任务通知数组的大小, 默认: 1 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES   1
/* 为1时使用互斥信号量 */
#define configUSE_MUTEXES                        1
/* 为1时使用递归互斥信号量 */
#define configUSE_RECURSIVE_MUTEXES                1
/* 为1时使用计数信号量 */
#define configUSE_COUNTING_SEMAPHORES            1
/* 不为0时表示启用队列记录,具体的值是可以记录的队列和信号量最大数目。 */
#define configQUEUE_REGISTRY_SIZE                8
/* 为1时启用队列 */
#define configUSE_QUEUE_SETS                    1
/* 1: 任务创建时分配Newlib的重入结构体, 默认: 0 */
#define configUSE_NEWLIB_REENTRANT              0
/* 1: 使能兼容老版本, 默认: 1 */
#define configENABLE_BACKWARD_COMPATIBILITY     0
/* 定义线程本地存储指针的个数, 默认: 0 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
/*  */
#define configUSE_APPLICATION_TASK_TAG            0    
//
/* 定义任务堆栈深度的数据类型, 默认: uint16_t */
#define configSTACK_DEPTH_TYPE                          uint16_t
/* 定义消息缓冲区中每条消息的长度, 默认: size_t */
#define configMESSAGE_BUFFER_LENGTH_TYPE                size_t
/***************************************************************************************************************/
/*                                FreeRTOS与内存申请有关配置选项                                                */
/***************************************************************************************************************/
/* 支持动态内存申请 */
#define configSUPPORT_DYNAMIC_ALLOCATION        1
/* 支持静态内存 */
#define configSUPPORT_STATIC_ALLOCATION            0
/* 系统所有总的堆大小 */
#define configTOTAL_HEAP_SIZE                    ((size_t)(32*1024))
/* 1: 用户手动分配FreeRTOS内存堆(ucHeap), 默认: 0 */
#define configAPPLICATION_ALLOCATED_HEAP                0
/* 1: 用户自行实现任务创建时使用的内存申请与释放函数, 默认: 0 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP       0
/***************************************************************************************************************/
/*                                FreeRTOS与钩子函数有关的配置选项                                              */
/***************************************************************************************************************/
/* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子
 * 
 * 空闲任务钩子是一个函数,这个函数由用户来实现,
 * FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ),
 * 这个函数在每个空闲任务周期都会被调用
 * 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。
 * 因此必须保证空闲任务可以被CPU执行
 * 使用空闲钩子函数设置CPU进入省电模式是很常见的
 * 不可以调用会引起空闲任务阻塞的API函数
 */
#define configUSE_IDLE_HOOK                        1
/* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子
 * 
 * 时间片钩子是一个函数,这个函数由用户来实现,
 * FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void )
 * 时间片中断可以周期性的调用
 * 函数必须非常短小,不能大量使用堆栈,
 * 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数
 */
/*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/
#define configUSE_TICK_HOOK                        0
/* 使用内存申请失败钩子函数 */
#define configUSE_MALLOC_FAILED_HOOK            0
/* 大于0时启用堆栈溢出检测功能,如果使用此功能 
 * 用户必须提供一个栈溢出钩子函数,如果使用的话
 * 此值可以为1或者2,因为有两种栈溢出检测方法 */
#define configCHECK_FOR_STACK_OVERFLOW            0
/* 1: 使能定时器服务任务首次执行前的钩子函数, 默认: 0 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK      0
/***************************************************************************************************************/
/*                                FreeRTOS与运行时间和任务状态收集有关的配置选项                                 */
/***************************************************************************************************************/
/* 为1时启用运行时间统计功能 */
#define configGENERATE_RUN_TIME_STATS            0
#if configGENERATE_RUN_TIME_STATS
/* 定时器3提供时间统计的时基,频率为10K,即周期为100us */
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  ConfigureTimeForRunTimeStats()
/* 获取时间统计时间值 */
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE()          FreeRTOSRunTimeTicks
#endif
/* 为1启用可视化跟踪调试 */
#define configUSE_TRACE_FACILITY                0
/* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
 * prvWriteNameToBuffer()
 * vTaskList(),
 * vTaskGetRunTimeStats()
*/
#define configUSE_STATS_FORMATTING_FUNCTIONS    0
/***************************************************************************************************************/
/*                                FreeRTOS与协程有关的配置选项                                                  */
/***************************************************************************************************************/
/* 为1时启用协程,启用协程以后必须添加文件croutine.c */
#define configUSE_CO_ROUTINES                     0     
/* 定义协程的最大优先级, 最大优先级=configMAX_CO_ROUTINE_PRIORITIES-1, 无默认configUSE_CO_ROUTINES为1时需定义 */
#define configMAX_CO_ROUTINE_PRIORITIES         ( 2 )                   
/***************************************************************************************************************/
/*                                FreeRTOS与软件定时器有关的配置选项                                            */
/***************************************************************************************************************/
/* 为1时启用软件定时器 */
#define configUSE_TIMERS                        0   
/* 软件定时器优先级 */
#define configTIMER_TASK_PRIORITY                (configMAX_PRIORITIES-1)   
/* 软件定时器队列长度 */
#define configTIMER_QUEUE_LENGTH                5          
/* 软件定时器任务堆栈大小 */
#define configTIMER_TASK_STACK_DEPTH            (configMINIMAL_STACK_SIZE*2)    
/***************************************************************************************************************/
/*                                FreeRTOS可选函数配置选项                                                      */
/***************************************************************************************************************/
/* 获取任务调度器状态 */
#define INCLUDE_xTaskGetSchedulerState          1   
/* 设置任务优先级 */
#define INCLUDE_vTaskPrioritySet                1
/* 获取任务优先级 */
#define INCLUDE_uxTaskPriorityGet                1
/* 删除任务 */
#define INCLUDE_vTaskDelete                        1
/*  */
#define INCLUDE_vTaskCleanUpResources            1
/* 挂起任务 */
#define INCLUDE_vTaskSuspend                    1
/* 任务绝对延时 */
#define INCLUDE_vTaskDelayUntil                    1
/* 任务延时 */
#define INCLUDE_vTaskDelay                        1
/* 获取任务状态 */
#define INCLUDE_eTaskGetState                    1
/* 将函数的执行挂到定时器服务任务 */
#define INCLUDE_xTimerPendFunctionCall            0
/* 获取任务堆栈历史剩余最小值 */
#define INCLUDE_uxTaskGetStackHighWaterMark     1
/* 获取空闲任务的任务句柄 */
#define INCLUDE_xTaskGetIdleTaskHandle          1
/* 中断任务延时 */
#define INCLUDE_xTaskAbortDelay                 1
/* 通过任务名获取任务句柄 */
#define INCLUDE_xTaskGetHandle                  1
/* 恢复在中断中挂起的任务 */
#define INCLUDE_xTaskResumeFromISR              1
/* 以下为使用Percepio Tracealyzer需要的东西,不需要时将 configUSE_TRACE_FACILITY 定义为 0 */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
/* 启用一个可选函数(该函数被 Trace源码使用,默认该值为0 表示不用)*/
/* 获取当前任务的任务句柄 */
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#else
/* 获取当前任务的任务句柄 */
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#endif
/* 恢复在中断中挂起的任务 */
//#define INCLUDE_xResumeFromISR                  1
/* 在中断中设置事件标志位 */
//#define INCLUDE_xEventGroupSetBitFromISR        1
/***************************************************************************************************************/
/*                                FreeRTOS与中断有关的配置选项                                                  */
/***************************************************************************************************************/
#ifdef __NVIC_PRIO_BITS
    #define configPRIO_BITS               __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS               4                  
#endif
/* 中断最低优先级 */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY            15
/* 系统可管理的最高中断优先级 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
/*  */
#define configKERNEL_INTERRUPT_PRIORITY                 ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/*  */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY             ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* 无作用? */
//#define configMAX_API_CALL_INTERRUPT_PRIORITY           configMAX_SYSCALL_INTERRUPT_PRIORITY
/* 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
/***************************************************************************************************************/
/*                                FreeRTOS与中断服务函数有关的配置选项                                         */
/***************************************************************************************************************/
#define xPortPendSVHandler     PendSV_Handler
#define vPortSVCHandler     SVC_Handler
/***************************************************************************************************************/
/*                                FreeRTOS MPU 特殊定义                                                        */
/***************************************************************************************************************/
//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
//#define configTOTAL_MPU_REGIONS                                8
//#define configTEX_S_C_B_FLASH                                  0x07UL
//#define configTEX_S_C_B_SRAM                                   0x07UL
//#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY            1
//#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS             1
/***************************************************************************************************************/
/*                                ARMv8-M 安全侧端口相关定义。                                                 */
/***************************************************************************************************************/
//#define secureconfigMAX_SECURE_CONTEXTS         5


#endif /* FREERTOS_CONFIG_H */

4. 修改中断函数

1. 注销SVC_Handler和PendSV_Handler两个函数。

2. 修改SysTick_Handler函数

#include "FreeRTOS.h"
#include "task.h"
/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
    {//系统已经运行
#endif  /* INCLUDE_xTaskGetSchedulerState */ 
        extern void xPortSysTickHandler(void);        
        xPortSysTickHandler();    
#if (INCLUDE_xTaskGetSchedulerState  == 1 )
    }
#endif  /* INCLUDE_xTaskGetSchedulerState */
  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

5.添加启动任务创建文件

/* Includes ------------------------------------------------------------------*/
#include "components.h"
//
#include "FreeRTOS.h"
#include "task.h"
//
#include "bsp.h"
/* Private macros ------------------------------------------------------------*/
/*******任务优先级******/
#define MAIN_TASK_PRIORITY        (configMAX_PRIORITIES-1)
/*******任务堆栈大小******/    
#define MAIN_TASK_STACK_SIZE     512 
/* Private types -------------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/*任务句柄*/
TaskHandle_t MainTask_Handler = NULL;
#if configSUPPORT_STATIC_ALLOCATION
    /* 空闲任务任务堆栈 */
    static StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
    /* 定时器任务堆栈 */
    static StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];
    /* 空闲任务控制块 */
    static StaticTask_t Idle_Task_TCB;    
    /* 定时器任务控制块 */
    static StaticTask_t Timer_Task_TCB;
    /* MainTask任务任务堆栈 */
    static StackType_t MainTask_Stack[128];
    /* MainTask 任务控制块 */
    static StaticTask_t MainTask_TCB;
#endif
/* Private functions ---------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
extern void SystemClock_Config(void);
/***********************************************************************************************

                                       硬件配置函数

************************************************************************************************/
#if configSUPPORT_STATIC_ALLOCATION
/**
  **********************************************************************
  * @brief  获取空闲任务的任务堆栈和任务控制块内存
    *                    ppxTimerTaskTCBBuffer    :    任务控制块内存
    *                    ppxTimerTaskStackBuffer    :    任务堆栈内存
    *                    pulTimerTaskStackSize    :    任务堆栈大小
  * @author  fire
  * @version V1.0
  * @date    2018-xx-xx
  **********************************************************************
  */ 
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
                                   StackType_t **ppxIdleTaskStackBuffer, 
                                   uint32_t *pulIdleTaskStackSize)
{
    *ppxIdleTaskTCBBuffer=&Idle_Task_TCB;/* 任务控制块内存 */
    *ppxIdleTaskStackBuffer=Idle_Task_Stack;/* 任务堆栈内存 */
    *pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;/* 任务堆栈大小 */
}
/**
  *********************************************************************
  * @brief  获取定时器任务的任务堆栈和任务控制块内存
    *                    ppxTimerTaskTCBBuffer    :        任务控制块内存
    *                    ppxTimerTaskStackBuffer    :    任务堆栈内存
    *                    pulTimerTaskStackSize    :        任务堆栈大小
  * @author  fire
  * @version V1.0
  * @date    2018-xx-xx
  **********************************************************************
  */ 
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 
                                    StackType_t **ppxTimerTaskStackBuffer, 
                                    uint32_t *pulTimerTaskStackSize)
{
    *ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任务控制块内存 */
    *ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任务堆栈内存 */
    *pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任务堆栈大小 */
}
#endif
/***********************************************************************************************

                                       应用任务函数

************************************************************************************************/
/* 开始任务任务函数 */
void main_thread_entry(void *pvParameters)
{
    extern int main(void);
    extern int $Super$$main(void);
    
    taskENTER_CRITICAL();           /*进入临界区*/
    /***************创建任务***************/
    /* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)
    $Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)
    main();
#endif
    /*************删除开始任务*************/         
    vTaskDelete(NULL);   
    taskEXIT_CRITICAL();            /*退出临界区*/
}
/***********************************************************************************************

                                       应用主函数

************************************************************************************************/
void FreeRtos_hw_board_init(void)
{
    HAL_Init();
    /* Configure the system clock */
    SystemClock_Config();
    /* 硬件BSP初始化统统放在这里,比如LED、串口、LCD等 */
    BSP_Init();
    
#ifdef HARDWARE_TEST
    /* 测试硬件是否正常工作 */
    
#endif
}
void FreeRtos_application_init(void)
{
#if configSUPPORT_STATIC_ALLOCATION
    /* 创建 AppTaskCreate 任务 */
    MainTask_Handler = xTaskCreateStatic((TaskFunction_t    )main_thread_entry,        //任务函数
                                         (const char*     )"main",        //任务名称
                                         (uint32_t         )MAIN_TASK_STACK_SIZE,    //任务堆栈大小
                                         (void*               )NULL,                //传递给任务函数的参数
                                         (UBaseType_t     )MAIN_TASK_PRIORITY,     //任务优先级
                                         (StackType_t*   )MainTask_Stack,    //任务堆栈
                                         (StaticTask_t*  )&MainTask_TCB);    //任务控制块
#else
    xTaskCreate((TaskFunction_t )main_thread_entry,            /*任务函数*/
                (const char*    )"main",          /*任务名称*/
                (uint16_t       )MAIN_TASK_STACK_SIZE,        /*任务堆栈大小*/
                (void*          )NULL,                  /*传递给任务函数的参数*/
                (UBaseType_t    )MAIN_TASK_PRIORITY,       /*任务优先级*/
                (TaskHandle_t*  )&MainTask_Handler);   /*任务句柄*/
#endif
}
int FreeRtos_startup(void)
{
    taskENTER_CRITICAL();           /*进入临界区*/
    /* board level initialization
     * NOTE: please initialize heap inside board initialization.
     */
    FreeRtos_hw_board_init();    

    /* create init_thread */
    FreeRtos_application_init();
         
    /* start scheduler */
    if(NULL != MainTask_Handler)/* 创建成功 */
        vTaskStartScheduler();/* 启动任务,开启调度 */
    
    /* never reach here */
    return 0;
}

#if defined(__CC_ARM) || defined(__CLANG_ARM)
extern int $Super$$main(void);
/* re-define main function */
int $Sub$$main(void)
{
    FreeRtos_startup();
    return 0;
}
#elif defined(__ICCARM__)
extern int main(void);
/* __low_level_init will auto called by IAR cstartup */
extern void __iar_data_init3(void);
int __low_level_init(void)
{
    // call IAR table copy function.
    __iar_data_init3();
    FreeRtos_startup();
    return 0;
}
#elif defined(__GNUC__)
extern int main(void);
/* Add -eentry to arm-none-eabi-gcc argument */
int entry(void)
{
    FreeRtos_startup();
    return 0;
}
#endif

6. 修改main.c文件

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
#include "main.h"
#include "bsp.h"
#if (SYS_SUPPORT_OS == 0)
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "dma.h"
#include "eth.h"
#include "iwdg.h"
#include "rtc.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#else
#include "mydata.h"
#include "Task_LED.h"
#endif
/* USER CODE END Includes */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
#if ( SYS_SUPPORT_OS == 0 )
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_CAN1_Init();
  MX_CAN2_Init();
  MX_IWDG_Init();
  MX_RTC_Init();
  MX_SPI3_Init();
  MX_USART1_UART_Init();
  MX_USART3_UART_Init();
  MX_USART6_UART_Init();
  MX_ETH_Init();
  /* USER CODE BEGIN 2 */
#endif
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
#if 1
  AppData_Init();
  RTOS_Components_Init();
  Task_LED_create();
#else
  while (1)
  {
    /* USER CODE END WHILE */

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

7.添加测试任务(Task_LED)

 

/* Includes ------------------------------------------------------------------*/
#include "Task_LED.h"
/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
/*  */
#include "bsp.h"
/* Private macros ------------------------------------------------------------*/
#if ( configUSE_IDLE_HOOK == 0 )
/*******任务优先级******/
#define LED_TASK_PRIO        1
/*******任务堆栈大小******/    
#define LED_STK_SIZE         64 
/* Private types -------------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* LED任务句柄 */
static TaskHandle_t LED_Task_Handle = NULL;/* LED任务句柄 */
#endif
/* Private functions ---------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/***********************************************************************************************

                                       应用任务函数

************************************************************************************************/
#if ( configUSE_IDLE_HOOK == 0 )
void led_task(void *pvParameters)
#else
// 空闲钩子函数
void vApplicationIdleHook( void )
#endif
{
    while(1)
    {
        LED2(LED_OFF);
        HAL_xmsDelay( 179 );
        FeedDog();
        LED2(LED_ON);
        HAL_xmsDelay( 19 );
        FeedDog();
    }
}
/***********************************************************************************************

                                       应用主函数

************************************************************************************************/
void Task_LED_create(void)
{
#if ( configUSE_IDLE_HOOK == 0 )
    BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为pdPASS */
    
    /* 创建LED1_Task任务 */
    xReturn = xTaskCreate((TaskFunction_t )led_task,         /* 任务入口函数 */
                          (const char*    )"led",       /* 任务名字 */
                          (uint16_t       )LED_STK_SIZE,     /* 任务栈大小 */
                          (void*          )NULL,              /* 任务入口函数参数 */
                          (UBaseType_t    )LED_TASK_PRIO,      /* 任务的优先级 */
                          (TaskHandle_t*  )&LED_Task_Handle);/* 任务控制块指针 */    
    if(pdPASS == xReturn)
        PRINTF("[D] [RTOS] led_task create succeed!\r\n");
    else
        PRINTF("[D] [RTOS] led_task create failure!\r\n");
#else
    PRINTF("[D] [RTOS] IdleHook create succeed!\r\n"); 
#endif
}
#ifndef __Task_LED_H__
#define __Task_LED_H__

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Includes ------------------------------------------------------------------*/
/* Private macros ------------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported macros -----------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
void Task_LED_create(void);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif  // __Task_LED_H__

 

posted @ 2024-08-09 13:50  我是,一株蒜。  阅读(16)  评论(0)    收藏  举报