6271|12

76

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

调用KernelIoControl获取逻辑中断号失败的原因 [复制链接]

请教:

  if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&g_Irq,sizeof(UINT32),&g_SysIntr,sizeof(UINT32),NULL))
    {
      RETAILMSG(1,TEXT("ERROR:Failed to request sysintr value for Timer1 inturrupt!/r/n"));
      return;
    }

结果,执行时串口输出:ERROR:Failed to request sysintr value for Timer1 inturrupt!

请问:这里调用KernelIoControl获取Timer1的逻辑中断号失败的原因会是什么呢?还请热心的各位给与多多少少的指点,多谢多谢……

其中:static UINT32 g_Irq=IRQ_TIMER1;static UINT32 g_SysIrq=SYSINTR_UNDEFINED;
     S3C2410x_intr.h中#define IRQ_TIMER1 11

最新回复

的确如此.......  详情 回复 发表于 2008-12-28 13:34
点赞 关注

回复
举报

71

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
在参数没有传错的情况下,对IOCTL_HAL_REQUEST_SYSINTR进行KernelIoControl调用失败可能的原因有:
1.Irq>IRQ_MAXIMUM;
2.系统没有可得的SYSINTR;
不过这两种情况都不太像。
建议打开OAL中函数OALIoCtlHalRequestSysIntr和OALIntrRequestSysIntr的调试信息,很容易就知道哪里有问题了!

-Daniel.Dong
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
十分感谢DanieDong1977大侠的回复,谢谢。我再试试看。

大侠,另外关于这方面我还有一些比较浅薄的问题,希望得到大侠的帮助。

1.       我想用S3C2410的定时器1的中断,那么用KernelIoControl申请的逻辑中断号必须由我来自定义么?

是在:\WINCE500\PLATFORM\SMDK2410\INC\oalintr.h中定义么?

是在一定范围内随便定义的么?                                         

这个特定的范围是不是在:\WINCE500\PUBLIC\COMMON\OAK\INC\nkintr.h中定义的?

这个范围值是不是(SYSINTR_FIRMWARE到SYSINTR_MAXIMUM)?

2.       我查看:\WINCE500\PLATFORM\SMDK2410\KERNEL\HAL\oemioctl.c中的OEMIoControl函数中确实没有case IOCTL_HAL_REQUEST_SYSINTR一项,反而有另外一个case IOCTL_HAL_TRANSLATE_IRQ一项,这项条件下调用了OEMTranslateIrq函数,该函数直接把硬件中断号返回了,而且我也试了,我用KernelIoControl(IOCTL_HAL_TRANSLATE_IRQ,……),确实能够返回一个跟硬件中断号一样的值。

但是问题又出现了,如果我用这样返回的逻辑中断号,那么在驱动中接下来执行InterruptInitialize时,又失败了,所以我想是不是这样得到的逻辑中断号有问题?

3.       另外,对于硬件中断号,我直接使用:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\INC\s3c2410x_intr.h中对中断号的宏定义(如:#define IRQ_TIMER1  11)作为申请逻辑中断号的硬件中断号可以么?

如果这样可以的话那么上面我说到的得到定时器1对应的逻辑中断号就是11,那么这个数值岂不是比nkintr.h中定义的SYSINTR_FIRMWARE=16还小?

4.       我在:\WINCE500\PLATFORM\SMDK2410\KERNEL\HAL\oemioctl.c中的OEMIoControl函数中紧在case IOCTL_HAL_TRANSLATE_IRQ之前加入case IOCTL_HAL_TRANSLATE_IRQ一项,而驱动中仍然用KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,……)然后再次运行应用程序,返回Sysintr值失败,说明我在oemioctl.c中的修改没有起作用。

那么想请问何老师,要想修改的oemioctl.c起作用需要重新编译内核么?如果想不变动预装的操作系统,应该怎么做?

5.       我看到:\WINCE500\PLATFORM\SMDK2410\INC\oalintr.h中有一段函数:

DWORD MapIrq2SyaIntr(DWORD _Irq)

{

        If(_Irq<=20)

               return (SYSINTR_FIRMWARE+_Irq);

        Else

               Return(0xffffffff);

}

