• 【STM32/FreeRTOS】SysTick定时器及FreeRTOS系统节拍


    目录

    一、SysTick定时器

    1、SysTick寄存器介绍

    (1)控制及状态寄存器

    (2)重装载数值寄存器

    (3)当前数值寄存器

    2、SysTick寄存器配置函数

    二、FreeRTOS中的SysTick定时器

    1、SysTick配置函数及分析

    2、SysTick中断函数

    三、其他操作配置FreeRTOS的SysTick

    1、找到头文件 FreeRTOSConfig.h 有如下定义。

    2、搜索 configTICK_RATE_HZ,在port.c中。

    3、搜索 portNVIC_SYSTICK_CTRL_REG,在port.c中。

    4、下面证明地址是不是SYSTICK的配置地址。

     5、跳转到 SysTick 定义处。


    一、SysTick定时器

    SysTick系统定时器是属于内核中的一个外设,内嵌在NVIC中。该定时器是一个24位的向下递减的计数器。在裸机编程中常用做延时函数,而在FreeRTOS中则用来给系统提供时钟的,因此非常重要。

    1、SysTick寄存器介绍

    SysTick共有4个相关寄存器,通常只用到3个(校准寄存器少用)。

    寄存器名称寄存器描述
    CTRLSysTick控制及状态寄存器
    LOADSysTick重装载数值寄存器
    VALSysTick当前数值寄存器
    CALIBSysTick校准数值寄存器

    (1)控制及状态寄存器

    可通过读取第16位判断计数是否到0。

    (2)重装载数值寄存器

           用来存放重装载数的,改变该值以调节计数时间。数值范围:0—(2^24-1)即(0-16777215)。

    (3)当前数值寄存器

           该寄存器的值在递减,计数到0时会自动重载,数值为重装载数值寄存器内的值。

    2、SysTick寄存器配置函数

            在库文件core_cm4.h (M4内核)中有相关配置函数,也可以重写。

    1. __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) /*参数ticks为计数值,最大2^24(已有减1操作)*/
    2. {
    3. if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1);/*判断传入的值是否满足,不能超过0xffffff*/
    4. SysTick->LOAD = ticks - 1; /*将数值传入重装载数值寄存器*/
    5. NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /*设置Systick中断优先级*/
    6. SysTick->VAL = 0; /*清空当前值寄存器*/
    7. SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
    8. SysTick_CTRL_TICKINT_Msk |
    9. SysTick_CTRL_ENABLE_Msk;
    10. /* SysTick_CTRL_CLKSOURCE_Msk = 1<<2 */
    11. /* SysTick_CTRL_TICKINT_Msk = 1<<1 */
    12. /* SysTick_CTRL_ENABLE_Msk = 1<<0 */
    13. /*将第0、1、2位置1,即使能定时器,使能中断,选择系统时钟(168M或72M)*/
    14. return (0);
    15. }

    二、FreeRTOS中的SysTick定时器

    在FreeRTOS中SysTick定时器尤为重要,因为它是给FreeRTOS系统提供时钟的。在FreeRTOS中任务的切换即每个任务运行的时间是由SysTick定时器提供的。

    1、SysTick配置函数及分析

    在FreeRTOS中已经提供了SysTick配置的函数vPortSetupTimerInterrupt(),函数在port.c文件中。当调用了开启任务调度函数vTaskStartScheduler()后里面就会调用该函数完成SysTick的配置。vPortSetupTimerInterrupt()函数分析:
     

    1. #if ( configOVERRIDE_DEFAULT_TICK_CONFIGURATION == 0 ) /*条件编译*/
    2. __weak void vPortSetupTimerInterrupt( void )
    3. {
    4. /* Calculate the constants required to configure the tick interrupt. */
    5. #if ( configUSE_TICKLESS_IDLE == 1 ) /*条件编译,这段不编译*/
    6. {
    7. ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
    8. xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
    9. ulStoppedTimerCompensation = portMISSED_COUNTS_FACTOR / ( configCPU_CLOCK_HZ / configSYSTICK_CLOCK_HZ );
    10. }
    11. #endif /* configUSE_TICKLESS_IDLE */
    12. portNVIC_SYSTICK_CTRL_REG = 0UL; /*清空控制及状态寄存器*/
    13. portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; /*清空当前值寄存器*/
    14. /*设置重装载数值寄存器数值*/
    15. /*168000000/1000= 168000重装载值,168000/168M=0.001S=1MS*/
    16. portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
    17. /*设置控制及状态寄存器*/
    18. portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
    19. /*( 1UL << 2UL ) | ( 1UL << 1UL ) | ( 1UL << 0UL ) */
    20. /*选择处理器时钟、开定时器中断、使能定时器*/
    21. }
    22. #endif /* configOVERRIDE_DEFAULT_TICK_CONFIGURATION */

     

    2、SysTick中断函数

    在SysTick中断函数中并不是直接执行任务切换,而是将xTickCount进行加1操作,xTickCount是FreeRTOS的系统时钟节拍数,具体实现函数则是xTaskIncrementTick(),该函数在中断函数中被调用。中断函数的实现在port.c文件中也有定义:xPortSysTickHandler(),因此在SysTick中断函数中直接调用该函数即可。

    1. void SysTick_Handler(void)
    2. {
    3. if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED) //系统已经运行
    4. {
    5. xPortSysTickHandler(); //调用port.c中已写好的中断函数
    6. }
    7. }

    三、其他操作配置FreeRTOS的SysTick

    1、找到头文件 FreeRTOSConfig.h 有如下定义。

    1. #define configCPU_CLOCK_HZ ((unsigned long)168000000) //CPU频率
    2. #define configTICK_RATE_HZ (( portTickType )1000) //时钟节拍频率,这里设置为1000,周期就是1ms

    2、搜索 configTICK_RATE_HZ,在port.c中。

    1. portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
    2. portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );

    3、搜索 portNVIC_SYSTICK_CTRL_REG,在port.c中。

    1. #define portNVIC_SYSTICK_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000e010 ) )
    2. #define portNVIC_SYSTICK_LOAD_REG ( * ( ( volatile uint32_t * ) 0xe000e014 ) )

    4、下面证明地址是不是SYSTICK的配置地址。

    STM32库函数中core_cm4.h中配置systick函数为 uint32_t SysTick_Config(uint32_t ticks)

    1. SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
    2. NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
    3. SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
    4. SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
    5. SysTick_CTRL_TICKINT_Msk |
    6. SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
    7. return (0UL); /* Function successful

     5、跳转到 SysTick 定义处。

    1. #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
    2. #define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
    3. #define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
    4. #define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
    5. #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
    6. #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
    7. #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
    8. #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
    9. #define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
    10. #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
    11. #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */

    FreeRTOS学习笔记——SysTick中断-CSDN博客

    STM32使用FreeRTOS时SysTick哪里配置的?_systic在哪配的-CSDN博客

    FreeRTOS 之六 任务调度原理解析(Systick、PendSV、SVC)_freertos svc-CSDN博客

    【STM32/FreeRTOS】SysTick定时器及FreeRTOS系统节拍_freertos systick-CSDN博客

  • 相关阅读:
    汽车信息安全--如何理解TrustZone(1)
    阿里云服务器
    Linux 中的权限
    一起Talk Android吧(第五百五十回:如何适配SplashScreen)
    硬盘长寿十五招
    5原型模式
    如何在 Spring Boot中更改默认端口
    易基因|性别分化:DNA甲基化表观遗传调控性别表型可塑性,诱导斑马鱼性别比例失调
    谈谈如何写作(二)
    2022年推荐算法效率开发必备工具榜单
  • 原文地址:https://blog.csdn.net/AuroraSmith/article/details/134409002