请选择 进入手机版 | 继续访问电脑版
查看: 9144|回复: 24

[分享] [经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

[复制链接]

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
发表于 2014-3-20 10:51:15 | 显示全部楼层 |阅读模式
本帖最后由 FSL_TICS_ZJJ 于 2015-3-17 09:26 编辑


关于Kinetis L系列中断优先级设置问题的解决方案

最近在调试Kinties L系列的时候,使用官方例程中arm_cm0.c,使用其中的void set_irq_priority (int irq, int prio)函数设置了中断优先级,然后仿真的时候,在寄存器窗口发现NVIC_IPRx寄存器的值并没有改变,然后查看寄存器具体的地址的内存发现也没有改变, 后来将NVIC_IPRx寄存器地址的值赋给一个变量,然后使用printf将该变量打印出来,发现第一次能够打印正确的值,但是连续第二次打印,值又变为了0.当时感觉很奇怪,然后仔细阅读了下ARM Cortex-M0的内核文档:The Definitive Guide to the ARM cortex M0.pdf.
发现对于中断优先级的操作,和ARM Cortex-M4还是有区别的:主要在于对于M0+内核的NVIC_IPRx寄存器,每次操作都是一组32位操作,若要改变寄存器的值,首先先要读出相应的值,然后改变一个字节,再将值写回到原来的地址上。
M0内核文档是这么讲的:
1.jpg
图1

M4内核就不一样,是可以字节操作的,这点在M4的内核文档上也可以找到。
所以,我认为,原来arm_cm0.cset_irq_priority (int irq, int prio)函数不能实现优先级正确设置的原因之一,是由于采用了8位操作的方式如下:
uint8 *prio_reg;
prio_reg = (uint8 *)((uint32)&NVIC_IP(div));
*prio_reg = ( (prio&0x3) << (8 - ARM_INTERRUPT_LEVEL_BITS) );  
定义需要修改为:
uint32 *prio_reg;
prio_reg = (unsigned long *)((uint32)&NVIC_IP(div));//div
第二,从原来的代码可以看出,并不能准确的实现具体irq的定位与值的修改。
假设我们需要设置:  set_irq_priority(17, 3);
可以看出,上面错误的代码只能实现irq=16值的修改,原因其只是定位到了NVIC_IPR4中的低字节,而没有在IPR44个字节做偏移,所以只能修改irq=16的优先级
根据我们的reference manual可以知道,在每组IPR中,具体定位IRQ,可以通过8*(IRQ mod 4)+6的方法,注意mod是取余数,程序中是“%”,不要理解为“/”.
综合上面两点,我将set_irq_priority函数修改如下:
void set_irq_priority (int irq, int prio)
{   
    /*irq priority pointer*/
    uint8 *prio_reg;
    uint8 err = 0;
    uint8 div = 0;
    uint32 temp=0;
    uint32 *prio_reg1;
    /* Make sure that the IRQ is an allowable number. Right now up to 32 is
     * used.
     *
     * NOTE: If you are using the interrupt definitions from the header
     * file, you MUST SUBTRACT 16!!!
     */
    if (irq > 32)
    {
        printf("\nERR! Invalid IRQ value passed to priority irq function!\n");
        err = 1;
    }
    if (prio > 3)
    {
        printf("\nERR! Invalid priority value passed to priority irq function!\n");
        err = 1;
    }

    if (err != 1)
    {
        /* Determine which of the NVICIPx corresponds to the irq */
        div = irq / 4;
        prio_reg1 = (unsigned long *)((uint32)&NVIC_IP(div));//div
        *prio_reg1 = ( (prio&0x3) << ((8 - ARM_INTERRUPT_LEVEL_BITS) + 8*(irq%4)));
    }
}
同样以set_irq_priority(17, 3);为例,使用CW测试的结果如下:
2.jpg
3.jpg
回复

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
 楼主| 发表于 2014-3-20 10:52:21 | 显示全部楼层

回复:关于Kinetis L系列中断优先级设置问题的解决方案

给出修改后的arm_cm0.c文件
arm_cm0.rar (1.47 KB, 下载次数: 58)
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
 楼主| 发表于 2014-3-20 10:52:41 | 显示全部楼层

RE:关于Kinetis L系列中断优先级设置问题的解决方案

说的不正确的地方,欢迎大家指正。
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

65

帖子

0

中级会员

Rank: 3Rank: 3

积分
233
最后登录
1970-1-1
发表于 2014-3-20 11:23:05 | 显示全部楼层

RE:关于Kinetis L系列中断优先级设置问题的解决方案

回复可见回复可见
回复 支持 反对

使用道具 举报

该用户从未签到

16

主题

705

帖子

0

金牌会员

Rank: 6Rank: 6

积分
1745
最后登录
1970-1-1
发表于 2014-3-20 14:06:18 | 显示全部楼层

RE:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

回复可见!!!
回复 支持 反对

使用道具 举报

该用户从未签到

16

主题

705

帖子

0

金牌会员

Rank: 6Rank: 6

积分
1745
最后登录
1970-1-1
发表于 2014-3-20 14:07:00 | 显示全部楼层

RE:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

这个之前倒没有去确认过,感谢版主的经验分享。
回复 支持 反对

使用道具 举报

该用户从未签到

10

主题

65

帖子

0

新手上路

Rank: 1

积分
94
最后登录
1970-1-1
发表于 2014-3-23 22:07:45 | 显示全部楼层

回复:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

 看看
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
 楼主| 发表于 2014-3-24 15:27:48 | 显示全部楼层

RE:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

大家也可以直接用keil的库文件arm_cm0.c,这个内核文件写的是正确的。
回复 支持 反对

使用道具 举报

该用户从未签到

145

主题

4926

帖子

0

金牌会员

Rank: 6Rank: 6

积分
9267
最后登录
1970-1-1
 楼主| 发表于 2014-3-24 15:28:51 | 显示全部楼层

RE:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

我们网站上的代码将会在下次的时候更新,并且推出我们的SDK代码。
回复 支持 反对

使用道具 举报

该用户从未签到

16

主题

705

帖子

0

金牌会员

Rank: 6Rank: 6

积分
1745
最后登录
1970-1-1
发表于 2014-3-24 17:46:54 | 显示全部楼层

回复:[经验分享]关于Kinetis L系列中断优先级设置问题的解决方案

回复第 8 楼 于2014-03-24 15:27:48发表:
大家也可以直接用keil的库文件arm_cm0.c,这个内核文件写的是正确的。
 
谢谢斑竹的推荐,看了下,的确那边写的是正确的
 
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2024-3-29 15:57 , Processed in 0.153470 second(s), 29 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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