不知道这段小程序是用在哪里的?我找不到,只在……\SMDK2410\DRIVERS\USB\OHCD中看到其中有用到dwSysIntr=MapIrq2Intr(dwIRQ);其dwIRQ=11,其说明部分如下:

        // The "MapIrq2SysIntr()" makes the system IRQ value be mapped to the physical interrupt. This function is defined in the 'oalintr.h' in the directory 'INC'. The dwIRQ may be used a higher value than 10. The value 0 to 10 is alreay used.

dwSysIntr = SYSINTR_USB = SYSINTR_FIRMWARE + dwIRQ,dwIRQ = 11. I decided its value temporary.

好像这段程序适用于在oalintr.h中有定义的中断。

6.       还有一个问题:我读了:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\PWRBUTTON\pwrbtn2410.c,它好像是自带的一个对一个管电源的按键的流接口驱动,其中

UINT32 g_PwrButtonIrq=IRQ_EINT2;//Determined by SMDK2410 board layout.

申请逻辑中断号的代码如下:

if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&g_PwrButtonIrq, sizeof(UINT32), &g_PwrButtonSysIntr, sizeof(UINT32), NULL))

    {

        RETAILMSG(1, (TEXT("ERROR: PwrButton: Failed to request sysintr value for power button interrupt.\r\n")));

        return(0);

    }

    RETAILMSG(1,(TEXT("INFO: PwrButton: Mapped Irq 0x%x to SysIntr 0x%x.\r\n"), g_PwrButtonIrq, g_PwrButtonSysIntr));

我理解这个驱动应该是已经编译到已经预装的操作系统中了,那么也就是说它的硬件中断号也是用的类似于s3c2410x_intr.h中对中断号的宏定义(如:#define IRQ_TIMER1  11),那么它怎么就可以直接用KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,……)呢,而实际情况如我前所说,OEMIoControl函数中确实没有case IOCTL_HAL_REQUEST_SYSINTR一项,反而有另外一个case IOCTL_HAL_TRANSLATE_IRQ一项?

问题比较杂而且碎,劳驾大侠了。
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

4
 
1.如果KernelIoControl调用成功,那么返回的逻辑中断号一定在SYSINTR_FIRMWARE到SYSINTR_MAXIMUM之间;
2.看起来你的BSP有点问题,你不是用的Windows CE 5.0中默认的SMDK2410吧,看起来它的和你的差别很大;在Windows CE 5.0的默认BSP中,IOCTL_HAL_TRANSLATE_IRQ和IOCTL_HAL_REQUEST_SYSINTR对应的处理函数是OALIoCtlHalRequestSysIntr,它所在的位置是WINCE500\PLATFORM\COMMON\SRC\COMMON\INTR\COMMON\ioctl.c中;
3.当然可以,但是你的对应处理函数不正确,所以自然得不到正确的逻辑中断号;
4.对于这种修改,重新编译BSP即可;
5.我没有看到你完整的BSP,所以对这段程序也不理解;
6.你确信这个驱动中KernelIoControl调用是成功的吗?如果它可以调用成功,理论上你的调用也应该成功才是;无论如何,你必须先找到IOCTL_HAL_REQUEST_SYSINTR对应的处理函数,在整个Windows CE目录下找找看呢?

-Daniel.Dong
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

5
 
DanieDong1977大侠,首先对您的热心帮助在这里表示由衷的感谢了。
还是以上的相关问题:
1.我用的不是Windows   CE   5.0中默认的SMDK2410,而是开发板光盘带的SMDK2410;
2.我在整个CE目录下搜索含有有IOCTL_HAL_REQUEST_SYSINTR的文件,得到如下结果:
ioctl.c         C:\WINCE500\PLATFORM\COMMON\SRC\COMMON\INTR\COMMON
oal_intr.h        C:\WINCE500\PLATFORM\COMMON\SRC\INC
oal_ioctl_tab.h        C:\WINCE500\PLATFORM\COMMON\SRC\INC
ioctl_tab.h        C:\WINCE500\PLATFORM\COMMON\SRC\X86\INC
globals.c        C:\WINCE500\PLATFORM\EMULATOR\SRC\KERNEL\OAL
imple.c                C:\WINCE500\PLATFORM\MAINSTONEII\SRC\DRIVERS\SDHC
s3c2410kbd.cpp        C:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\KEYBD\KBDCOMMON
pdsockdt.cpp        C:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\PCCARD
pwrbtn2410.c    C:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\PWRBUTTON
ser_smdk2410.cppC:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\SERIAL
pxa25xpdd.cpp   C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\INTEL\PXA25X\USB\FUNCTION\PDD
sdcontrol.c     C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\INTEL\PXA27X\SDHC
bul16550.cpp    C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\INTEL\PXA27X\SERIAL
sdiocontrollerbase.cpp    C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\SDHC\SDHCBASE
s3c2410x_touch.cpp        C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\TOUCH
s3c2410pdd.cpp            C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\USB\FUNCTION
hwctxt.cpp                C:\WINCE500\PUBLIC\COMMON\OAK\CSP\ARM\SAMSUNG\S3C2410X\WAVEDEV
pdsocket.cpp              C:\WINCE500\PUBLIC\COMMON\OAK\CSP\MIPS\AMD\AU1\PCCARD
auuart.cpp                C:\WINCE500\PUBLIC\COMMON\OAK\CSP\MIPS\AMD\AU1\SERIAL
ohcd.c          C:\WINCE500\PUBLIC\COMMON\OAK\CSP\MIPS\AMD\AU1\USB
pdd.c           C:\WINCE500\PUBLIC\COMMON\OAK\CSP\MIPS\AMD\AU1\WAVEDEV\PDD
wince.c         C:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\RNDISMINI
pcibus.cpp      C:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\PCCARD\MDD
pcmciaen.cpp    C:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\PCCARD\MDD
pcmcia.cpp      C:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\PCCARD\PCMCIA
pcibus.c        C:\WINCE500\PUBLIC\COMMON\OAK\DRIVERS\PCIBUS
pkfunc.h        C:\WINCE500\PUBLIC\COMMON\OAK\INC
由上可见,在SMDK2410目录下的只有四个,而且它们都只是作为驱动程序是用了KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,……),而IOCTL_HAL_REQUEST_SYSINTR对应的处理函数似乎除了ioctl.c好像是没有的吧。
但是就像我前面说的,:\WINCE500\PLATFORM\SMDK2410\SRC\DRIVERS\PWRBUTTON\pwrbtn2410.c中确实是这样用的,if(!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&g_PwrButtonIrq,   sizeof(UINT32),   &g_PwrButtonSysIntr,   sizeof(UINT32),   NULL)) ,而且我想编译好的内核应该也是用的这段程序吧?只不过在串口的输出信息中比程序中让输出的数量少,所以我又怀疑编译好已经预装的系统中是不是用的这段程序。这个问题我问问厂家看能不能问出来吧。

