wince6.0 +S3C6410 中断处理例子(按键控制LED灯)+应用程序控制LED流水灯

首先:介绍一下wince中断处理过程,
1、当一个中断发生后,发送到内核异常处理器(ExceptionHandler)
2、内核的中断支持处理器调用OAL层函数OEMInterruptDisable 屏蔽中断(..\hal\Cfw.c)
     屏蔽掉所有优先级等于或是小于当前优先级的中断
3、内核调用ISR,ISR  返回中断号(逻辑中断标识符)给内核。
      内核的处理程序打开除当前外的所有中断,然后内核根据此中断号绑(InterruptInitialize函数 绑定中断号核事件)的事件(Event)唤醒事件的等待线程(IST),IST 在用户态完成中断处理。
4、IST   调用InterruptDone 来告诉操作系统中断处理完毕,操作系统再次调用OAL 中
     OEMInterruptDone函数完 成中断的处理。
5、IST调用InterruptDone函数来通知系统已经完成中断的处理。
     这个函数会调用OAL层的OEMinterruptDone函数,它会重新开启当前中断

WinCE的中断处理模型

二、WinCE中断体系结构

从结构上看,WinCE中断涉及4 层,即:硬件层、内核层、OAL层、IST处理层。了解这 4层之间的交互传递将对我们了解WinCE中断处理很有帮助。

1、硬件层:

  硬件层就是实际触发中断的硬件,这里主要有两方面作用,一个是触发中断,第二个是enable/disable硬件中断。   1、层即上述模型中的第一部分 中断相应  产生物理IRQ

2、OAL层

  这一层主要就是我们需要实现的代码了,来识别硬件IRQ,对应到SYSINTR。 上述模型中的内核

3、内核层:

  这一层由内核来处理,包括中断异常产生后跳转到相应的ISR,以及根据SYSINTR 来触发相应的Event。关于SYSINTR 和 IRQ 的概念后面会说明。

4、IST处理层

  一般使用 IST 来做实际的中断处理,这样不会占用很多的锁定系统时间来处理中断,但是对中断的实时性大打折扣

三、WinCE中断处理实例(按键控制LED)


详细代码下载地址:http://download.csdn.net/detail/lyx123/4525808


大致步骤如下:

1.    初始化GPIO口

2、  创建事件

3、  获取IRQ的系统中断号

4、  创建挂起的中断服务线程IST

5、  调用InterruptInitialize以创建IRQ与事件之间的关联。(创建未挂起的中断服务线程有可能导致InterruptInitialize函数调用失败,因为该事件已经处于等待状态)

6、  调用CeSetThreadPriority函数设置IST的优先级

7、  启动IST线程

采用流驱动编写

 


1.初始化GPIO口

//声明的一些变量

HANDLE m_interruptTestEvent = NULL;
HANDLE m_interrupTestThread = NULL;
DWORD m_interruptTestSysId = SYSINTR_UNDEFINED;
DWORD m_interruptTestPhyId = 0;
LPDWORD lpThreadId = NULL;
DWORD threadpriority = 6;
BOOL m_ExitThread = FALSE ;


void InitInterruptTestGPIO(void)
{
RETAILMSG(1,(TEXT("***test InitInterruptTestGPIO  \r\n")));
// interrupt led test  中断控制的led灯
v_pIOPregs->GPMCON &= 0xfffffff0; //set pin out
v_pIOPregs->GPMCON |= 0x1;
  
v_pIOPregs->GPMPUD &= 0xfffffffc ;  //enable up
v_pIOPregs->GPMPUD |= 0x2;

//interrup sourse gpn0  设置gpn0脚为中断源
v_pIOPregs->GPNCON &= 0xfffffffc;
v_pIOPregs->GPNCON |= (0x2<<0);
      //pull up enable
v_pIOPregs->GPNPUD &= 0xfffffffc;
v_pIOPregs->GPNPUD |= (0x2<<0);
//filter enable
v_pIOPregs->EINT0FLTCON0 = (v_pIOPregs->EINT0FLTCON0 & ~(0x1<<6)) |(0x1<<7);

//Configurate the EINT0 Trigger of Flowing Type 01x 配置EINT0为下降沿触发
v_pIOPregs->EINT0CON0 &= 0xfffffff8;
v_pIOPregs->EINT0CON0 |= (0x2<<0);
}


2.使能中断

BOOL Enble_Test_Interrupt(void)
{
//clear interrupt eint 0
v_pIOPregs->EINT0PEND = (0x1<<0);

 //网上有说v_pIOPregs->EINT0PEND = (0x1<<0) 与v_pIOPregs->EINT0PEND |=(0x1<<0);

 //有差,前者是清除位元,后者是全部位清除,我试了都可以,还得好好研究                                                                                         
//ENable Interrupt MASK EINT0
v_pIOPregs->EINT0MASK =v_pIOPregs->EINT0MASK & ~(0x1<<0);
return true;
}


3.物理中断映射成系统中断号,创建中断事件及中断处理线程

BOOL InitInterruptTest(void)
{

    RETAILMSG(1,(TEXT("******testInitInterruptTest\r\n")));

m_interruptTestPhyId = IRQ_EINT0;//物理中断号
//物理中断映射成系统中断号
if  (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,&m_interruptTestPhyId,sizeof(DWORD),&m_interruptTestSysId,sizeof(DWORD),NULL))
{
RETAILMSG(1,(TEXT("******test KernelIoControlt fail\r\n")));
m_interruptTestSysId = SYSINTR_UNDEFINED;
return FALSE;
}

//create an event
m_interruptTestEvent = CreateEvent(NULL, FALSE, FALSE,NULL);
if (NULL == m_interruptTestEvent)
{
RETAILMSG(1,(TEXT("******test create event fail\r\n")));
return FALSE;
}
// 创建一个挂起的线程
m_interrupTestThread = CreateThread(NULL,  // Security
0,     // No Stack Size
(LPTHREAD_START_ROUTINE)Threadproc,//Interrupt Thread        /*参数必须与中断处理函数名称一样*/          
NULL,     // No  Parameters   
CREATE_SUSPENDED, // Create Suspended
lpThreadId ); // Thread Id  );


// set the thread priority
threadpriority  = 6;
if( !CeSetThreadPriority( m_interrupTestThread, threadpriority))
{
RETAILMSG(1,(TEXT("test: Failed setting Thread Priority.\r\n")));
return FALSE;
}

//initialize interrupt event
if (!InterruptInitialize(m_interruptTestSysId,m_interruptTestEvent,NULL,0))
{
ERRORMSG( 1, (TEXT("test interrupt is not initialized\n\r")));
return(FALSE);

}
//启动线程
ResumeThread( m_interrupTestThread );
return TRUE;
}


4.中断线程处理函数

DWORD WINAPIThreadproc(LPVOID lpvParam)
{
DWORD  dwStatus;
BOOL  fState = TRUE;
static BOOL count = TRUE;
   RETAILMSG(1,(TEXT("entry test thread \r\n")));
while (!m_ExitThread)
{
        dwStatus = WaitForSingleObject(m_interruptTestEvent,INFINITE);
if (m_ExitThread)
{
break;
}
if (dwStatus == WAIT_OBJECT_0)
{
RETAILMSG(1,(TEXT("test thread happend \r\n")));

}
count = ~count;
if(count&0x1)
      v_pIOPregs->GPMDAT |= 0x1; //灯灭
else
v_pIOPregs->GPMDAT &= 0xfffffffe;//灯亮
InterruptDone(m_interruptTestSysId);

Enble_Test_Interrupt();

}
return FALSE;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值