Wince外部中断控制LED详解动态申请
1.中断分两大类:内部中断和外部中断。
外部中断:由外部设备所引发的中断,这些外部中断都是通过GPIO中的中断引脚产生的。S3C2440有24个外部中断,相关的寄存器如下:
EXTINT0-EXTINT2:三个寄存器设定EINT0-EINT23的触发方式。
EINTFLT0-EINTFLT3:控制滤波时钟和滤波宽度。
EINTPEND:中断挂起寄存器
EINTMASK:中断屏蔽寄存器
内部中断:内部中断是有CPU内部器件产生的中断,如定时器中断,USB中断,UART中断等。相关的寄存器如下:
SUBSRCPND:次级中断挂起寄存器。
INTSUBMSK:次级中断屏蔽寄存器。
INTMOD:中断方式寄存器
PRIORITY :优先级寄存器
SRCPND :中断挂起寄存器
INTMSK :中断屏蔽寄存器。
INTPND :中断发生后,SRCPND中会有位置1,可能好几个,这些中断会由优先级仲裁器选出一个优先级最高的,然后INTPND中相应位置1,同一时间只有一位是1。
这里要注意一级中断和次级中断的区别,次级中断的设置要比一级中断复杂一些。
2.WINCE中断机制:ISR和IST
WINCE中断从大的方面分为ISR和IST两部分,具体ISR,IST是什么这里就不详说了,网上一搜一大把。简单的说是ISR负责把IRQ转化为逻辑中断并返回给内核;IST则负责中断的逻辑处理。
3.WINCE中断实例:外部按键中断控制LED灯
(1)创建一个简单的流驱动模板,这一步可以手动创建,也可以通过"Windows CE Developer Samples" -> "Windows CE 5.0 Embedded Development Labs" -> "DrvWiz.exe" 框架产生。建议采用后者,简单快捷,不易出错。这里工程命名为LED,即生产的DLL为LED_DLL。
(2)填充函数体。这里主要介绍与中断相关的两个函数:
DWORD LED_Init( LPCTSTR pContext)//驱动初始化函数,主要做内存的分配和调用中断初始化函数。
DWORD WINAPI LED_IST( LPVOID lpvParam ) //中断处理线程,即IST,在这里进行中断处理.
DWORD InitInterrupt( void ) //中断初始化函数,包括中断寄存器的设置,事件和线程的创建,初始化等。
首先介绍DWORD InitInterrupt( void ),代码如下:
DWORD InitInterrupt( void )
{
HANDLE g_htIST; //线程返回句柄
BOOL fRetVal;
DWORD dwThreadID;
printfmsg((TEXT("come into the setup interrupt!!!\r\n")));
//初始化外部中断8
s2440IO->rGPGCON &= ~(0X3);
s2440IO->rGPGCON |= 0X2;//设置为中断模式
s2440IO->rEXTINT1 &= ~(0X0f);
s2440IO->rEXTINT1 |= 0XA; //下降沿触发,使能滤波器
s2440IO->rEINTMASK &= ~(1<8);//打开中断 8
s2440IO->rEINTPEND |= (1<8);//清除中断
//GPIO 设置-LED
s2440IO->rGPBCON = (s2440IO->rGPBCON &~(3 < 14)) | (1< 14); // GPB7 == OUTPUT.
s2440IO->rGPBCON = (s2440IO->rGPBCON &~(3 < 16)) | (1< 16); // GPB8 == OUTPUT.
s2440INTR->rINTMSK &= ~(0x20); //取消外部中断8的屏蔽
s2440INTR->rSRCPND |= (0x20); //清除外部中断8
s2440INTR->rINTPND |=0X20; //清除外部中断,即初始化
// 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
//将物理中断IRQ转换为逻辑中断
fRetVal = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ,
&dwIrq,
sizeof( dwIrq ),
&g_dwSysInt,
sizeof( g_dwSysInt ),
NULL );
if( !fRetVal )
{ return -1 }
// Create a thread that waits for signaling
// 创建中断服务线程IST
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 -1 }
// Set the thread priority to real time
// 设置线程的优先级
int m_nISTPriority = 7;
if(!CeSetThreadPriority( g_htIST, m_nISTPriority))
{ return -1 }
// Initialize the interrupt
// 初始化中断,将逻辑中断号与事件关联,即中断产生时触发该事件
//在中断服务线程IST中会等该事件的发生,即WaitForSingleObject(g_hevInterrupt, INFINITE);
//从而中断发生就导致IST运行,处理中断任务
if ( !InterruptInitialize(g_dwSysInt, g_hevInterrupt, NULL, 0) )
{return -1; }
ResumeThread( g_htIST );
printfmsg((TEXT("*leave the setup interrupt!!!\r\n")));
return 1;
}
简单说一下初始化中断的流程,首先是初始化相关的中断寄存器,我这里采用的是外部中断8。接下来是创建一个事件,用于关
Wince外部中断控制LED动态申 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)