FreeRTOSConfig.h 配置优化及深入

2023-11-20

本篇目标:基于上一篇的移植freertos(stm32f4_freertos)上,修改 FreeRTOSConfig.h 文件的相关配置来优化辅助 FreeRtos 的使用,并且建立一些基本功能(信号量、消息地列等)的简单应用位于(stm32f4_os_app)工程。

资料准备:


配置优化简介

之前的移植功能只是将从源文件 demo中拷贝了一份 FreeRTOSConfig.h 做了一些移植修改而已,但是对于文件每个宏的定义,以及配置的修改没有做过多的深入。

所以这篇中的工程将 FreeRTOSConfig.h 进行了配置的修改与优化,并且注释了常用的宏定义的用途,详细的也会在下面进行解析,初步来看下相关的配置。

首先将 FreeRTOSConfig.h 的配置分成几部分:

  • FreeRTOS 与系统有关的配置
  • FreeRTOS 与功能api相关的配置
  • FreeRTOS 相关钩子函数的配置
  • FreeRTOS DEBUG调试相关的配置
  • FreeRTOS 与系统优先级相关的配置
  • FreeRTOS 应用自定义配置

配置优化解析

  • FreeRTOS 与系统有关的配置:

    /* RTOS CONFIG(配置) */
    
    /* 系统调度器配置 :抢占式调度为1,时间片调度为0 */
    #define configUSE_PREEMPTION            1
    
    /* 移植系统(stm32)配置的时钟主频,stm32主频最高为 168MHz */
    #define configCPU_CLOCK_HZ              ( SystemCoreClock )
    
    /* Freertos 每 1/1000 s产生一次systick,来维持实时性调度 */
    #define configTICK_RATE_HZ              ( ( TickType_t ) 1000 )
    
    /* Freertos 配置的最大优先级,配置32以内的值 */
    #define configMAX_PRIORITIES            ( 10 )
    
    /* 空闲任务栈大小 */
    #define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 130 )
    
    /* 整个 Freertos 内存堆的大小 */
    #define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 75 * 1024 ) )
    
    /* 任务名称最大长度 */
    #define configMAX_TASK_NAME_LEN         ( 10 )
    
    /* 系统数据类型长度定义,stm32为32位,16位机开启该宏 */
    #define configUSE_16_BIT_TICKS          0
    
    /* 调度与空闲任务优先级相同的任务 */
    #define configIDLE_SHOULD_YIELD         0
    
  • FreeRTOS 与功能api相关的配置:

    /* RTOS API(资源使能与裁剪) */
    
    /* 与互斥锁相关 */
    #define configUSE_MUTEXES               1       //使能互斥锁
    #define configUSE_RECURSIVE_MUTEXES     1       //使能递归互斥锁
    #define configUSE_TASK_NOTIFICATIONS    1       //使能任务间通知
    #define configUSE_COUNTING_SEMAPHORES   1       //使能计数信号量
    #define configUSE_QUEUE_SETS            1       //使能消息集
    #define configQUEUE_REGISTRY_SIZE       8       //设置队列注册的个数
    
    #define configUSE_TIMERS                1       //使能定时器
    #if configUSE_TIMERS
        #define configTIMER_TASK_PRIORITY           ( 2 )
        #define configTIMER_QUEUE_LENGTH            10
        #define configTIMER_TASK_STACK_DEPTH        ( configMINIMAL_STACK_SIZE * 2 )
        #define configUSE_DAEMON_TASK_STARTUP_HOOK  0
    #endif
    
    /* Set the following definitions to 1 to include the API function, or zero
    to exclude the API function. (使能任务相关api) */
    #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
    
    #define INCLUDE_xTaskGetIdleTaskHandle          0
    #define INCLUDE_xTaskGetCurrentTaskHandle       1
    #define INCLUDE_uxTaskGetStackHighWaterMark     1
    #define INCLUDE_xTaskGetSchedulerState          1
    
  • FreeRTOS 相关钩子函数的配置,需要定义钩子函数,钩子函数定义放在了工程 stm_config.c 中:

    #define configUSE_IDLE_HOOK             1
    /* 空闲任务钩子函数使能,需要定义下列函数,此函数在空闲函数 prvIdleTask 中调用 */
    void vApplicationIdleHook( void )
    {
        //log_d("%s", __FUNCTION__);
    }
    
    /* 空闲任务低功耗函数使能,stm32 已经在 port.c 中定义了 vPortSuppressTicksAndSleep 函数,在空闲函数 prvIdleTask 中调用 */
    #define configUSE_TICKLESS_IDLE         0       //
    
    
    #define configUSE_TICK_HOOK             0
    /* tick钩子函数使能,需要定义下列函数,此函数在systick中断函数中由 xTaskIncrementTick 调用 */
    void vApplicationTickHook( void )
    {
        //printf("%s\r\n", __FUNCTION__);
    }
    
    
    #define configUSE_MALLOC_FAILED_HOOK    1
    /* 内存申请失败钩子函数使能,需要定义下列函数,此函数在内存申请函数pvPortMalloc中调用 */
    void vApplicationMallocFailedHook( void )
    {
        log_d("%s", __FUNCTION__);
        log_e("os malloc fail");
    }
    
    
    #define configCHECK_FOR_STACK_OVERFLOW  2
    /* 任务栈溢出检测钩子函数使能,需要定义下列函数,此函数在PendSV函数中由 vTaskSwitchContext调用。
     * 任务堆栈检测有两种方式,发生异常则会调用钩子函数:
     * 方式1为检查当前任务栈指针是否在任务栈的合法空间内。
     * 方式2为在任务栈最后区域填入0xa5a5a5a5的数据,每次调度的时候检查数据是否有改动。
     */
    void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
    {
        log_d("%s", __FUNCTION__);
        log_e("task Overflow : %s [%p]", pcTaskName, xTask);
    }
    
    
    #define configSUPPORT_STATIC_ALLOCATION 0
    /* 静态任务创建函数使能,需要定义下列官方示例函数,使能后可以使用 xTaskCreateStatic 函数 */
    /* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
    implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
    used by the Idle task. */
    void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
                                        StackType_t **ppxIdleTaskStackBuffer,
                                        uint32_t *pulIdleTaskStackSize )
    {
        /* If the buffers to be provided to the Idle task are declared inside this
        function then they must be declared static - otherwise they will be allocated on
        the stack and so not exists after this function exits. */
        static StaticTask_t xIdleTaskTCB;
        static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
    
        /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
        state will be stored. */
        *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
    
        /* Pass out the array that will be used as the Idle task's stack. */
        *ppxIdleTaskStackBuffer = uxIdleTaskStack;
    
        /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
        Note that, as the array is necessarily of type StackType_t,
        configMINIMAL_STACK_SIZE is specified in words, not bytes. */
        *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
    }
    /*-----------------------------------------------------------*/
    
    /* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
    application must provide an implementation of vApplicationGetTimerTaskMemory()
    to provide the memory that is used by the Timer service task. */
    void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
                                         StackType_t **ppxTimerTaskStackBuffer,
                                         uint32_t *pulTimerTaskStackSize )
    {
        /* If the buffers to be provided to the Timer task are declared inside this
        function then they must be declared static - otherwise they will be allocated on
        the stack and so not exists after this function exits. */
        static StaticTask_t xTimerTaskTCB;
        static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
    
        /* Pass out a pointer to the StaticTask_t structure in which the Timer
        task's state will be stored. */
        *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
    
        /* Pass out the array that will be used as the Timer task's stack. */
        *ppxTimerTaskStackBuffer = uxTimerTaskStack;
    
        /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
        Note that, as the array is necessarily of type StackType_t,
        configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
        *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
    }
    
  • FreeRTOS DEBUG调试相关的配置,函数实现在工程 stm_config.c 中:

    /* 使能以下两个宏,既可以使用任务可视化追踪,可以调用 vTaskList 打印任务信息 */
    #define configUSE_TRACE_FACILITY                1
    #define configUSE_STATS_FORMATTING_FUNCTIONS    1
    
    /* 使能下面的宏,将可以调用 vTaskGetRunTimeStats 查看任务占用情况
     * rtos_sys_timer_init 为定时器初始化,定义一个10倍tick(100Hz)以上的速率来计算任务占用率
     * rtos_sys_cnt_get 为获取按上述速率增加的计数值
     */
    #define configGENERATE_RUN_TIME_STATS   1
    #if (defined configGENERATE_RUN_TIME_STATS) && (configGENERATE_RUN_TIME_STATS == 1)
    #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  rtos_sys_timer_init()
    #define portGET_RUN_TIME_COUNTER_VALUE()          rtos_sys_cnt_get()
    #endif
    
    /* Normal assert() semantics without relying on the provision of an assert.h
        header file. (断言) */
    #include "elog.h"
    #define OS_ASSERT(x)       log_e(x)
    #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); OS_ASSERT("os err"); for( ;; ); }
    
  • FreeRTOS 与系统优先级相关的配置:

    /* stm32与os相关中断优先级的配置,由stm32手册以及头文件可知支持优先级为4bit,所以下面配置为4,并且系统初始化的时候需要设置中断分组配置:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); */
    #ifdef __NVIC_PRIO_BITS
        /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
        #define configPRIO_BITS             __NVIC_PRIO_BITS
    #else
        #define configPRIO_BITS             4        /* 15 priority levels */
    #endif
    
    /* The lowest interrupt priority that can be used in a call to a "set priority"
    function. */
    #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0xf
    
    /* The highest interrupt priority that can be used by any interrupt service
    routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
    INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
    PRIORITY THAN THIS! (higher priorities are lower numeric values. */
    #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5
    
    /* 以上两个为RTOS配置的优先级区间,从最大到最小,所以注意所有需要在中断里调用RTOS的api的时候,
     * 这个中断的优先级一定要在上面这个区间内,否则就会出现断言错误,系统也无法正常调度。
     * --------------------------------------------------------------------
     * 下面两个优先级为转换后的优先级数据,因为上面的4bit优先级占据寄存器的高4位,
     * 所以下面需要进行移位转换
     */
    
    /* Interrupt priorities used by the kernel port layer itself.  These are generic
    to all Cortex-M ports, and do not rely on any particular library functions. */
    #define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
    /* !!!! 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    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
    
  • FreeRTOS 应用自定义配置:

    /* 定义常用的优先级,进行应用应用,避免应用编程出现直接的数值 */
    #define RTOS_PRIORITY_HIGHEST       (configMAX_PRIORITIES-1)
    #define RTOS_PRIORITY_LEVEL_1ST     (configMAX_PRIORITIES-2)
    #define RTOS_PRIORITY_LEVEL_2ST     (configMAX_PRIORITIES-3)
    #define RTOS_PRIORITY_LEVEL_3ST     (configMAX_PRIORITIES-4)
    #define RTOS_PRIORITY_LEVEL_4ST     (configMAX_PRIORITIES-5)
    #define RTOS_PRIORITY_LEVEL_5ST     (configMAX_PRIORITIES-6)
    

