云计算百科
云计算领域专业知识百科平台

【FreeRTOS】刨根问底1: SysTick在FreeRTOS上咋工作的

    有些事吧,你不去深究,还真是闹心!搞明白了,吃到嘴了,也就没有遗憾了。你说别人搭建移植好的东西,你再去研究还有什么意义呢?错!吃透高手的代码,就等于汲取了高级技能的营养!话不多说,开搞…

    

一、SysTick什么玩意?

    它是ARM设计CPU架构时就带的一个定时器,它可不是芯片设计公司给的TIMx啊,它在CPU上集成的设备,不是片上外设!

    《Cortex-M4 Devices Generic User Guide》 4.4节中就有描述:

    SFR:控制与状态在0xE000E010,重载数值寄存器在0xE000E014,当前计数值寄存器0xE000E018,还有一个修正寄存器0xE000E01C。它们怎么配置的我们暂且不提,我们只说它们在系统中怎么用的!

二、SysTick的定义与使用

    1、SysTick寄存器组结构体声明:Core/CMSIS/Core/Include/core_cm4.h

typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;

    看,结构体中定义的是uint32_t,正好4个字节的offset,与SFR在地址总线上的地址分布正好匹配!

   __IOM&__IM又是什么?Core/CMSIS/Core/Include/core_cm4.h

/* following defines should be used for structure members */
#define __IM volatile const /*! Defines 'read only' structure member permissions */
#define __OM volatile /*! Defines 'write only' structure member permissions */
#define __IOM volatile /*! Defines 'read / write' structure member permissions */

  声明的是易变量常量与易变量【相关代码不要被优化掉啊~~~】

    2、SFR结构体指向物理地址基地址:Core/CMSIS/Core/Include/core_cm4.h

#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */

SysTick_BASE又是什么?


#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */

#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */

    是不是明朗了?

    3、SysTick的初始化:Core/CMSIS/Core/Include/core_cm4.h

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks – 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}

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

    通过控制寄存器配置SysTick的工作模式,通过计数与重载特殊功能寄存器配置初始与重载值!当然还有NVIC的优先级配置!

    SysTick_CTRL_CLKSOURCE_Msk 这样的宏又是干什么的?

/* SysTick Control / Status Register Definitions */
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */

#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */

#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */

#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */

    就是CPU 用户指导手册中对SFR个控制位组合的数值定义抽象!!!

    4、SysTick与FreeRTOS的对接:stm32f4xx_hal_cortex.c

uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
{
return SysTick_Config(TicksNumb);
}

    咋样,是不是从硬件底层被逐级抽象出来了?

    5、应用又是怎么初始化的呢?main.c

void SystemClock_Config(void)
{

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

}

    是不是豁然开朗了呢?写了这么久的SystemClock_Config,到底都干了啥,这回心里清楚了不?

三、引申

    STM32Cube库整体的底层到HAL层的抽象过程,都类似于上述的过程,它封装了底层的硬件控制、状态查询与数据交互的细节过程,让用户专注于顶层的设计与实现!但,有些时候,掌握好HAL层以下的设计实现原理跟重要!你细品…

赞(0)
未经允许不得转载:网硕互联帮助中心 » 【FreeRTOS】刨根问底1: SysTick在FreeRTOS上咋工作的
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!