您的位置:首页 > 其它

wince中断处理过程

2015-02-27 17:27 309 查看
中断在系统设计中的应用非常广泛,可以说,硬件中断、软件中断无处不在,在WINCE下驱动开发更是如此,比如:按键中断、触摸屏中断、AUDIO中断、DMA中断.....等等,几乎含概每个模块。因此,了解中断的处理过程对驱动开发极其重要,下面对WINCE下的中断处理过程做一个简单介绍。
    
中断处理可以分为两部分:中断服务例程-ISR、中断服务线程-IST。系统在处理中断异常的时候,应该要尽可能快的完成,因此,我们应该在ISR中做简短的处理,把中断标识返回给中断处理器,越快越好。那么就要把大部分的处理留给IST来处理。我们可以简单的认为,ISR的任务就是完成把硬件中断也就是物理中断转为系统中断并返回。
    下面再来了解一下IST,IST就是一个线程,在驱动初始化的时候创建并等待一个事件,当然,在这之前要先创建一个事件,并与中断相关联起来,当中断产生以后该事件触发IST,IST里通常是用户的处理程序。IST的实现必须先实现两个过程:IST的中断必须和一个事件相关联,IST必须通过WaitForSingleObject来等待这个事件的唤醒,IST的最后要调用INTERRUPTDONE来对注销中断,否则该中断只能用一次,一般我们在驱动的XXX_INIT函数中实现。
    IST在BSP/COMMON/INTR/intr.c中,这里面的内容包括init、enable、disable、oeminterrupthandler等函数,主要是对中断的初始化、使能、处理等,其中最关键的是oeminterrupthandler。

而IST的具体实现过程可以参照下面的步骤:
1、创建一个事件。用createEvent 来实现
2、定义一个中断DWORD key_intr=SYSINTR_NOP;
3、得到ISR返回的中断号,并通过KernelIoControl将其与上面定义的中断相关联。
4、将创建的事件与中断相关联即通知系统注册中断,可以通过InterruptInitialize函数来实现。
5、创建一个中断处理IST,通过CreateThread来实现。
6、IST通过WaitForSingleObject来等待事件的唤醒,并处理中断。
7、IST调用InterruptDone来注销中断,循环等待下一次唤醒。

如果是一个按键对应一个IO,且作为外部中断的话,只需要对IO积存器、中断积存器进行设置就可以实现,下面贴出一个我自己的测试代码供大家参考:
#include  
#include  
#include 
#include 
#include "s3c2440a_base_regs.h"
#include "s3c2440a_intr.h"
#include "s3c2440a_ioport.h"

#define FUSQ_DEBUG 1
volatile S3C2440A_IOPORT_REG *p2440a_ioport_reg = NULL;
volatile S3C2440A_INTR_REG   *p2440a_intr_reg = NULL;
DWORD Key_Interrupt = SYSINTR_NOP;
DWORD Key_Interrupt1 = SYSINTR_NOP;

HANDLE abc_KeyIntr_Event;
HANDLE abc_KeyIntr_Event1;
HANDLE abc_Key_Thread;
HANDLE abc_Key_Thread1;
void abc_KeyThread_Fun();
void abc_KeyThread_Fun1();
int i1=0;
int i2=0;