也贴一下修改后所有的 FreeRTOSConfig.h 以及移植适配的 stm_config.c 文件:

/*
 * FreeRTOS Kernel V10.3.1
 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * http://www.FreeRTOS.org
 * http://aws.amazon.com/freertos
 *
 * 1 tab == 4 spaces!
 */


#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/*-----------------------------------------------------------
 * 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
 *----------------------------------------------------------*/

/* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined (__ICCARM__) || defined (__CC_ARM) || defined (__GNUC__)
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

#ifndef USE_OS
#define USE_OS
#endif

/* RTOS CONFIG(配置) */
#define configUSE_PREEMPTION            1       //抢占式调度:1 | 时间片调度:0
#define configCPU_CLOCK_HZ              ( SystemCoreClock )          //移植系统运行主频
#define configTICK_RATE_HZ              ( ( TickType_t ) 1000 )      //RTOS运行tick时钟
#define configMAX_PRIORITIES            ( 10 )                       //RTOS最大优先级
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 130 )   //RTOS任务最小栈大小
#define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 75 * 1024 ) ) //RTOS内存堆大小
#define configMAX_TASK_NAME_LEN         ( 10 )                       //任务名称最大长度
#define configUSE_16_BIT_TICKS          0       //数据类型长度定义,32位为0,16位或8位开启
#define configIDLE_SHOULD_YIELD         0       //使能与空闲任务优先级相同的任务


