WINCE下SOS驱动开发
********************************LoongEmbedded************************
作者:LoongEmbedded(kandi)
时间:2011.03.30
类别:WINCE驱动开发
********************************LoongEmbedded************************
备注:系统是WINCE4.2移植过来的BSP包+S3C2440A
1. SOS
S.O.S.是国际莫尔斯电码救难信号,并非任何单字的缩写。鉴于当时海难事件频繁发生,往往由于不能及时发出求救信号和最快组织施救,结果造成很大的人员伤亡和财产损失,国际无线电报公约组织于1908年正式将它确定为国际通用海难求救信号。这三个字母组合没有任何实际意义,只是因为它的电码“ ...---...”(三个圆点,三个破折号,然后再加三个圆点)在电报中是发报方最容易发出,接报方最容易辨识的电码。
我们产品的SOS的需求是用户(比如说司机)在需要求救的时候,按下SOS键(按下3s),然后驱动告诉应用程序,而应用程序这时候就可以拨号求救(那对应的号码可以预先设定),这就是我们产品SOS的需求和设计思想。
2. SOS的硬件检测
SOS按键的设计部分:
图1
CPU的GPG10作为SOS检测引脚
图2
3. SOS软件的实现
3.1 SOS中断检测的实现
因为GPG10是作为SOS按键检测引脚的,所以可以利用GPG10的中断功能来检查到是否按下SOS按键,因为SOS键没有按下时,引脚SOS_DET是低电平,按下SOS键后事高电平,大概2.95V左右,所以可以把GPG10配置为EINT18中断功能引脚,并且设置为上升沿触发,也即按下SOS按键时触发,相应的实现代码:
⑴ SMDK2440/SRC/INC/oalintr.h静态定义EINT18对应的逻辑中断号
图3
⑵ 把GPG10配置为上升沿触发的中断引脚
图4
⑶ SMDK2440/SRC/KERNEL/HAL/ARM/armint.c下的OEMInterruptHandler()添加对EINT18中断处理的支持
图5
⑷ SMDK2440/SRC/KERNEL/HAL/ARM/armint.c下的OEMInterruptEnable ()添加对EINT18中断处理的支持
图6
⑸ SMDK2440/SRC/KERNEL/HAL/ARM/armint.c下的OEMInterruptDisable ()添加对EINT18中断处理的支持
图7
⑹ SMDK2440/SRC/KERNEL/HAL/ARM/armint.c下的OEMInterruptDone ()添加对EINT18中断处理的支持
图8
3.2 SOS中断IST线程
图9
在此学习一下IsAPIReady函数的功能
图10
3.3
4. SOS驱动调试遇到的问题
4.1 没有按下SOS按键的时候SOS_DET引脚的电平是1.3V左右
根据图1和图2的设计思路,在没有按下SOS键的时候,SOS_DET引脚的电平应该是接近0v的,但实际用万用表测出来时1.3v左右,这样CPU就认为此时为高电平,而按下按键的时候SOS_DET引脚的电平时2.95V左右,那么就会出现不管是否按下SOS按键,CPU都认为是高电平,也就是认为SOS键一直处于按下的状态,这样就不能使用EINT18的上升沿中断触发功能。
刚开始我一直以为是硬件设计的问题,可是硬件同事一时也不知道问题在哪里,我就试着在SOS_EnableInterrupt函数中把GPG10的上拉功能关闭掉,然后再来测试SOS键没有按下时的电压,此时是0.01V,这才是我想要的电平,可是为什么把GPG10的上拉功能关闭掉后可以拉低SOS_DET引脚的电压为0V呢?而之前是使能GPG10的上拉功能的,也就是使能GPG10上拉功能的时候,CPU内部中GPG10的上拉电阻(一般是75K左右)和图1的R173形成回路,这样根据分压原理就可以知道SOS_DET引脚的电源为1.3V左右,所以我们需要把GPG10的上拉功能关闭掉,这是我的理解,不知是否有误,而且我的理解还不够深入,在此忘大家赐教,谢谢了。
4.2 接入sd卡启动之后SOS按键中断没有被触发
但如果没有接入SD卡启动,那么就可以正常相应SOS按键中断,带SD卡启动之后再按下SOS按键OEMInterruptHandler函数都没有进入图5的代码处理段,为什么呢?见图2可知用于检测SD卡是否插入的引脚nCD_SD连接到EINT16/GPG8的,见下图
图11
后来仔细看看了SD卡驱动部分,虽然把GPG8初始化为中断功能EINT16,但实际是用查询的模式,下图是CSDIOControllerBase::Initialize()函数相关部分
图12
这样在带SD卡驱动的时候,就会检查到nCD_SD引脚对应的EINT16中断进来,自然而然就
执行了图5的检查SD卡插入的处理部分,可以看到其中执行了下面语句
s2440INT->rSRCPND = BIT_EINT8_23;
这表示中断源EINT16的已经插入中断请求,等待中断处理,可是系统起来后SD卡驱动并没有实际用到EINT16的中断处理,也没有清除中断相关寄存器的对应位,也就是没有一直处于外部扩展中断EINT8到EINT23的中断请求这时候就进不来,认识到这一点之后,在CSDIOControllerBase::Initialize()函数的后面添加下面的代码就解决了这个问题:
图13
图13中调用InterruptDone函数,从而内核调用了OEMInterruptDone函数的相关部分,见
图8,这样就解决了这个问题。