OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3103|回复: 5

systick 滴答中断优先级的问题

[复制链接]

12

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-3-15
在线时间
66 小时
发表于 2018-4-11 15:00:51 | 显示全部楼层 |阅读模式
20金钱
本帖最后由 lijing150123 于 2018-4-11 15:08 编辑

需要使用滴答来为lwip提供一个系统时钟,lwip用的是1.3.1版本(直接用的官方例程,换4.1比较麻烦,而且工程已经搭建好了,不想动这一块),官方有句代码不是很理解。[mw_shl_code=c,true]  /* Update the SysTick IRQ priority should be higher than the Ethernet IRQ */
  /* The Localtime should be updated during the Ethernet packets processing */
  NVIC_SetPriority (SysTick_IRQn, 1); [/mw_shl_code]
把滴答设成了每隔10ms一次中断,每次中断加一个将localtime+20,贴代码[mw_shl_code=applescript,true]void Time_Update(void)
{
  LocalTime += SYSTEMTICK_PERIOD_MS;
}[/mw_shl_code]
前一段的解释是把滴答的优先级设置为比eth的中断优先级要高,以便localtime能够及时更新。我不理解的是按照CM3的中断优先级顺序,systick本来的优先级就比eth要高啊,为什么要加这一句话,原来的代码里面中断优先级分组是2,然后把eth的抢占优先级设为2,我现在把eth的中断优先级改成了0,现在会出现ping一段时间之后就ping不通了,但是单步跟踪进去又会正常,跟踪不出来问题(中断比较多,按原来工程设置为2的话,抢占不够用,所以还需要改),怀疑是中断优先级设置的问题,这句话到底应该怎么理解

最佳答案

查看完整内容[请看2#楼]

终于搞懂了,记录一下,方便以后查看。 首先看CM3的内容: CM3支持中断嵌套,高优先级异常可以抢占低优先级异常,原则上,CM3最少支持3个固定优先级和256级可编程优先级(CM3优先级分组规定,子优先级最少要占一位,所以实际可配置的抢占优先级只剩128级了,但是不晓得为什么stm32没有这个规定,最低可以用0位子优先级),这个优先级分组是靠着AIRCR寄存器决定的,这是一个8bit的寄存器,优先级以MSB对齐(便于跨器件的移植,后 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-3-15
在线时间
66 小时
 楼主| 发表于 2018-4-11 15:00:52 | 显示全部楼层
终于搞懂了,记录一下,方便以后查看。
首先看CM3的内容:
CM3支持中断嵌套,高优先级异常可以抢占低优先级异常,原则上,CM3最少支持3个固定优先级和256级可编程优先级(CM3优先级分组规定,子优先级最少要占一位,所以实际可配置的抢占优先级只剩128级了,但是不晓得为什么stm32没有这个规定,最低可以用0位子优先级),这个优先级分组是靠着AIRCR寄存器决定的,这是一个8bit的寄存器,优先级以MSB对齐(便于跨器件的移植,后面会讲到),所以CM3最少支持8级可编程的优先级。
而stm32使用了4位中断优先级,这样就一共有16个可编程的优先等级(最低0位子优先级,这样抢占最多可以达到16级)。这时候,片上一共68个可屏蔽的中断通道加上内核的16个中断线(不包含RESET,NMI和硬fault,这三个是固定的,可以跨越所有的其他异常)都可以由你来指定到底这些中断要划分为几个层次,,这里用到了两个寄存器,AIRCR寄存器和IP寄存器(中断优先级控制寄存器)来决定的(AIRCR寄存器参考CM3),IP寄存器是一个8bit的寄存器组,stm32只用到了前68个组,其中这8bit并没有被全部使用,而是又被分成了高4位和低4位。实际只使用了高4位,这4位又被分成了抢占优先级和子优先级,具体抢占和子优先级各占几位,要由AIRCR寄存器决定,也就是一旦你设置好了优先级分组,你就知道你的中断被划分成了多少个等级了。
抢占优先级和子优先级共同决定了优先级的编号[mw_shl_code=c,true]          /* 2 bit for pre-emption priority, 2 bits for subpriority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
       
        /* Enable the USART2 global Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;          
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;       
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);[/mw_shl_code]
这样设置的话,USART2_IRQn的优先级编号就是15。可以用NVIC_GetPriority()验证一下。

回到我一开始问的问题[mw_shl_code=c,true] * Set the priority for the specified interrupt. The interrupt
* number can be positive to specify an external (device specific)
* interrupt, or negative to specify an internal (core) interrupt.
*
* Note: The priority cannot be set for every core interrupt.
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if(IRQn < 0) {
    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
  else {
    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts  */
}[/mw_shl_code]
这个函数为什么允许传入负数,我自己试了一下,其实不试也能猜出来,因为用get获取中断优先级编号的时候返回的是一个无符号的整数,而AIRCR寄存器是高字节对齐的,顶多就是你想配置最高级别的中断,结果配成了最低的呗,但是这个函数注释比较令人疑惑,传入负数指定一个core中断,应该不是内核中断的意思吧
回复

使用道具 举报

12

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-3-15
在线时间
66 小时
 楼主| 发表于 2018-4-11 15:14:54 | 显示全部楼层
更改systick中断优先级顺序的函数跟踪进去是这样[mw_shl_code=c,true] * Set the priority for the specified interrupt. The interrupt
* number can be positive to specify an external (device specific)
* interrupt, or negative to specify an internal (core) interrupt. \n
*
* Note: The priority cannot be set for every core interrupt.
*/
static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if(IRQn < 0) {
    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */
  else {
    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts      */
}[/mw_shl_code]

CM3权威手册中,systick是属于可编程的系统异常,这个函数也很奇怪啊,注释里面的意思是可以把中断号设成负数,使其成为内核中断吗?像第一句把中断号设为1是使systick成为外部中断了吗
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-4-12 00:31:45 | 显示全部楼层
systick就是属于系统中断的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-3-15
在线时间
66 小时
 楼主| 发表于 2018-4-12 11:41:19 | 显示全部楼层
本帖最后由 lijing150123 于 2018-4-12 11:43 编辑

居然被原子哥临幸。看了半天CM3的内核资料,还是不太懂,系统中断本来优先级就比外部中断要高,为什么要加这一句话呢?把systick的中断标号设置为1,那他的优先级顺序到底是怎么排列的,是指除了reset,nmi和硬fault之后,优先级最高的就是systick了吗,那中断优先级分组里面的抢占优先级序号和这个标号有什么关系?我已经lwip的时钟基准改成定时器提供了,改用查询的方式,还是不用这个中断了,搞不清这个概念
回复

使用道具 举报

12

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
111
金钱
111
注册时间
2016-3-15
在线时间
66 小时
 楼主| 发表于 2018-4-12 15:58:22 | 显示全部楼层
当然,我还是不理解为什么要去设置一下systick中断的优先级,系统中断优先级本来就比外部中断高不是吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 04:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表