0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一个有关SYSTICK好奇的问题

麦辣鸡腿堡 来源:茶话MCU 作者:茶话MCU 2023-06-21 15:48 次阅读

前不久在研究SYSTICK有关问题阅读相关技术资料时,无意间产生了个小疑惑。

问题是这样的,我们知道SYSTICK定时器是个24位向下计数器,每当发生从1记到0时会让一个名为COUNTFLAG的标志位置1,如果此时SYSTICK的滴答中断请求使能了的话,可以对CPU发起中断请求。

根据我们平常STM32的开发经验,通常各种外设事件发起中断请求时,往往有相应的事件标志跟中断响应关联,在中断服务程序里并将相关事件标志做清零操作,否则它会没完没了地发起中断请求。基于这点,我想这个COUNTFLAG标志应该也是跟SYSTICK中断密切相关,溢出时被置位,在SYSTICK中断服务程序里将其清零。

可是,我们平常的SYSTICK的中断服务程序里根本没看到哪里有对COUNTFLAG标志做清零。ARM

Cortex内核手册针对COUNTFLAG标志的描述中涉及它可以清零的地方有两处:

第一个地方是在SYSTICK控制寄存器【SYST_CSR】里有介绍,读它可以清零。说实在的,这点我是通过咨询ARM公司才理解到位的。第二个地方是在介绍SYSTCIK的当前计数器寄存器时提到,即对当前计数器寄存器进行写操作时也会将COUNTFLAG标志清零。

问题是平常的SYSTICK的中断服务程序里根本就没有涉及到上面提到的可能对COUNTFLAG标志清零的操作啊?!既没有读SYSTICK控制寄存器,也没有对计数器做写操作。那这个标志啥时候被清零的呢?如果不清零的话,难道不会没完没了地申请中断,可现在的实践结果又不是这样的!

后来,找同事咨询、讨论,有同事说他印象中计数器重装时会将该标志清零。如果说重装可以清COUNTFLAG的话,这样可以很好地解释目前的结果。因为既然每次重装可以清零,自然用不着到中断服务程序里再做清零,那么在中断服务程序里见不到对COUNTFLAG的清零操作也就再正常不过了。也因此一时以为找到了答案。可后来一想,还是有些不对劲的地方。至少有2点说不通。

第一、如果是重装时清零,该标志是溢出时被置1的,而溢出和重装两个动作可以看成同一时刻完成,即置位后马上被清零。这样的话,用户永远没有机会见到该标志为1的时候。何时能被软件用得上呢?定义这个标志意义何在呢?

第二、关于这个标志,在ARM 内核手册里还说了一句话

意思就是说用户软件可以通过查看COUNTFLAG标志来确认SYSTICK之前有发生过溢出。如果重装可以清零的话,用户软件是不可能有机会读到该标志为1的时候。也就是说重装清零结论跟这句话是矛盾的。

经过与同事的来回讨论,以及查找其它相关信息,后来认为这个标志可能跟中断没有必然关系。这个过程中我也意识到我提出这个标志哪里清零的问题,可能是先入为主的惯性思维在作怪。具体点说,我们认为这个COUNTFLAG标志在发生溢出时置位没问题,前面提到的两种情形下会被清零也没问题。但是,SYSTICK的滴答中断不跟这个标志位关联,它只与计数器发生从1计到0的事件有关,即手册中下面绿色方框框住的这句话。

说实在的,这句话我老早就看到了,只是觉得溢出做为中断触发条件没错,但一门心思老纠结着哪个地方对COUNTFLAG清零了。

如果说COUNTFLAG只是个溢出事件标志,滴答中断不跟它关联也是可以理解和接受的。首先,根据ARM手册描述来理解这个结论没有问题,没有说不通的地方,然后,实现逻辑上也没啥问题,反正溢出一次就申请一次中断。

