今天调试三星S3C2440的中断部分,遇到一些问题,也解决了一些问题,希望与大家分享。 我先列写一下三星ARM的中断初始化过程: 1、GPnCON。 对中断口进行设置(默认状态为I/O) 2、EXTINTn(外部中断控制寄存器)。设置外部中断的信号方式,本寄存器仅针对外部中断。 3、EINTMASK,EINTPEND。这两个寄存器针对外部中断,用于使能外部中断,只需要初始化一次。 4、SRCPND,INTPND。针对所有中断。 SRCPND--源中断指示寄存器:32位中的每一位对应着一个中断源,每一位被设置为1,则相应的中断源产生中断请求并且等待中断被服务,因此这个寄存器表明哪个中断源在等待中断请求被处理。不管INTMASK如何设置,当有中断请求时,SRCPND都会自动被置1。在指定的中断源的服务程序中。SRCPND相应的位必须被清除,这样才可以正确的响应同一中断源的中断请求。如果从ISR返回而没有清除相应的位,也就是说SRCPND中对应的还是1,那么就会一直相应这个中断请求。 INTPND--中断请求寄存器:32位中的每一位对应着相应的中断请求,经过优先级逻辑后,INTPND寄存器只能有一位被设置为1。在IRQ中断服务程序中能够读取这个寄存器的值来决定32个中断源的哪一个中断被服务。同SRCPND寄存器一样,在中断服务程序里,这个寄存器的相应位需要被清除。我们可以向INTPND寄存器写一个数据1,来清除寄存器的指定位。 5、将中断服务子程序的入口地址赋给中断向量。CPU在响应中断后首先会跳到中断向量表,中断向量表存放中断服务子程序的函数地址。在ISR中一定要记住第一件要做事情,将SRCPND,INTPND些“1”。
6、INTMASK:中断屏蔽寄存器,默认为中断屏蔽。当你的CPU接收到中断的话,就可以启动ISR了。
在代码的调试中,深入学习了几个知识点: extern的作用 extern关键字的作用是声明变量和函数为外部链接,即该变量或函数名在其它文件中可见。用其声明的变量或函数应该在别的文件或同一文件的其它地方定义,提示编译器遇到此变量和函数时在其他模块中寻找其定义。 仅仅是一个变量的声明,并不分配内存空间。 如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别:extern int f(); 和int f(); 当函数提供方单方面修改函数原型时,如果使用方不知情继续沿用原来的extern申明,这样编译时编译器不会报错。但是在运行过程中,因为少了或者多了输入参数,往往会照成系统错误。目前业界针对这种情况的处理没有一个很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供对外部接口的声明,然后调用方include该头文件,从而省去extern这一步。以避免这种错误。 在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况。C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。 下面是一个标准的写法: //在.h文件的头上 #ifdef __cplusplus #if __cplusplus extern 'C'{ #endif #endif /* __cplusplus */ … … //.h文件结束的地方 #ifdef __cplusplus #if __cplusplus } #endif #endif /* __cplusplus */
|