×
单片机 > 单片机程序设计 > 详情

S3C2410的中断过程中保存和还原现场问题分析

发布时间:2020-05-28 发布时间:
|

在我的一个中断处理例程中有一下一段:

          save_flags(flags);
          cli();
          set_gpio_mode_user(k->gpio_port, GPIO_MODE_IN);
          up = read_gpio_bit(k->gpio_port);
          set_external_irq(k->irq_no, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);
          restore_flags(flags);

我有若干问题问各位大虾:

1.关于save_flags和restore_flags的源代码的阅读,可以知道他们的作用是保存和还原现场。但是具体在什么时候应该保存,什么时候还原现场。

2.关于cli(),他是作为关中断而起作用的,但是在后面为什么会没有sti()进行开中断。

3.在这里,set_external_irq(tmp->buttons_int_irq, EXT_BOTH_EDGES, GPIO_PULLUP_DIS);难道可以起到开中断的作用,因为前面有cli的操作。


说说我的看法:
使用save_flags()等的原因是:如果在这个函数之前已经禁止了中断,那么就会出现一定的危险,因为在以后调用开中断的时候,它会无条件地激活中断,所以需要一种机制把中断恢复到以前的状态而不是简单地禁止或激活. 
后面之所以没有sti()是因为后面调用了restore_flags(),就恢复到了以前的状态了!
S3C2410中的cpsr的低八位可以实现中断的开启和关闭的作用.

原先一次save_flags()实际上是保存了原来的CPSR的数值
而后cli关中断

最后的restore_flags()就是开中断,因为我们保存了原先的flags.



类UNIX系统一直采用cli和sti函数来禁用和启用中断。而在现代的Linux系统中却不鼓励直接使用它们。
如果必须禁用中断,那么最好使用下列调用:
unsigned    long    flags;
save_flags(flags);
cli();
/*下面的代码在中断被禁用的情况下运行*/
restore_flags(flags);

其中save_flags是一个宏,用于保存标志的参数flags被直接传入,不带&操作符。

另外中断处理的顺序一般是:
1. 保存现场 
2. 关中断
3. 执行中断处理Makefile文件:
4. 开中断并恢复现场

最近在写linux驱动.遇到这么一个问题:
: 有这么一个函数 __raw_readl. 我查了他的原型是:
: #define __raw_readl(a)        (__chk_io_ptr(a), *(volatile unsigned int
: __force     *)(a))
: 而__chk_io_ptr(x)的原型是
: #ifdef __CHECKER__
: extern void __chk_io_ptr(void __iomem *);
: #else
: # define __chk_io_ptr(x) (void)0
: #endif
: __raw_readl(23)展开以后就是((void)0,*(volatile unsigned int _force *)(23)). 
: 请问上面的展开式式什么意思???我所不理解的是(xx, xxxxxx)这样的语法是什么意思?

只有后面这个表达式是有效表达式
上面等同,*(volatile unsigned int _force *)(23);


关键字:S3C2410  中断过程  保存  还原 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
TQ210天嵌开发板S5PV210 LED闪烁程序C语言代码记录