SysTick的优先级是高还是低
来源:互联网 发布:论坛社区源码 编辑:程序博客网 时间:2024/04/28 18:35
SysTick系统嘀嗒定时器并非STM32独有的,它是Cortex内核的部分,CM3为它专门开出一个异常类型,并且在中断向量表中占有一席之地(异常号15)。这样它可以很方便的移植到不同厂商出CM3内核的芯片上,尤其对于有实时操作系统的软件,它一般会作为整个系统的时基,所以这个对操作系统非常重要。
但在STM32开发手册中对它的介绍却很少,几乎到一笔带过的程度。有关SysTick的详细介绍可参考《Cortex-M3权威指南》第133 页第八章及第179页第十三章。
刚接触SysTick时,因它属于内核中断优先级,我一直有个疑问,它是比所有的可屏蔽中断优先级都高呢还是都低,或是处在等同设置地位 ?
最初我自以为内核中断优先级要比所有可屏蔽中断优先级高,当认真查阅资料与做实验后,发觉并非如此。
SysTick总共有四个寄存器:
1、
此寄存器在系统代码中由 SysTick->CTRL变量表示;
2、
此寄存器在系统代码中由 SysTick-> LOAD变量表示;
3、
此寄存器在系统代码中由 SysTick-> VAL变量表示;
4、
此寄存器在系统代码中由SysTick-> CALIB 变量表示,没有用过,也不常用,暂不作介绍。
这几个寄存器的偏移量如下图所示:
上面寄存器结构体的定义在 \CMSIS\CM3\CoreSupport core_cm3.h中如下所示:
/
**@addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick
memory mapped structure
for
SysTick
@{
*/
typedef
struct
{
__IO uint32_t CTRL;
/*!< Offset: 0x00 SysTick Control and Status Register */
__IO uint32_t LOAD;
/*!< Offset: 0x04 SysTick Reload Value Register */
__IO uint32_t VAL;
/*!< Offset: 0x08 SysTick Current Value Register */
__I uint32_t CALIB;
/*!< Offset: 0x0C SysTick Calibration Register */
} SysTick_Type;
SysTick 是一个24 位的定时器,即一次最多可以计数 224个时钟脉冲,这个脉冲计数值被保存到SysTick->VAL 当前计数值寄存器中,它只能向下计数,每接收到一个时钟脉冲SysTick->VAL 的值就向下减 1,直至0,然后由硬件自动把重载寄存器SysTick->LOAD 中的值到SysTick->VAL重新计数,并且当SysTick->VAL值计数到0时,触发异常,调用void SysTick_Handler(void)函数,可以在此中断服务函数中处理定时中断事件了,一般是对设定值进行递减计数操作。只要不把它在SysTick控制及状态寄存器SysTick->CTRL中的第0位使能位清除,就永不停息。
它属于系统异常,是内核级中断,并且优先级是可以设置的,具体设置也是在 core_cm3.h中代码如下:
/**
* @brief Initialize and start the SysTick counter and its interrupt.
*
* @param ticks number of ticks between two interrupts
* @return 1 = failed, 0 = successful
*
* Initialise the system tick timer and its interrupt and start the
* system tick timer / counter in free running mode to generate
* periodical interrupts.
*/
static
__INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if
(ticks > SysTick_LOAD_RELOAD_Msk)
return
(1);
/* Reload value impossible */
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
/* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return
(0);
/* Function successful */
}
在此段代码中,优先级的设置是通过NVIC_SetPriority()函数实现,此函数对内核中断优先级和外部中断优先级设置都可以,比较强大,但需要手动算出来抢占和从优先级,不太方便,当跳进此函数,我们可以算出Systick默认优先是最低的(效果相当于SCB->SHP[11] = 0xF0,如果你推算下,SHP[11] 正好对应于Systick优先级的设置);对于可屏蔽中断,优先级的设置一般通过 NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)函数来实现,具体应用可参考下面的示例代码。
当介绍完了理论后,发现还是没有搞清楚最初的疑惑!现在就做实现来揭示真相。
先设置一事件中断,把优先级设置高一些,
void
Exti_Config(
void
)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
注:中断分组我在实验中,最初初始化设置为如下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
设为第二组。
在系统滴答中断里触发外部中断事件,并点亮LED1 :
void
SysTick_Handler(
void
)
{
EXTI_GenerateSWInterrupt(EXTI_SWIER_SWIER1);
LED_1 = ON;
Delay();
}
外部中断处理函数中点亮LED0,如下:
void
EXTI1_IRQHandler(
void
)
{
if
(EXTI_GetITStatus(EXTI_Line1) != RESET)
{
EXTI_ClearITPendingBit(EXTI_Line1);
LED_0 = ON;
Delay();
}
}
当外部中断优先级比较高时,它可以抢占Systick中断先执行,以上代码实验结果为,LED0先点亮后,再回到LED1再点亮。
但当把外部中断设置为与systick相同的优先级时,则systick优先级就会相对较高,例如把上面的优先级改为:
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
则会LED1先亮,执行完SysTick_Handle函数后才轮到EXTI1_IRQHandler执行。
由以上实验可得出,当优先级相同时,内核级中断要优先于外部可屏蔽中断执行,但设置外部可屏蔽中断优先级大于内核级中断时,它是可抢占内核中断的。
另外,个人认为,若要实现systick精确延时,最好把systick优先级设置高一些,如 NVIC_SetPriority (SysTick_IRQn, 0);
即把SCB->SHP[11] = 0x00;则可达到systick优先级高于任合外部中断的效果,此时延时会更少被其它中断干扰,会更加精准。
- SysTick的优先级是高还是低
- SysTick的优先级是高还是低
- 怎样判断机器的字节顺序是高字节在前还是低字节在前?
- 如何判断机器的字节顺序是高字节在前还是低字节在前
- 人们买不起房子是因为房子价格太高,还是因为我们的工资太低
- 在训练网络的时候,验证集误差是比测试集误差低还是高? | 社区问答
- 在训练网络的时候,验证集误差是比测试集误差低还是高? | 社区问答
- STM32的systick的中断优先级
- 你比Java的平均薪资高还是低?
- 低门槛究竟是深度学习的危机,还是契机?
- leetcode_374. Guess Number Higher or Lower 猜数字是比给定的数字高了还是低了,二分查找法
- 创业门槛高了还是低了?
- stm32滴答时钟SYStick的优先级设定方法详解
- cocos2d-x中数值越低,优先级越高。
- 高三,是与信息再见,还是新的旅程?
- MFC中setimer和ontimer定时器函数到时间不能触发执行是因为WM_TIMER消息的优先级低
- 高版本的JavaCV是可以调用低版本的openCV的
- 思考:你是高薪水低价值的老IT人吗?
- 圆轨迹弧度计算方法
- codevs1183 泥泞的道路 图论+奇怪的东西[四星]
- 如何为Eclipse安装主题(Color Theme)
- spring事务
- IE内存溢出报错Stack overflow at line
- SysTick的优先级是高还是低
- 「Python」利用OpenGL作渲染以及离屏渲染
- Deterministic vs Probabilistic Model
- 第九章 虚拟存储器
- 实体bean实现序列化parcelable接口的常见问题
- GCD之主队列、全局并发队列、以及同步任务的执行
- linux c strtol 函数解析
- Bezier曲线绘制方法
- HDU 1072 Nightmare