BOOL APIENTRY DllMain(HANDLE hModule,
                      DWORD dwReason,
                      LPVOID lpvReserved)
{   
  
  RETAILMSG(FUSQ_DEBUG, (TEXT("--------------abc_DllMain /r/n") ) );   
    return TRUE;         
}
DWORD abc_Init(LPCTSTR pContext,LPVOID lpvBusContext)
{
  UINT32 Irq;
  
  RETAILMSG(FUSQ_DEBUG, (TEXT("-----------------abc_Init /r/n") ) );
  
  
  //initialize io port
  p2440a_ioport_reg = (volatile S3C2440A_IOPORT_REG*)VirtualAlloc(0, sizeof(S3C2440A_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (!p2440a_ioport_reg)
   {
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_ioport_reg: VirtualAlloc failed!/r/n")));
    return(FALSE);
   }
   else
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_ioport_reg: VirtualAlloc ok----------!/r/n")));
    
  if (!VirtualCopy((PVOID)p2440a_ioport_reg, (PVOID)(S3C2440A_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2440A_IOPORT_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
   {
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_ioport_reg: VirtualCopy failed!/r/n")));
    return(FALSE);
   } 
   else
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_ioport_reg: VirtualCopy ok-----------!/r/n")));
   /*
   p2440a_ioport_reg->GPFCON &=0xFFFFEBFF;//GPF5 、GPF6 For External interrupt
   p2440a_ioport_reg->GPFCON |=(1<<11)|(1<<13);
  */
  // p2440a_ioport_reg->EXTINT0 &=0xFF8FFFFF;// EINT5 Low Level Triggered
   
   //p2440a_ioport_reg->GPFCON=0xAAAAAAAA;    //all initialize int intr.c of OALIntrInit()
   
   p2440a_ioport_reg->EXTINT0=0xf33fffff;
   
   //initialize interrupt 
   p2440a_intr_reg = (volatile S3C2440A_INTR_REG*)VirtualAlloc(0, sizeof(S3C2440A_INTR_REG), MEM_RESERVE, PAGE_NOACCESS);
  if (!p2440a_intr_reg)
   {
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_intr_reg: VirtualAlloc failed!/r/n")));
    return(FALSE);
   }
   else
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_intr_reg: VirtualAlloc ok------------!/r/n")));
  if (!VirtualCopy((PVOID)p2440a_intr_reg, (PVOID)(S3C2440A_BASE_REG_PA_INTR >> 8), sizeof(S3C2440A_INTR_REG), PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
   {
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_intr_reg: VirtualCopy failed!/r/n")));
    return(FALSE);
   } 
   else
    RETAILMSG(FUSQ_DEBUG, (TEXT("p2440a_intr_reg: VirtualCopy ok-----!/r/n")));
   
   //relating the INTR to SystemIntr
   Irq=IRQ_EINT5;
   if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(Irq),
&Key_Interrupt, sizeof(UINT32), NULL))
    {
      RETAILMSG(FUSQ_DEBUG, (TEXT("ERROR: KernelIoControl For Key_Interrupt failed./r/n")));
      Key_Interrupt = SYSINTR_UNDEFINED;
      return(FALSE);
    }
    else
     RETAILMSG(FUSQ_DEBUG, (TEXT("KernelIoControl For Key_Interrupt ok---./r/n"))); 
      
   Irq=IRQ_EINT6;
   if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &Irq, sizeof(Irq),
&Key_Interrupt1, sizeof(UINT32), NULL))
    {
      RETAILMSG(FUSQ_DEBUG, (TEXT("ERROR: KernelIoControl For Key_Interrupt1 failed./r/n")));
      Key_Interrupt1 = SYSINTR_UNDEFINED;
      return(FALSE);
    }
   
   
   //create Intr Event and relating Intr to Event        
  abc_KeyIntr_Event=CreateEvent(NULL,false,false,NULL);
  if(!abc_KeyIntr_Event)
  {
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateEvent--faile---/r/n")));
   return false;
  }
  else
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateEvent---OK--/r/n"))); 
   
  abc_KeyIntr_Event1=CreateEvent(NULL,false,false,NULL); 
  if(!abc_KeyIntr_Event1)
  {
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateEvent1--faile---/r/n")));
   return false;
  } 
  
  if(!
InterruptInitialize(Key_Interrupt, abc_KeyIntr_Event, NULL, 0)) 
  {
      RETAILMSG(FUSQ_DEBUG,(TEXT("InterruptInitialize--Key_Interrupt to abc_KeyIntr_Event failed ./r/n")));
      return FALSE;
    }
    else
     RETAILMSG(FUSQ_DEBUG,(TEXT("InterruptInitialize--Key_Interrupt to abc_KeyIntr_Event ok----- ./r/n")));
  
  if(!
InterruptInitialize(Key_Interrupt1, abc_KeyIntr_Event1, NULL, 0)) 
  {
      RETAILMSG(FUSQ_DEBUG,(TEXT("InterruptInitialize--Key_Interrupt to abc_KeyIntr_Event failed ./r/n")));
      return FALSE;
    }
  
  
  
  abc_Key_Thread=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                0,
                (LPTHREAD_START_ROUTINE)abc_KeyThread_Fun,
                0,
                0,
                NULL
                );
  if(!abc_Key_Thread)
   {
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateThread----faile--/r/n")));
   return false;
   }
  else
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateThread----OK--/r/n"))); 
  
  abc_Key_Thread1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,
                0,
                (LPTHREAD_START_ROUTINE)abc_KeyThread_Fun1,
                0,
                0,
                NULL
                );
  if(!abc_Key_Thread1)
   {
   RETAILMSG(FUSQ_DEBUG,(TEXT("CreateThread1----faile--/r/n")));
   return false;
   }
   
  return true;
}
BOOL  abc_Deinit(DWORD hDeviceContext)
{
  RETAILMSG(FUSQ_DEBUG,(TEXT("--------abc_Deinit--/r/n")));      
  return true;
}
DWORD abc_Open(DWORD hDeviceContext,DWORD AccessCode,DWORD ShareMode)
{
  RETAILMSG(FUSQ_DEBUG,(TEXT("--------abc_Open--/r/n")));   
  return true;

BOOL   abc_Close(DWORD hOpenContext)
{
  
    RETAILMSG(FUSQ_DEBUG,(TEXT("--------abc_Close--/r/n")));
    return true;
}       
   
bool abc_IOControl(DWORD hOpenContext,DWORD dwCode,char pBufIn[],DWORD dwLenIn,char pBufOut[],DWORD dwLenOut,PDWORD pdwActualOut)
{            
  //PBYTE pBufOut  PBYTE pBufIn
    RETAILMSG(FUSQ_DEBUG,(TEXT("--------abc_IOControl----------------/r/n")));
    return true;            
}

void abc_KeyThread_Fun()
{
while(1)
{
  WaitForSingleObject(abc_KeyIntr_Event,INFINITE);
  RETAILMSG(FUSQ_DEBUG,(TEXT("Thread is running:times==%d/r/n"),i1));
  i1++;
  InterruptDone(Key_Interrupt);
  //OEMInterruptDone(Key_Interrupt);
}

void abc_KeyThread_Fun1()
{
while(1)
{
  WaitForSingleObject(abc_KeyIntr_Event1,INFINITE);
  RETAILMSG(FUSQ_DEBUG,(TEXT("Thread is running:times1==%d/r/n"),i2));
  i2++;
  InterruptDone(Key_Interrupt1);
  //OEMInterruptDone(Key_Interrupt);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  wince 中断