/* RTOS API(资源使能与裁剪) */
#define configUSE_MUTEXES               1       //使能互斥锁
#define configUSE_RECURSIVE_MUTEXES     1       //使能递归互斥锁
#define configUSE_TASK_NOTIFICATIONS    1       //使能任务间通知
#define configUSE_COUNTING_SEMAPHORES   1       //使能计数信号量
#define configUSE_QUEUE_SETS            1       //使能队列集
#define configQUEUE_REGISTRY_SIZE       8       //设置队列注册的个数

#define configUSE_TIMERS                1       //使能定时器
#if configUSE_TIMERS
    #define configTIMER_TASK_PRIORITY           ( 2 )
    #define configTIMER_QUEUE_LENGTH            10
    #define configTIMER_TASK_STACK_DEPTH        ( configMINIMAL_STACK_SIZE * 2 )
    #define configUSE_DAEMON_TASK_STARTUP_HOOK  0
#endif

/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. (使能任务相关api) */
#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

#define INCLUDE_xTaskGetIdleTaskHandle          0
#define INCLUDE_xTaskGetCurrentTaskHandle       1
#define INCLUDE_uxTaskGetStackHighWaterMark     1
#define INCLUDE_xTaskGetSchedulerState          1


/* RTOS HOOK(功能钩子函数) */
#ifdef OS_HOOK
    #define configUSE_IDLE_HOOK             1       //空闲任务钩子函数
    #define configUSE_TICKLESS_IDLE         0       //空闲任务低功耗功能使能
    #define configUSE_TICK_HOOK             0       //tick时钟钩子函数
    #define configUSE_MALLOC_FAILED_HOOK    1       //内存申请失败的钩子函数
    #define configCHECK_FOR_STACK_OVERFLOW  2       //任务栈溢出检测
    #define configSUPPORT_STATIC_ALLOCATION 0       //额外静态任务创建,需添加额外函数