3.那么在这种情况下我是不是需要加入installable ISR,但是我看了PB帮助文档并且查阅网上,好像在OEMInterruptHandler中调用了NKCallIntChain时,才能用installable ISR吧?而我看了OEMInterruptHandler函数并没有调用NKCallIntChain,那就是说我也不能用installable ISR了?
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

6
 
DanieDong1977大侠,我又仔细看了,确实是我把CE 5.0中默认的SMDK2410当成了开发板带的SMDK2410了,所以上面我发到四楼的帖子无效,我想修改,却修改不了上面的帖子,汗……
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

7
 
1.不过我在开发板带的SMDK2410下搜索确实没有出现任何带有IOCTL_HAL_REQUEST_SYSINTR文件。
2.开发板带的SMDK2410中oemioctl.c中OEMInit中只有这一项,如我前面说的一样。
        case IOCTL_HAL_TRANSLATE_IRQ:
                // Translate a logical interrupt number to a SYSINTR value.
                //
                if (nInBufSize>=sizeof(PULONG) && nOutBufSize>=sizeof(PULONG) &&
                        lpOutBuf && lpInBuf) {
            *(PULONG)lpOutBuf = OEMTranslateIrq(*(PULONG)lpInBuf);
            if (lpBytesReturned)
                *lpBytesReturned = sizeof(ULONG);
            retval = TRUE;
                }
                else {
                        SetLastError(ERROR_INVALID_PARAMETER);
                        retval=FALSE;
                }
                break;
而且开发板带的SMDK2410的armint.c中对OEMTranslateIrq的定义如下:
DWORD OEMTranslateIrq(DWORD dwIrq)
{
    return dwIrq;
}
这都跟我前面提到的一样啊。
3.我是不是需要加入installable   ISR,但是我看了PB帮助文档并且查阅网上,好像在OEMInterruptHandler中调用了NKCallIntChain时,才能用installable   ISR吧?而我看了OEMInterruptHandler函数并没有调用NKCallIntChain,那就是说我也不能用installable   ISR了?
现在头脑里好乱,不知道到底应该从哪入手来解决问题,烦劳大侠了。
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

