dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
阅读:2050回复:14

wince中断问题

楼主#
更多 发布于:2004-12-31 13:21
我现在遇到的问题是不知道如何编写硬件触发中断处理程序
环境为wince.net  x86,代码如下希望您给予关注
//Öжϴ¦Àí²¿?Ö
HANDLE g_hevInterrupt;;
HANDLE g_htIST;
DWORD g_dwSysInt;
DWORD SetupInterrupt ( void );
DWORD WINAPI ThreadIST ( LPVOID lpvParam );
DWORD  SetupInterrupt( void )
{
BOOL fRetVal;
DWORD dwIrq = 7(这是硬件设置的中断号)
DWORD dwThreadID;
// Create an event
//
g_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL);
if(!g_hevInterrupt) return 10;
// Have the OAL Translate the IRQ to a system irq
//
fRetVal = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ,
&dwIrq,
sizeof( dwIrq ),
&g_dwSysInt,
sizeof( g_dwSysInt ),
NULL );
if( !fRetVal )return 11;
// Create a thread that waits for signaling
//
g_htIST =  CreateThread(NULL,// CE Has No Security
0, // No Stack Size
ThreadIST,// Interrupt Thread
NULL,// No Parameters
CREATE_SUSPENDED,// Create Suspended until we are done
&dwThreadID // Thread Id
);
if( !g_htIST )return 12;
// Set the thread priority to real time
//
int m_nISTPriority = 7;
if(!CeSetThreadPriority( g_htIST, m_nISTPriority))
  return 13;
// Initialize the interrupt
//
if ( !InterruptInitialize(g_dwSysInt,g_hevInterrupt,NULL,0) )return 14;
    ResumeThread( g_htIST );
return 0;
}

DWORD WINAPI ThreadIST( LPVOID lpvParam )
{
   DWORD   dwStatus;
   // Always chec the running flag
   //
   BOOL g_fRun = TRUE;
   while( g_fRun )
   {
      dwStatus   = WaitForSingleObject(g_hevInterrupt, INFINITE);
      // Make sure we have the object
      //
      if( dwStatus == WAIT_OBJECT_0 )
      {
         // Handle Interrupt Here
         //
         ::MessageBox (NULL, _T("²âÊÔ!"), _T("¾¯¸æÌáʾ"), MB_ICONQUESTION);
// Finish the interrupt
         //
         InterruptDone( g_dwSysInt );
      }
   }
   return 0;
}
不知道为什么不能触发
wxl_50685330
论坛版主
论坛版主
  • 注册日期2002-11-19
  • 最后登录2018-09-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望521点
  • 贡献值0点
  • 好评度419点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-12-31 15:41
你的7(硬件号)号中断的isr里面要返回你申请的sysintr才行
根据地的兄弟们,团结就是力量
dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-12-31 16:13
你的7(硬件号)号中断的isr里面要返回你申请的sysintr才行

我是刚刚入行 ,很感谢你的回帖,你的意思我不太懂?请明示
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-12-31 16:38
dellgao兄弟,怎么没有看到你的中断处理程序isr?是你自己写的吗?只有在你的isr中返回你前面定义的g_dwSysInt值,你的WaitForSingleObject函数才会被释放。
Come on, let us drive the world.
dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-12-31 16:50
dellgao兄弟,怎么没有看到你的中断处理程序isr?是你自己写的吗?只有在你的isr中返回你前面定义的g_dwSysInt值,你的WaitForSingleObject函数才会被释放。

你说的中断服务程序,DWORD WINAPI ThreadIST ( LPVOID lpvParam );这个函数不是吗?你写过给一段源码好吗我参考一下,多谢了
liumengtao
驱动牛犊
驱动牛犊
  • 注册日期2003-03-02
  • 最后登录2006-08-08
  • 粉丝0
  • 关注0
  • 积分64分
  • 威望8点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-01-01 01:06
ISR跟IST不是一回事,ISR负责获取硬件中断,再返回系统中断号给IST以触发WaitForSingleObject,ISR源码直接在帮助里找到,改改就行了。
午夜母猪魔
驱动牛犊
驱动牛犊
  • 注册日期2004-11-18
  • 最后登录2006-06-01
  • 粉丝0
  • 关注0
  • 积分29分
  • 威望4点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-01-02 10:00