#else
    #define configUSE_IDLE_HOOK             0       //空闲函数钩子函数
    #define configUSE_TICK_HOOK             0       //tick时钟钩子函数
#endif


/* RTOS TASK DEBUG(任务资源调试) */
#if (defined OS_DEBUG) && (OS_DEBUG == 1)
    #define configUSE_TRACE_FACILITY                1       //使能任务可视化追踪
    #define configUSE_STATS_FORMATTING_FUNCTIONS    1

    #define configGENERATE_RUN_TIME_STATS   1               //使能任务状态统计函数-计算任务占用率
    #if (defined configGENERATE_RUN_TIME_STATS) && (configGENERATE_RUN_TIME_STATS == 1)
        #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()  rtos_sys_timer_init()
        #define portGET_RUN_TIME_COUNTER_VALUE()          rtos_sys_cnt_get()
    #endif

    /* Normal assert() semantics without relying on the provision of an assert.h
    header file. (断言) */
    #include "elog.h"
    #define OS_ASSERT(x)       log_e(x)
    #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); OS_ASSERT("os err"); for( ;; ); }
#endif

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

/* Cortex-M specific definitions. (stm32与os相关中断优先级的配置) */
#ifdef __NVIC_PRIO_BITS
    /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
    #define configPRIO_BITS             __NVIC_PRIO_BITS
#else
    #define configPRIO_BITS             4        /* 15 priority levels */
#endif

/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0xf

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! 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    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )


/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
// #define xPortSysTickHandler SysTick_Handler


/* others */


/* user config code (用户自定义配置) */
#if (configMAX_PRIORITIES > 6)
    #define RTOS_PRIORITY_HIGHEST       (configMAX_PRIORITIES-1)
    #define RTOS_PRIORITY_LEVEL_1ST     (configMAX_PRIORITIES-2)
    #define RTOS_PRIORITY_LEVEL_2ST     (configMAX_PRIORITIES-3)
    #define RTOS_PRIORITY_LEVEL_3ST     (configMAX_PRIORITIES-4)
    #define RTOS_PRIORITY_LEVEL_4ST     (configMAX_PRIORITIES-5)
    #define RTOS_PRIORITY_LEVEL_5ST     (configMAX_PRIORITIES-6)
#endif


#endif /* FREERTOS_CONFIG_H */


/**
  *****************************************************************************
  * @file    : stm_config.c
  * @author  : Tuu
  * @version : 1.0.0
  * @date    : 2020-04-01
  * @brief   : stm32f407 freertos config file
  ******************************************************************************
  * @lasteditors  : Tuu
  * @lasteditTime : 2020-06-02
  ******************************************************************************
  * @atten   : Copyright (C) by Tuu Inc
  *
  *****************************************************************************
  */