8
 
建议检查一下你使用的开发板带的SMDK2410中其它driver是采用什么方式来申请逻辑中断号的?都是用IOCTL_HAL_TRANSLATE_IRQ来申请的吗?如果是,可以检查一下它使用的硬件中断号是如何定义的?为什么不会出现得到逻辑中断号的小于SYSINTR_FIRMWARE的情况?

-Daniel.Dong
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

9
 
DanieDong1977大侠,我查看了一下,板带SMDK2410中:

出现InterruptInitialize的文件:

\SMDK2410\DRIVERS\KEYBD\KBDCOMMON\s3c2410kbd.cpp中
ReadRegDWORD( TEXT("HARDWARE\\DEVICEMAP\\KEYBD"), _T("SysIntr"), &dwSysIntr_Keybd );
InterruptInitialize(dwSysIntr_Keybd,m_hevInterrupt,NULL,0)

\SMDK2410\DRIVERS\USB\FUNCTION\sc2410_usb_ser.c
InterruptInitialize(pHWHead->pHWObj->dwIntID, pHWHead->hSerialEvent, 0, 0)


\SMDK2410\DRIVERS\WAVEDEV\hwctxt.cpp中       
m_IntrAudio         = SYSINTR_AUDIO;
bSuccess = InterruptInitialize(m_IntrAudio, m_hAudioInterrupt, NULL, 0);


\SMDK2410\DRIVERS\SERIAL\mdd.c中
InterruptInitialize(pSerialHead->pHWObj->dwIntID,
                              pSerialHead->hSerialEvent,
                              NULL,
0)        )


\SMDK2410\DRIVERS\PWRBTN中:
(InterruptInitialize(SYSINTR_POWER, gPwrButtonIntrEvent, 0, 0))
好像都是直接用逻辑中断号,或者是从注册表中获取等。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

10
 
这个帖子很有价值哦。
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

11
 
????
在OALIntrInit这个函数里会调用
// Initialize interrupt mapping
OALIntrMapInit();
// Mask and clear interrupts in INTC
OALIntrStaticTranslate(SYSINTR_USBH,IRQ_PHY_UHC);
这两个函数。
OALIntrMapInit();是微软的代码,做了irq2sysintr[]和sysintr2irq[]的初始化,初始化值都是未定义标志。
OALIntrStaticTranslate也是微软的代码,这里应该是静态分配了usb host的sysintr值了。
那么其它的中断是不是通过KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&Irq, sizeof(UINT32),&SysIntr, sizeof(UINT32), NULL))这样的方式得到Windows CE动态分配的SysIntr值呢?当然Irq是已知确定值。
 
 
 

回复

101

帖子

0

TA的资源

一粒金砂(中级)

12
 
http://topic.eeworld.net/u/20080627/17/5EC7E28A-D4FC-4304-91FA-CE1419586A90.html
找到如下一段话。
调用这个函数KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR...) 系统会分配一个sysintr,并且将这个sysintr和irq联系起来,实际上就是放在两个数组里,一个数组的序号是irq,数组元素是sysintr,一个数组的序号是sysintr,元素是irq,这样系统就可以方便的找到irq和sysintr的对应关系了.这是所谓的动态映射,静态映射就是自己调用函数把irq和自己定义的sysintr添加到数组里. 这样在oal层处理中断的时候可以用一个循环语句来处理. 这些都是ce5.0采用的处理方式.ce4.2就没有这样的数组,所以中断处理的时候有大量的if else语句,或者 swicth case语句.
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 11 楼 wohuazhen 的回复:
http://topic.eeworld.net/u/20080627/17/5EC7E28A-D4FC-4304-91FA-CE1419586A90.html
找到如下一段话。
调用这个函数KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR...) 系统会分配一个sysintr,并且将这个sysintr和irq联系起来,实际上就是放在两个数组里,一个数组的序号是irq,数组元素是sysintr,一个数组的序号是sysintr,元素是irq,这样系统就可以方便的找到irq和sysintr的对应关系了.这是所谓的动态映射,静态映射就是自己调用函数…


的确如此.......
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表