原文地址http://blog.csdn.net/Ricky_hu/archive/2009/02/22/3923340.aspx
最近在做系统的电源管理以及系统底电流的调试工作,要求在系统进入suspend的时候耗电电流在几个mA以内。其中有一个耗电比较大的模块,我想在系统进入suspend的时候将它的驱动卸载,系统resume的时候再重新给它加载,本来这种方式之前用过很多次了,应该没有什么问题,唯一让我担心的是这个驱动比较复杂,有很多线程在跑,担心卸载的时候一些资源没有释放或者释放顺序有问题导致第二次不能够加载成功。但是随着调试的进行,对该驱动的卸载和加载似乎很顺利,重新加载后通过SPI接口成功的将firmware下载到了芯片中,但是随之也出现了问题:芯片工作不正常,反应很慢,好像是数据处理不过来,导致底层的接收缓冲区满了。最后通过示波器检测发现,第二次加载后,虽然firmware下载成功了,但是当有数据需要处理的时候,芯片却不给CPU发送中断信号,或者中断信号非常少,数据没有被及时的取走从而导致了缓冲区的溢出。这就让我开始郁闷了,firmware都下载成功了,SPI通信应该没有问题吧,芯片不给cpu发中断,那是芯片有问题,或者是firmware工作不正常啊......
于是一天天的调试,还找芯片供应商的FAE也过来帮忙查找问题。因为芯片驱动的sample是供应商给的,我们把它重新移植了一下,之前不卸载的时候工作一切正常。但是不应该卸载了再加载就工作不正常啊,更何况第二次加载也没报任何错误,firmware还下载成功了,芯片的上电、下电时序也满足spec啊。郁闷ing...
后来,我查看之前的一个驱动的deinit函数,发现它里面不但把系统中断给disable了,而且还调用KernelIoCtl将这个系统中断给释放了,看到这个释放,我一下子顿悟了:是我忘记释放系统中断号了。我只是在deinit的时候把系统中断给disable了,但是这个系统中断还存在于系统中,而InterruptDisable禁掉的只是硬件GPIO中断,在我第二次加载驱动的时候,这个GPIO中断我还会给它Enable,同时我也会重新申请一个系统中断号,这样,一个GPIO的IRQ就对应了2个系统中断号了,于是问题就出来了:芯片发送过来的中断cpu接收不到或者只能接收一部分,从而导致异常。
解决办法:
1.对于动态申请的系统中断,在卸载驱动的时候不但要disable系统中断和GPIO IRQ,而且还要释放该系统中断。
2.如果不愿意释放,可以将该中断做成静态映射的,这样的话这个GPIO对应的系统中断就是固定的,无论你加载卸载多少次,这个系统中断号都不会变,也不需要你去释放和重新初始化。
Add by Hzh---2009.02.22 21:05
看了本文感受
DeInit函数中不释放中断会造成什么后果?
刚才无意中在HZH的博客看到了一些信息,我的中断号在DeInit函数也是没有释放的。奶奶的。难怪我卸载驱动之后再次重新加载驱动之后不会产生中断了呢?原来是一个中断对应了两个系统中断,甚至几个,我想我这样休想使用wince串口调试助手了。哈哈。经验啊。教训啊。以前我一直纳闷这是什么原因。