聊到这里,很多STM32用户【包括本人在内】可能会觉得有点别扭或不习惯,这点我们下面继续聊。我就我们针对COUNTFLAG标志跟SYSTICK中断的关系的理解,说得直白点就是SYSTICK中断跟COUNTFLAG有无关系、服务程序里要不要清零再次找ARM公司做了确认,他们完全认同我们的理解。即COUNTFLAG只是个溢出事件标志,SYSTICK中断不跟它关联,只与计数器溢出事件本身关联,并不关心COUNTFLAG的值是0还是1。到此,关于COUNTFLAG要不要在服务程序里清零的疑惑算是尘埃落定。

但是------

用过STM32外设事件申请中断的人应该很清晰地知道,要想各个外设事件中断申请能得到响应的话,除了NVIC端接受响应、外设端允许申请中断外,还得有相应的事件发生【包括软件方式】以及对应的事件标志被置位【或者说应该有效】,中断服务程序跟相应事件标志直接相关,即发生中断响应时中断事件标志必须有效,并需在中断服务程序里对标志清零,否则会没完没了地申请中断、响应中断。显然,这个过程跟前面SYSTICK中断有点不一样。SYSTICK中断虽然设置了溢出事件标志,但其中断并没有跟该标志关联起来。事实上这样运行起来也没有任何问题,那么ST设计的外设申请中断怎么非要跟标志位关联在一起呢?我们平常做STM32开发时,有时因为疏忽或原理不够清晰,没及时清零中断请求标志让CPU没完没了地进中断而陷入异常。

why?

整体上,STM32微控制器是由ARM处理器和ST外设集成而来,ARM

处理器又包括内核、核外设【以示区别于ST公司设计的外设】。其中SYSTICK、FPU、MPU、NVIC等均属于核外设。也就是说,SYSTICK是ARM的外设,不是ST设计的。既然这样,难道只是设计思路上的差异?但是,SYSTICK中断可以不跟事件标志关联起来,可以行得通,为什么ST不也这样设计呢?

一起来看看,尝试找找原因。

原因在于SYSTICK外设就一个溢出事件可以申请中断,在NVIC那边独立对应一个中断请求号【IRQ#],所以CPU在响应SYSTICK中断时根本无需关注那个溢出标志,有那个溢出事件就够了,因为除了这个溢出事件没别的事件来申请TICK中断。
而ST的外设申请中断时就没有SYSTICK那么好的福分了。往往是一个外设的多个事件共用1个中断请求。比方以上面STM32G4系列ADC3的中断来看,因为它只有1个中断申请号,在CPU看来就一个中断入口,即所有ADC3相关事件触发的中断共用一个中断服务程序入口,但可以申请中断的事件可多了,见下图【我后面把能触发同一中断请求的事件称之为兄弟事件】:

再以SPI3和LPTIM1的中断为例,它俩也各只有一个中断请求号,同样可以申请中断的事件也不少。

显然,ST设计的外设不能照搬SYSTICK的玩法。如果中断服务程序不跟触发事件标志关联起来,进了中断就不知该基于哪个事件来运行程序;基于某个事件运行了中断服务程序若不对它清零【包括读清零、写清零等】,等兄弟事件触发再进来时如何分得清哪是过时事件、哪是新触发的即时事件?

或许有人会说,为什么不给每个ST外设事件都安排一个中断请求号呢?这要考虑到必要性和中断请求号的有限性。不难理解必要性并不强,目前ST的设计其实没有啥不合理的地方。另外,内核开放的中断请求号数目是也有限的,视不同内核而定。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2240

    文章

    10675

    浏览量

    348868
  • 控制
    +关注

    关注

    4

    文章

    997

    浏览量

    122153
  • Systick
    +关注

    关注

    0

    文章

    62

    浏览量

    12952