/* Includes -------------------------------------------------------------------*/
#include "config.h"

#include "FreeRTOS.h"
#include "task.h"


/* Defines --------------------------------------------------------------------*/


/* Variables ------------------------------------------------------------------*/
static TaskHandle_t xTask_creat;

/* Functions ------------------------------------------------------------------*/
extern void user_main(void *p);

/**
  * @note   This function is used to creat app task and delect self.
  * @brief  None
  * @param  *p
  * @retval None
  */
static void creat_task(void *p)
{
    log_d("%s", __FUNCTION__);

    /* creat app task in this 在这里创建应用任务 */
    taskENTER_CRITICAL();

    user_main(NULL);

    taskEXIT_CRITICAL();
    /* creat app task in this 在这里创建应用任务 */

#if 0
    int cnt = 0;

    /* delay task 延时退出,并删除本任务 */
    while(1){
        log_d("this is creat task:idle-%d", cnt++);
        vTaskDelay(1000);

        if (cnt >= 10){
            break;
        }
    }
#endif

    log_d("delete creat task");

    vTaskDelete(xTask_creat);
}

/**
  * @note   This function is used to creat app task and delect self.
  * @brief  None
  * @param  *p
  * @retval None
  */
int rtos_init(void)
{
    /* stm32 NVIC config */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

    BaseType_t xReturn = pdPASS;

    log_i("Freertos v10.3.1 start ");

    /* first creat task in this 创建rtos第一个任务,用于创建其他任务 */
    xReturn = xTaskCreate(  (TaskFunction_t )creat_task,
                            (const char *   )"creat_task",
                            (unsigned short )1024,
                            (void *         )NULL,
                            (UBaseType_t    )1,
                            (TaskHandle_t * )&xTask_creat);

    if (pdPASS != xReturn){
        return -1;
    }

    /* start task 开启任务调度 */
    vTaskStartScheduler();

    return xReturn;
}

/* systick */
#if 1
void SysTick_Handler(void)
{
    extern void xPortSysTickHandler( void );
    /* USER CODE END SysTick_IRQn 0 */
    #if (INCLUDE_xTaskGetSchedulerState == 1 )
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
    #endif /* INCLUDE_xTaskGetSchedulerState */
        xPortSysTickHandler();
    #if (INCLUDE_xTaskGetSchedulerState == 1 )
    }
    #endif /* INCLUDE_xTaskGetSchedulerState */
}
#endif

#if (defined OS_DEBUG) && (OS_DEBUG == 1)

#if (defined configGENERATE_RUN_TIME_STATS) && (configGENERATE_RUN_TIME_STATS == 1)
#define USE_IRQ_TICK_CNT    0
#if USE_IRQ_TICK_CNT
static uint32_t rtos_run_time_cnt = 0;

/**
  * @note   TIM2_IRQHandler
  * @brief  None
  * @param  None
  * @retval None
  */
void TIM2_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
        rtos_run_time_cnt++;

        TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }
}
#endif

/**
  * @note   rtos_sys_timer_init
  * @brief  None
  * @param  None
  * @retval None
  */
void rtos_sys_timer_init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

#if !USE_IRQ_TICK_CNT
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;
    TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
#else
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Prescaler = 168-1;
    TIM_TimeBaseStructure.TIM_Period = 100;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    rtos_run_time_cnt = 0;
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
#endif

    TIM_Cmd(TIM2, ENABLE);
}

/**
  * @note   rtos_sys_cnt_get
  * @brief  None
  * @param  None
  * @retval None
  */
uint32_t rtos_sys_cnt_get(void)
{
#if USE_IRQ_TICK_CNT
    return rtos_run_time_cnt;
#else
    return TIM_GetCounter(TIM2);
#endif
}
#endif

#endif

/* config function */
#ifdef OS_HOOK

#if (defined configUSE_IDLE_HOOK) && (configUSE_IDLE_HOOK == 1)
void vApplicationIdleHook( void )
{
    //log_d("%s", __FUNCTION__);
}
#endif

#if (defined configUSE_TICK_HOOK) && (configUSE_TICK_HOOK == 1)
void vApplicationTickHook( void )
{
    //printf("%s\r\n", __FUNCTION__);
}
#endif