给你讲讲关于硬件中断转换为系统中断的流程你可能就清楚了:(因为我使用的是arm所以抗smdk2410为例。你可以根据你自己的平台来调整)
1。要使用中断必须先注册中断。具体位置在:
D:\WINCE420\PLATFORM\SMDK2410\INC\oalintr.h参照wince自带的中断注册即可。
2。将硬件中断变为系统中断
D:\WINCE420\PLATFORM\SMDK2410\KERNEL\HAL\ARM\armint.c 其中函数OEMInterruptHandler是实现硬件中断转换为系统中断的函数。可以参展别的中断产生的方法写你自己的中断。
3。中断与事件的绑定(以串口的为例,你要根据自己的需要写自己的东西。但是使用的函数是一样的):
com_init()
{ PHW_INDEP_INFO pSerialHead = NULL;
 pSerialHead->hserialevent =  CreateEvent (0.FALSE,FALSE,NULL);
InterruptInitialize (pSerialhead->pHWObj->dwIntID,//系统中断号       pSerialHead->hserialevent ,NULL,0);
                      
)//此函数为中断与事件绑定

pSerialHead->pDispatchThread = CreateThread(NULL,0,IST,pSerialHead,0,NULL);//开一个处理线程
return(pSerialHead);
}
static DWORD WINAPI
IST ( PVOID pContext)
{
PHW_INDEP_INFO pSerialHead = (PHW_INDEP_INFO )pContext;
ULONG WaitReturn;
while (!Done())
{
WaitReturn = WaitForSingleObject
(pSerialHead->hserialevent ,INFINITE);
SerialEventHandler(pSerialHead);
InterruptDone(pSerialhead->pHWObj->dwIntID);
}
return(0)
}
在这里SerialEventHandler是自己要写的。
4。以上就是是中断处理的具体流程。你可以参考使用。如果有不对的地方请大家补充;
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-01-04 10:28
To dellgao: 不要着急,其实你离成功只差那么一小步了:)))
我仔细看了一下你给出的代码,还差那么一点点。就是没有把你的硬件中断(7号)和你的ISR相关联。你想想,对于你给出的代码,即使你的硬件已经产生了中断,系统也无法通知你的线程,因为系统怎么会知道你的IST和7号中断有关?所以你还需要做的就是把7号中断与一个ISR相关联,当产生7号中断时,系统会调用这个ISR。这个ISR由你自己来写,一般情况下,ISR只是完成简单的处理工作,主要工作还是由IST来完成。ISR的主要任务:
(1)判断这个中断(对于共享中断)是不是由你的硬件产生,如果
不是则直接返回SYSINTR_CHAIN;
(2)如果是由你的硬件产生,但不需要再由你的IST做进一步处理,那么返回SYSINTR_NOP就可以了;
(3)如果是由你的硬件产生,而且还需要由你的IST做进一步处理,那么要返回g_dwSysInt (这个值是你前面在SetupInterrupt( void )中得到的),返回g_dwSysInt之后,内核会激活与g_dwSysInt关联的事件,这样你的IST中的wait函数就会被释放了。


总结一下:
(1)你需要自己的写这个中断的处理函数即ISR,ISR的代码可以参照前面给出的主要任务来写,也可以参考pb里面的例子;
(2)在你的SetupInterrupt函数中调用LoadIntChainHandler函数把你的硬件中断(7号)同你写的ISR关联起来。

这样,就可以了,你试试吧,Good Luck.
 :P :P :P