收藏 人收藏

    评论

    相关推荐

    有关systick问题

    按照3.5库函数测试systick,发现所设置的延时与预期的不对。原本预期是1s灯转换次状态,但实际上是9s左右转换次。程序如下,求指点:void
    发表于 06-09 21:50

    请问有关SysTick的几个函数在哪个文件里?

    请问有关SysTick的几个函数在哪个文件里?只在misc.c文件里看到SysTick_CLKSourceConfig();函数源代码,谢谢!
    发表于 11-01 16:51

    如何将systick计数器用于中断定时,作为系统时间

    在这个论坛上用原子的开发板也学习了许多,谢谢大家!以下更改,如果有更好的实现方法,请指正!更改的目的是为了将systick计数器用于中断定时,作为系统时间,开机后不停运行,将来可以作为
    发表于 05-21 04:35

    STM32_SysTick—系统定时器 精选资料分享

    SysTick 的简介和寄存器的详细描述。因为 SysTick 是属于CM3 内核的外设,有关寄存器的定义和部分库函数都在 core_CM3.h 这个头文件中实现。所以学习 SysTick
    发表于 08-19 09:17

    有关SysTick定时器基础知识

    SysTick定时器基础知识SysTick定时器是简单的定时器,CM3和CM4内核芯片都有SysTick定时器。
    发表于 08-19 07:35

    有关SysTick相关的介绍

    SysTick定时器是内核级别的,这个定时器很简单,主要用来延时和用作实时系统里面的心跳时钟可以节省单片机资源,SysTick定时器就是系统滴答定时器,是24位的倒计数定时器,当
    发表于 08-19 06:26

    浅析STM32 SYSTICK及延时函数

    STM32 SYSTICK及延时函数详解SysTick定时器SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要
    发表于 08-19 07:37

    介绍简单的系统定时器Systick

    STM32系列中m3内核中包含了简单的系统定时器Systick,计时方式采取向下计数,计数容量为24位。关于Systick主要有四32
    发表于 02-24 06:17

    如何使用STM32实现systick的精确延时

    SYSTICK寄存器初始化 void SysTick_Configuration(void) { if (SysTick_Config(SystemCoreClock / 100
    发表于 11-21 15:54 5714次阅读

    STM32的SysTick时钟源是来自Cortex系统定时器吗?

    初始化调用这段代码之后,SysTick将会实现1ms中断一次。这段代码实现1ms中断一次相信大家都能理解,但是这里SysTick初始化和上面说的时钟『/8』有关系吗?
    的头像 发表于 04-03 13:54 5199次阅读
    STM32的<b class='flag-5'>SysTick</b>时钟源是来自Cortex系统定时器吗?

    STM32_SysTick—系统定时器

    SysTick 的简介和寄存器的详细描述。因为 SysTick 是属于CM3 内核的外设,有关寄存器的定义和部分库函数都在 core_CM3.h 这个头文件中实现。所以学习 SysTick
    发表于 12-23 19:56 2次下载
    STM32_<b class='flag-5'>SysTick</b>—系统定时器

    好用的SYSTICK

    好用的Systick在core_cm3.h和core_cm4.h头文件里边都有Systick滴答定时器的配置函数。/** * @brief Initialize and start
    发表于 01-14 12:11 0次下载
    好用的<b class='flag-5'>SYSTICK</b>

    stm32之SysTick的理解(NVIC)

    1、SysTick的介绍 SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统
    发表于 02-11 15:39 5次下载
    stm32之<b class='flag-5'>SysTick</b>的理解(NVIC)

    SysTick时钟

    Cortex-M3内核的处理器,内部包含了一个SysTick定时器,SysTick是一个24位的倒计数定时器,当计数到0时,将从ReLoad寄存器中自动重装载定时初值,开始新一轮计数。只要不把它在SysTick控制及状态寄存器中
    的头像 发表于 03-01 17:40 554次阅读
    <b class='flag-5'>SysTick</b>时钟

    关于SYSTICK的COUNTFLAG标志的小疑惑

    前不久在研究SYSTICK有关问题阅读相关技术资料时,无意间产生了个小疑惑。
    的头像 发表于 03-26 14:48 762次阅读