#if (defined configUSE_MALLOC_FAILED_HOOK) && (configUSE_MALLOC_FAILED_HOOK == 1)
void vApplicationMallocFailedHook( void )
{
    log_d("%s", __FUNCTION__);
    log_e("os malloc fail");
}
#endif

#if (defined configCHECK_FOR_STACK_OVERFLOW) && (configCHECK_FOR_STACK_OVERFLOW >= 1)
void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
{
    log_d("%s", __FUNCTION__);
    log_e("task Overflow : %s [%p]", pcTaskName, xTask);
}
#endif

#if (defined configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1)
/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
                                    StackType_t **ppxIdleTaskStackBuffer,
                                    uint32_t *pulIdleTaskStackSize )
{
    /* If the buffers to be provided to the Idle task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xIdleTaskTCB;
    static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];

    /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
    state will be stored. */
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;

    /* Pass out the array that will be used as the Idle task's stack. */
    *ppxIdleTaskStackBuffer = uxIdleTaskStack;

    /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configMINIMAL_STACK_SIZE is specified in words, not bytes. */
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
/*-----------------------------------------------------------*/

/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
                                     StackType_t **ppxTimerTaskStackBuffer,
                                     uint32_t *pulTimerTaskStackSize )
{
    /* If the buffers to be provided to the Timer task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xTimerTaskTCB;
    static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];

    /* Pass out a pointer to the StaticTask_t structure in which the Timer
    task's state will be stored. */
    *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;

    /* Pass out the array that will be used as the Timer task's stack. */
    *ppxTimerTaskStackBuffer = uxTimerTaskStack;

    /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
    *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
#endif

#endif


/************************ (C) COPYRIGHT Tuu ********END OF FILE****************/



功能简单应用

在 stm32f4_os_app 工程中,建立了有关任务、信号量、消息队列、互斥锁、定时器、事件通知的简单应用。工程及运行情况如下:
在这里插入图片描述
在这里插入图片描述


小结

这次只是介绍了常用的一些系统配置,这样就可以初步得知道Freertos各方面的功能,也方便以后实际使用。一般大家都喜欢由浅入深,这也是便于理解的方式,先知道功能与使用方法,用于正常开发,再在其他的时间深入功能具体实现的方式。工程也包括了经常会用到的基本功能,可以通过开关宏定义来试着尝试一下。


如有其它问题可以问我哦~

Tuu

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOSConfig.h 配置优化及深入 的相关文章

  • 5.13 综合案例2.0-火焰检测系统(2.2版本接口有更新)

    综合案例2 0 火焰检测系统 简介 火焰传感器 准备 硬件连接图 代码流程 功能实现 1 物联网平台开发 2 设备端开发 调试 3 物联网应用开发 4 1新建 普通项目 4 2创建 Web应用 4 3页面设计 4 4关联产品 4 5关联数据
  • 阿里平头哥CPU技术生态负责人陈炜:平头哥的发展之路

    整理 巫柔颖 RISC V是近年兴起的一种CPU新架构 因其开放 灵活的特性而逐渐成为半导体行业的热门选择 当前 已有近2500家机构加入RISC V基金会 包括阿里 华为 Google 英特尔 IBM等公司 在阿里宣布平头哥开源玄铁RIS
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • 物联网平台相关IoTgo

    相关资源 http www geek workshop com thread 12726 1 1 html https github com itead IoTgo https github com itead IoTgo Android
  • linux espidf vscode

    安装 根据 https docs espressif com projects esp idf zh CN latest esp32s2 get started linux macos setup html 里的要求安装一些东西 点插件的首
  • 44_C++_试定义一个处理学生信息的类Student,包含学号、成绩、姓名等数据成员(学号不能相同)【难点:涉及到了类数组的地址、以及类数组的地址传递】

    题目 难点 Student s new Student 3 类数组的定义 s i set num sorce name 给类数组设置参数的时候 类似于给数组对应下标赋值 这里类数组中的 每个元素都是一个类 包含类中的一切信息 Student
  • 再论FreeRTOS中的configTOTAL_HEAP_SIZE

    关于任务栈和系统栈的基础知识 可以参考之前的随笔 FreeRTOS 任务栈大小确定及其溢出检测 这里再次说明 define configTOTAL HEAP SIZE size t 17 1024 这个宏 官方文档解释 configTOTA
  • 异步Buck和同步Buck的特点

    1 介绍 随着时代的发展 工业 车载 通信 消费类等产品都提出了小型化 智能化的需求 相应的 对于这些系统中的电源模块提出了小型化的要求 目前 市场上依然存在很多异步Buck电源管理芯片使用的场景 针对这些应用 采用同步Buck电源管理芯片
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 使用 GCC 编译器的 ARM 内核的堆栈回溯(当存在 MSP 到 PSP 切换时)

    核心 ARM Cortex M4 编译器 GCC 5 3 0 ARM EABI 操作系统 免费 RTOS 我正在使用 gcc 库函数 Unwind Reason Code Unwind Backtrace Unwind Trace Fn v
  • 医药行业:轻松学会超低温冰箱技能

    超低温冰箱在医疗 科研和生物领域中扮演着至关重要的角色 用于存储和保护对温度极为敏感的样品和药品 然而 由于这些冰箱内的温度波动可能导致样品的损坏 因此对超低温冰箱的监控变得至关重要 客户案例 医疗研究机构 上海某医疗研究机构在其实验室中使
  • MN316 OpenCPU丨HTTP使用介绍

    HTTP Hyper Text Transfer Protocol 即超文本传输协议 是一个简单的请求 响应协议 通常运行在 TCP 之上 它指定了客户端可能发送给服务器消息类型以及得到什么类型响应 HTTPS Hyper Text Tra
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 计算机网络中的通信子网主要有哪些功能?

    计算机网络中的通信子网主要具有以下功能 负责全网的数据通信 通信子网通过使用各种通信协议和传输控制功能 能够确保数据从一台主机安全 准确地传输到另一台主机 这包括数据的封装 解封装 传输控制 差错控制等过程 完成各种网络数据的处理 转换和交
  • 市域治理现代化建设方案(智慧网格解决方案):PPT全文33页,附下载

    关键词 市域治理现代化 智慧网格解决方案 市域治理主要内容 市域社会治理重点内容 市域社会治理现代化 一 市域治理现代化背景 1 城市化进程加速 随着城市化进程的快速推进 城市人口不断增加 城市规模不断扩大 城市治理面临着更加复杂的挑战 2
  • 航空港务数据大屏为航空港的可持续发展提供有力支撑!

    随着经济的发展 不断加建与扩建民用机场 空港行业规模不断扩大 在不断引进和消化发达国家先进技术的同时 中国深入开展了对新技术和新材料的研究 极大地丰富和发展了中国的机场建设技术 且各项机场建设计划均已落实推进 行业在经济发展的推动下欣欣向荣
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • 揭秘看不见人的“黑灯工厂”

    你知道吗 未来工厂不需要人也能24小时运转 未来机器能自己配合的天衣无缝 未来工厂连一点灰尘都进不去 未来自研的智能化设备甚至几秒就能生产出一部手机 千万不要惊讶 其实这样的工厂已经在我们的身边 很可能你在元旦买到的一件衣服 一部手机就是
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free

随机推荐

  • osgEarth的shadowMap看下shadowcaster

    在application中 有osgEarth lights ShadowCaster caster osgEarth findTopMostNodeOfType
  • Ubuntu18.04 下安装CUDA,cuDNN及pytorch-gpu版本过程

    第一步 安装显卡驱动 首先添加ppa源 sudo add apt repository ppa graphics drivers ppa 更新一下 sudo apt get update 安装驱动 友情提示 如果BIOS有开启Secure
  • (esp-idf)一文看懂u8g2库点亮OLED

    github仓库地址 HawkJ02 esp32 oled github com 首先丢一个u8g2库的地址 olikraus u8g2 U8glib library for monochrome displays version 2 gi
  • JDBC基本概念

    什么是JDBC JDBC概念 JDBC Java DataBase Connectivity 是一套统一的基于Java语言的关系数据库编程接口规范 该规范允许将SQL语句作为参数通过JDBC接口发送给远端数据库 远端数据库接收到SQL语句后
  • tcp 三次握手 四次挥手

    四次挥手 为什么 和 不一起发 因为 需要服务器close客户端的套接字 但不是及时的 为了保证响应及时 就需要 比 早发 为什么是客户端先发送关闭请求 close 按图上所示 第一个发送close 的一边会在最后等待一段时间来接收对面的可
  • mysql之操作数据库的DDL语句

    1 退出mysql exit 或 quit 2 显示当前所有数据库 show databases 3 创建数据库 create database 数据库名 4 删除库文件 drop database 数据库名 5 切换正在使用的数据库 us
  • SimMIM:一种更简单的MIM方法

    自从何恺明的MAE 点击蓝字查看文章详情 出来之后 基于MIM Masked Image Modeling 的无监督学习方法越来越受到关注 这里介绍一篇和MAE同期的工作 SimMIM A Simple Framework for Mask
  • 【文件上传 后端】文件上传 后端 Part2 —— base64文件流方式

  • 大四了还在学机器学习

    依然是课程笔记 感谢杨晓春老师的指导 文章目录 绪论 概念 有监督学习无监督学习半监督学习增强学习 假设空间与特征向量的空间映射 概念学习 决策树 决策树的概念表示和适用条件 基本算法与最优分类属性的确定 信息增益 增益率 基尼指数 3种机
  • n选m

    思路 从1遍历到n 对于一个数字要么选要么不选 拿到m个数时停止 def dfs i n m res if len res m print join map str res else if i lt n res append i dfs i
  • dfs玄学剪枝法集锦

    题解 第一题 邮票面值设计问题 这道题是一道比较经典的题目 在NOIP初赛 伤心 试卷上也出现过 由于这道题没有什么比较强的剪枝 因此就不介绍了 主要思路就是枚举最大值 完全背包问题 第二题 木棒 这道题我一开始是直接上爆搜的 由于只有两组
  • day04-编程题

    知识点 数组 题目1 训练 请创建一个长度为6的整数数组 并为数组中的元素赋值 遍历数组 打印所有元素 元素之间用空格隔开 比如 数组为 1 2 3 4 5 打印结果 1 2 3 4 5 训练提示 1 数组中的元素有索引 开始索引和结束索引
  • 字节福利又刷屏了,难怪大家都说“字节三个月,人间抵一年”

    谈到大厂 内推问题无疑是绕不开的一个话题 就算没去大厂实习过 大多数同学印象中的大厂也应该是工资高 给钱痛快 福利待遇好吧 关于大厂我们最常见的进入方式想必就是内推了吧 不知道你馋了没有 如果没有 一起来欣赏下大厂的薪资和福利待遇吧 那么具
  • 002 数据结构_顺序表的实现过程——“C”

    引入 什么是顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构 一般情况下采用数组存储 在数组上完成数据的增删查改 顺序表一般可以分为 静态顺序表 使用定长数组存储元素 动态顺序表 使用动态开辟的数组存储 什么是mall
  • 实验四、shell编程

    一 实验目的 1 了解shell的特点和主要种类 2 掌握 shel1 脚本的建立和执行方式 3 掌握bash的基本语法 4 学会编写shell 脚本 二 实验内容 shell 脚本的建立和执行 历史命令和别名定义 shell变量和位置参数
  • python到底值不值得学,自学两年,有话说!!

    首先说说笔者自己 笔者从小就对计算机有浓厚的兴趣 无奈家里穷 买不起 考大学的时候又阴差阳错的进了文科专业 高大上的工商管理专业 第一台计算机 还是大二的时候花了600买的二手货 海尔品牌机 赛扬466cpu 那时候主流的cpu奔腾500
  • 已经设置了端口映射但是外网还是访问不了服务器

    来自于 http www tp link com cn pages article detail asp result faq d 31 已经设置了端口映射但是外网还是访问不了服务器 1 首先检查您设置的端口影射是否正确映射到您内网的服务器
  • Redis热点数据处理

    1 概念 热点数据就是访问量特别大的数据 2 热点数据引起的问题 流量集中 达到物理网卡上限 请求过多 缓存分片服务被打垮 redis作为一个单线程的结构 所有的请求到来后都会去排队 当请求量远大于自身处理能力时 后面的请求会陷入等待 超时
  • The style on this component requires your app theme to be Theme.MaterialComponents

    MD版本采用如下 implementation com google android material material 1 2 0 alpha01 再采用MD的Dialog的时候报标题错误 后经分析查找 当前版本强制APP主题为Mater
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3