• (二)移植FreeRTOS到STM32中


    一、概念

    (1)任务(线程):根据功能的不同,将一个系统分割成一个个独立且无法返回的函数,这个函数就被称为任务
    (2)任务栈:静态创建的任务保存在栈中
    (3)TCB:任务控制块,保存了一个任务节点
    (4)任务就绪列表:初始化的一个列表数组,每个数组元素的列表可以保存多个任务列表项
    (5)任务调度器:实现任务切换,从就绪列表中找到任务优先级最高的任务执行
    (6)临界段:执行的时候不能被中断的代码段,实际就是中断的开关控制
    (7)空闲任务:在CPU空闲时才会运行的任务
    (8)阻塞延时:任务调用此延时函数后,任务会被剥离CPU使用权,然后进入阻塞状态,直到延时结束,任务重新获取CPU使用权才可以继续运行
    (9)时间片:同一优先级下的多个任务,轮流享有CPU使用权,享有CPU的时间叫做时间片
    (10)free rtos官网

    二、移植

    (1)一级文件夹介绍
    一级文件夹
    FreeRTOS:freertos系统文件夹
    FreeRTOS-Plus:第三方组件
    (2)二级文件夹
    二级文件夹
    Demo:官方例程
    License:放置开源协议文件
    Source:系统源码文件(重要)
    (3)三级文件夹
    三级文件夹
    include:头文件
    portable:硬件接口文件
    .c:源文件
    (4)在STM32项目下创建freertos文件夹,然后在文件夹下创建inc、src、port文件夹
    (5)将FreeRTOS源码目录下的FreeRTOS/Source/include文件夹下的.h头文件全部复制到STM32项目的freertos/inc文件夹下
    (6)将FreeRTOS源码目录下的FreeRTOS/Source文件夹下的.c源文件全部复制到STM32项目的freertos/src文件夹下
    (7)将FreeRTOS源码目录下的FreeRTOS/Source/portable文件夹下的MemMang和RVDS文件夹复制到STM32项目的freertos/port文件夹下,其中MemMang文件夹下是不同的内存管理文件,一般选择heap_4.c文件,RVDS/ARM_CM3文件夹下存放的是单片机m3内核,不同单片机根据不同内核进行选择
    (8)打开STM32项目,创建分组,将freertos的.c源文件添加进项目中,.h头文件路径添加到魔术棒中
    (9)复制freertos源码的Demo文件夹下找到对应的单片机和编译器文件夹,将下边的FreeRTOSConfig.h文件复制到项目的头文件文件夹中
    (10)FreeRTOSConfig.h配置文件

    #ifndef FREERTOS_CONFIG_H
    #define FREERTOS_CONFIG_H
    
    /**
     *                                            基础配置
     */
    
    #define configUSE_PREEMPTION		1                                   //1使用抢占式调度器 0使用协作式调度器(时间片)
    #define configUSE_TIME_SLICING      1                                   //使能时间片调度
    #define configUSE_PORT_OPTIMISED_TASK_SELECTION     1                   //任务选择方法,0通用方法 1优化方法,一般为计算前导零[CLZ]指令
    #define configUSE_TICKLESS_IDLE     0                                   //1进入低功耗模式,下载代码可能会出错,0保持系统节拍(tick)中断一直运行
    #define configCPU_CLOCK_HZ			( ( unsigned long ) 72000000 )     //定义系统时钟
    #define configTICK_RATE_HZ			( ( TickType_t ) 1000 )             //系统节拍中断频率,即1s中断的次数
    #define configMAX_PRIORITIES		( 32 )                              //可使用的最大优先级
    #define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )         //空闲任务栈大小
    #define configMAX_TASK_NAME_LEN		( 16 )                              //任务名字最大长度
    #define configUSE_16_BIT_TICKS		0                                   //系统节拍计数器变量数据类型,1表示16位无符号整型,0表示32位无符号整型
    #define configIDLE_SHOULD_YIELD		1                                   //1表示空闲任务会放弃CPU使用权给其他同优先级的任务
    #define configUSE_QUEUE_SETS        0                                   //1表示使能队列集合
    #define configUSE_TASK_NOTIFICATIONS                1                   //1表示使能任务通知功能
    #define configUSE_MUTEXES           0                                   //互斥信号量使能标志
    #define configUSE_RECURSIVE_MUTEXES 0                                   //使用递归互斥信号量
    #define configUSE_COUNTING_SEMAPHORES               0                   //1表示使用计数信号量
    #define configQUEUE_REGISTRY_SIZE   10                                  //可以注册的信号量消息队列个数
    #define configUSE_APPLICATION_TASK_TAG              0
    
    /*
     *                                             内存申请相关配置
     */
    
    #define configSUPPORT_DYNAMIC_ALLOCATION            1                   //支持动态内存申请
    #define configSUPPORT_STATIC_ALLOCATION             0                   //支持静态内存
    #define configTOTAL_HEAP_SIZE		( ( size_t ) ( 17 * 1024 ) )        //系统所有总的堆大小
    
    
    /*
     *                                              钩子函数相关的配置
     */
    
    #define configUSE_IDLE_HOOK			0                                   //1使用空闲钩子 0忽略空闲钩子 freertos规定了函数名,需要用户自己实现void vApplicationIdleHook(void)
    #define configUSE_TICK_HOOK			0                                   //1使用时间片钩子 0忽略时间片钩子 freertos规定了函数名,需要用户自己实现void vApplicationTickHook(void)
    #define configUSE_MALLOC_FAILED_HOOK                0                   //1使用内存申请失败钩子函数
    #define configCHECK_FOR_STACK_OVERFLOW              0                   //1/2表示使用堆栈溢出检测功能 要使用此功能用户需要提供一个栈溢出钩子函数
    
    /*
     *                                          运行时间和任务状态收集的配置
     */
    
    #define configGENERATE_RUN_TIME_STATS               0                   //运行时间统计功能
    #define configUSE_TRACE_FACILITY	0                                   //可视化跟踪调试功能
    #define configUSE_STATS_FORMATTING_FUNCTIONS        0
    
    /*
     *                                                  协程有关的配置
     */
     
    #define configUSE_CO_ROUTINES       0                                   //协程启用状态位,启动协程必须添加croutine.c文件
    #define configMAX_CO_ROUTINE_PRIORITIES              (2)                //协程的有效优先级数目
    
    /*
     *                                               软件定时器相关配置
     */
    
    #define configUSE_TIMERS             0                                  //软件定时器启动标志位
    #define configTIMER_TASK_PRIORITY    (configMAX_PRIORITIES-1)           //软件定时器优先级
    #define configTIMER_QUEUE_LENGTH     (10)                               //软件定时器队列长度
    #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2)       //软件定时器的任务堆栈大小
    
    /*
     *                                           可选配置,是否编译对应的函数
     */
    
    #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
    
    /*
     *                                           中断相关配置
     */
     
    #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
    /* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255*/
    #define configKERNEL_INTERRUPT_PRIORITY 		255
    /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!*/
    #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         //实现跳转到第一个任务的中断
    
    #endif /* FREERTOS_CONFIG_H */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    (11)打开stm32f103x_it.c文件,注释掉已经实现的中断函数PendSV_Handler和SVC_Handler,修改SysTick_Handler内容为以下

    extern void xPortSysTickHandler(void);
    void SysTick_Handler(void)
    {
        #if (INCLUDE_xTaskGetSchedulerState == 1)
            if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_SATRTED)
            {
        #endif
                xPortSysTickHandler();
        #if (INCLUDE_xTaskGetSchedulerState == 1)
            }
        #endif
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    帆软报表实现通过js查询数据库设置表格数据
    【OCR】基于RCNN-CTC的不定长文本识别
    Direct3D模板缓存
    python线程类改变类变量
    【MySQL】为什么使用B+树做索引
    灵性·挖掘 2:自我迭代之路
    麻了,3个offer不知道选哪个?
    整理mongodb文档:副本集二
    自己动手写java虚拟机(第一话)
    奥浦迈生物通过注册:半年营收1.47亿 国寿成达与达晨是股东
  • 原文地址:https://blog.csdn.net/m0_49156395/article/details/136724852