Come on, let us drive the world.
dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2005-01-04 10:47
给你讲讲关于硬件中断转换为系统中断的流程你可能就清楚了:(因为我使用的是arm所以抗smdk2410为例。你可以根据你自己的平台来调整)
1。要使用中断必须先注册中断。具体位置在:
D:WINCE420PLATFORMSMDK2410INCoalintr.h参照wince自带的中断注册即可。
2。将硬件中断变为系统中断
D:WINCE420PLATFORMSMDK2410KERNELHALARMarmint.c 其中函数OEMInterruptHandler是实现硬件中断转换为系统中断的函数。可以参展别的中断产生的方法写你自己的中断。
3。中断与事件的绑定(以串口的为例,你要根据自己的需要写自己的东西。但是使用的函数是一样的):
com_init()
{ PHW_INDEP_INFO pSerialHead = NULL;
 pSerialHead->hserialevent =  CreateEvent (0.FALSE,FALSE,NULL);
InterruptInitialize (pSerialhead->pHWObj->dwIntID,//系统中断号       pSerialHead->hserialevent ,NULL,0);
                      
)//此函数为中断与事件绑定

pSerialHead->pDispatchThread = CreateThread(NULL,0,IST,pSerialHead,0,NULL);//开一个处理线程
return(pSerialHead);
}
static DWORD WINAPI
IST ( PVOID pContext)
{
PHW_INDEP_INFO pSerialHead = (PHW_INDEP_INFO )pContext;
ULONG WaitReturn;
while (!Done())
{
WaitReturn = WaitForSingleObject
(pSerialHead->hserialevent ,INFINITE);
SerialEventHandler(pSerialHead);
InterruptDone(pSerialhead->pHWObj->dwIntID);
}
return(0)
}
在这里SerialEventHandler是自己要写的。
4。以上就是是中断处理的具体流程。你可以参考使用。如果有不对的地方请大家补充;

"D:WINCE420PLATFORMSMDK2410INCoalintr.h参照wince自带的中断注册即可。
"我找了半天没有找到,请指教?谢谢我是新手
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2005-01-04 11:24
其实,arm和x86架构的平台,中断处理的实现方法的有一定的差别。在WINCE420\\PUBLIC\\COMMON\\OAK\\CSP\\I486\\INC的oalintr.h中定义了OEM所使用的用于irq和sysintr转换的函数,不过这些函数只能用于OAL层。在\\WINCE420\\PUBLIC\\COMMON\\OAK\\INC中的nkintr.h中有sysintr的定义,你可以看看。
其实,你可以按照我前面的方法试试,可以解决你的问题。你只需写一个isr并把这个isr和你的硬件中断相关联即可。
Come on, let us drive the world.
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2005-01-04 12:09
PB中提供了许多驱动的源代码,你的isr可以参考GIISR.dll来写,它的源代码位于WINCE420\\PUBLIC\\COMMON\\OAK\\DRIVERS\\GIISR。
Come on, let us drive the world.
dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-01-07 15:59
PB中提供了许多驱动的源代码,你的isr可以参考GIISR.dll来写,它的源代码位于WINCE420\PUBLIC\COMMON\OAK\DRIVERS\GIISR。

这几天忙乎了一大阵子,还是迷茫,我是在EVC环境开发,不是在PB里面做,而且我是对计数器板开发,厂家没有提供驱动,
我的程序要实现的目的如下:
1、硬件环境是一个基于x86的PC104三寸嵌入式板卡
2、pc104的IO卡带有3个计数器
软件要实现的功能就是:
对计数器进行编程,每当计数器完毕时候就触发一个中断
以上就是所要罗嗦的,希望您能给个建议,谢谢!
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-01-07 16:22
兄弟,如果我没说错的话,你的驱动是用来进行数据采集的?
其实,这个驱动的框架已经出来了(就是你最初写的那些),现在关键的问题是isr,你可以看看我前面给你建议,按照那个做肯定可以的。
Come on, let us drive the world.
dellgao
驱动牛犊
驱动牛犊
  • 注册日期2004-12-31
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分41分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2005-01-07 16:50
兄弟,如果我没说错的话,你的驱动是用来进行数据采集的?
其实,这个驱动的框架已经出来了(就是你最初写的那些),现在关键的问题是isr,你可以看看我前面给你建议,按照那个做肯定可以的。

我不是做采集的是分频用的,我看了你说的例程,有些迷糊
wwei_wang
驱动大牛
驱动大牛
  • 注册日期2002-06-07
  • 最后登录2006-06-23
  • 粉丝0
  • 关注0
  • 积分77分
  • 威望9点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-01-10 08:40
不管是分频还是数据采集,你的驱动肯定是用来响应外部(定时)中断的。现在的问题是,在你的驱动中,由谁来响应你的外部中断呢?肯定不是ist,因为ist只是用来对中断进行进一步的处理,它是不能和硬件中断直接联系在一起的。直接相应硬件中断的是isr,你需要写这个中断服务例程,并把这个例程(isr)同你的硬件中断关联起来,这样当中断产生的时候,系统就会先调用你的isr,进而执行你的ist线程。如果你还是不太清楚,你就看看pb下面关于installable isr方面的文档吧。
Come on, let us drive the world.
游客

返回顶部