Windows CE6.0中断实验过程

发布者:JoyfulJourney最新更新时间:2024-11-07 来源: cnblogs关键字:Windows  中断实验  S3C6410 手机看文章 扫描二维码
随时随地手机看文章

1.实验目的:通过本次试验学习Windows CE6.0的中断处理的过程以及熟悉在驱动程序中运行中断的编程。

2.我对Windows CE6.0中断的理解:

Windows® CE将中断处理分成两个步骤:中断服务程序ISR和中断服务线程IST。如果中断被使能,则当中断产生时,内核将调用该中断注册的ISR,ISR执行完后将返回系统中断号,内核检查系统中断号并且设置相关的事件,内核设置相关事件后,相应的IST将开始执行。

3.Windows® CE的处理流程:

(1)如果一个驱动程序要处理一个中断,那么驱动程序首先要建立一个事件(CreateEvent),然后调用InterruptInitialize将该事件与中断号绑定,这一步会使能该中断,OAL中的OEMInerrupteEnable会被调用,如果该函数不返回true的话,InterruptInitialize就会失败。然后驱动程序中的IST就可以使用WaitForSingleObject函数来等待中断的发生。

(2)当一个硬件中断发生之后,操作系统陷入异常,中断向量指示进入CE的异常处理程序,该异常处理程序然后调用OAL的OEMInterruptHandler函数,该函数检测硬件之后,将硬件中断转换为软件的中断号,返回给系统。该中断号就是上面提到的InterruptInitialize中使用的那个中断号。系统得到该中断号之后,就会找到该中断号对应的事件,并唤醒等待相应事件的线程(IST),然后IST就可以在用户态进行中断处理。处理完成之后,IST需要调用InterruptDone来告诉操作系统中断处理结束,操作系统调用OAL中的OEMInterruptDone函数,最后完成中断的处理。

4.在驱动中安装中断的方法:

首先, 在驱动中通过 CreateEvent()函数创建一个 Event 内核对象, 然后通过 InterruptInitialize()

函数负责把某个逻辑中断号与这个 Event 内核对象关联起来。当中断发生时,操作系统负责引发此

Event 事件,函数的原型如下: 

InterruptInitialize(DWORD idInt,         // SYSINTR中断号 

                    HANDLE hEvent ,     // 与该中断相关联的事件句柄 

                    LPVOID pvData,      // 传给OEMInterruptEnable缓冲指针   

DWORD cbData,      // 缓冲区的大小 

                    )

然后通过 CreatThread()函数来来创建一个线程,在线程函数中用 WaitForSingleObject()来阻塞

当前的线程,等待某个 Event 内核对象标识的事件发生。当中断发生后,OAL层就会返回逻辑中断,

与逻辑中断相关联的 Event 事件就会被触发,被阻塞的中断线程函数就会就绪开始工作。 

InterruptDonce()函数用来告诉操作系统, 对该中断的处理已完成, 操作系统可重新开启该中断。

5.步骤:

1.在vs2005里面新建一个DLL的子项目MyKey,在F:/WINCE600/PLATFORM/SMDK6410/SRC/DRIVERS/目录下

2.添加MyKey.c和MyKey.h文件,编辑源程序,如下:

MyKey.h:

#ifndef _MYKEY_H

#define _MYKEY_H

#ifdef  __cplusplus

Extern 'C' {

#endif

typedef struct { 

    volatile S3C6410_GPIO_REG     *pGPIOregs;

    BOOL   FlagExitThrd; 

} KEY_PUBLIC_CONTEXT, *PKEY_PUBLIC_CONTEXT;

#ifdef  __cplusplus

}

#endif

#endif

MyKey.c:

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 'MyKey.h'

#define Led1Mask  0x01

#define Led2Mask  0x02

#define Led3Mask  0x04

#define Led4Mask  0x08

#define LedAllMask 0x0F

#define Butt1Mask  0x01

#define Butt2Mask  0x02

#define Butt3Mask  0x04

#define Butt4Mask  0x08

#define Butt5Mask  0x10

#define Butt6Mask  0x20

static  KEY_PUBLIC_CONTEXT *pPublicKey = NULL;

static volatile UINT32 dwLedFlag   = 1;

UINT32 g_SysIntr1 = 0;

UINT32 g_SysIntr2 = 0;

HANDLE g_hEvent1 = NULL;

HANDLE g_hThread1 = NULL;  

HANDLE g_hEvent2 = NULL;

HANDLE g_hThread2 = NULL; 

/******************************************************************************

 *

 * MyKey button event thread

 *

 *******************************************************************************/

INT WINAPI Button1Thread(void)

{

RETAILMSG(1, (TEXT('Button1 Thread Entered ! /r/n')));

    while(!pPublicKey->FlagExitThrd)

    {

UINT16 ch;

RETAILMSG(1, (TEXT('Button1 KEY_Read: KEY Device Read Successfully./r/n')));

ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT;

RETAILMSG(1,(TEXT('Button1 ReadValue:  0x%x /n'), ch));

    RETAILMSG(1, (TEXT('Button1 Thread ! /r/n'))); 

WaitForSingleObject(g_hEvent1, INFINITE);

if(pPublicKey->FlagExitThrd)

break;

RETAILMSG(1, (TEXT('Button1 Thread Start Running ! /r/n')));

if( dwLedFlag == 1 )

{

dwLedFlag = 0;

pPublicKey->pGPIOregs->GPMDAT |= LedAllMask;

RETAILMSG(1, (TEXT('Button1 pressed---Led ALL On:/r/n')));

}

else

{

dwLedFlag = 1;

pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask;

RETAILMSG(1, (TEXT('Button1 pressed---Led ALL Off:/r/n')));

}

InterruptDone(g_SysIntr1);

    }

    RETAILMSG(1, (TEXT('KEY: KEY Button1Thread Exiting/r/n')));

    return 0;

} // Key_Button1Thread()

INT WINAPI Button2Thread(void)

{

DWORD LedNum = 1;

RETAILMSG(1, (TEXT('Button2 Thread Entered ! /r/n')));

    while(!pPublicKey->FlagExitThrd)

    {

UINT16 ch;

RETAILMSG(1, (TEXT('Button2 KEY_Read: KEY Device Read Successfully./r/n')));

ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT;

RETAILMSG(1,(TEXT('Button2 ReadValue:  0x%x /n'), ch));

    RETAILMSG(1, (TEXT('Button2 Thread ! /r/n'))); 

WaitForSingleObject(g_hEvent2, INFINITE);

if(pPublicKey->FlagExitThrd)

break;

RETAILMSG(1, (TEXT('Button2 Thread Start Running ! /r/n')));

if( LedNum == 1 )

{

LedNum = 2;

pPublicKey->pGPIOregs->GPMDAT |= Led1Mask;

RETAILMSG(1, (TEXT('Button2 pressed---Led 1 on:/r/n')));

}

else if ( LedNum == 2 )

{

LedNum = 3;

pPublicKey->pGPIOregs->GPMDAT |= Led2Mask;;

RETAILMSG(1, (TEXT('Button2 pressed---Led 2 On:/r/n')));

}

else if ( LedNum == 3 )

{

LedNum = 4;

pPublicKey->pGPIOregs->GPMDAT |= Led3Mask;;

RETAILMSG(1, (TEXT('Button2 pressed---Led 3 On:/r/n')));

}

else if ( LedNum == 4 )

{

LedNum = 0;

pPublicKey->pGPIOregs->GPMDAT |= Led4Mask;;

RETAILMSG(1, (TEXT('Button2 pressed---Led 4 On:/r/n')));

}

else

{

LedNum = 1;

pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask;;

RETAILMSG(1, (TEXT('Button2 pressed---Led ALL off:/r/n')));

}

InterruptDone(g_SysIntr2);

    }

    RETAILMSG(1, (TEXT('KEY: KEY Button2Thread Exiting/r/n')));

    return 0;

} // Key_Button2Thread()

BOOL KEY_Deinit(DWORD dwContext)

{

RETAILMSG(1, (TEXT('KEY_DeInit: dwContext = 0x%x/r/n/n'), dwContext));

// inform IST exit status

    pPublicKey->FlagExitThrd = TRUE;

// free virtual memory

if(pPublicKey->pGPIOregs ) 

{

DrvLib_UnmapIoSpace((PVOID)pPublicKey->pGPIOregs);

pPublicKey->pGPIOregs = NULL;

}

if(g_hEvent1)

    {

        SetEvent(g_hEvent1);

        InterruptDisable(g_SysIntr1);

        CloseHandle(g_hEvent1);

    }

if(g_hEvent2)

    {

        SetEvent(g_hEvent2);

InterruptDisable(g_SysIntr2);

        CloseHandle(g_hEvent2);

    }

    // Wait for threads to finish

    WaitForSingleObject(g_hThread1, INFINITE);

if(g_hThread1)

     CloseHandle(g_hThread1);

WaitForSingleObject(g_hThread2, INFINITE);

    if(g_hThread2)

     CloseHandle(g_hThread2);

LocalFree(pPublicKey);

    return (TRUE);

}

PKEY_PUBLIC_CONTEXT KEY_Init(DWORD dwContext)

{

LPTSTR                     ActivePath = (LPTSTR) dwContext; // HKLM/Drivers/Active/xx

    BOOL                       bResult = TRUE;

    DWORD                      dwHwIntr = 0;

RETAILMSG(1, (TEXT('KEY_Init:dwContext = 0x%x/r/n'), dwContext));

    RETAILMSG(1,(TEXT('[KEY] Active Path : %s/n'), ActivePath));

    if ( !(pPublicKey = (PKEY_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(KEY_PUBLIC_CONTEXT) )) )

    {

        RETAILMSG(1,(TEXT('[KEY] Can't not allocate for KEY Context/n')));

        return NULL;

    }

    // GPIO Virtual alloc

    pPublicKey->pGPIOregs = (volatile S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE);

    if (pPublicKey->pGPIOregs == NULL)

[1] [2] [3]
关键字:Windows  中断实验  S3C6410 引用地址:Windows CE6.0中断实验过程

上一篇:基于gnu-arm-linux的LPC2220的简单工程模板
下一篇:基于ARM7(LPC2131)平台的μC/OS-Ⅱ的移植

推荐阅读最新更新时间:2026-03-21 10:49

《逗比小憨憨51单片机Proteus仿真系列》第5期单片机的定时器中断实验仿真
源代码: #include reg51.h typedef unsigned char u8; typedef unsigned int u16; sbit dula = P2^6; sbit wela = P2^7; sbit led = P1^0; u8 code table ={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; u8 num,num1,num2,sh
[单片机]
51单片机的外部中断实验设计
51单片机的外设究竟该怎样理解?做以下实验。 实验1:外部中断0的实验 实验步骤:将一根杜邦线的一端接到P3^2口上,另一端接电源或者地 实验程序: #include sbit led = P1^0; void mian(void) { while(1){ if(IE0){ led = 0; } else{ led = 1; } } } 实验结果:当杜邦线另一端接电源时,led灭;当接地时,led就亮 结论:无论配置与否,51单片机的外部中断这个外设都在工作着,不可能禁止 实验2:定时器0的实验 实验程序: #include sbit led = P1^0; void main(void) { TR0 =1; while(
[单片机]
51单片机的外部<font color='red'>中断实验</font>设计
简单外中断实验(最近又要搞arm相关的东西,复习一下中断)
程序烧写在norflash上面 Makefile mem_controler.bin : start.s function.c arm-linux-gcc -g -c -o start.o start.s arm-linux-gcc -g -c -o function.o function.c arm-linux-ld -Ttext 0x30000000 -g start.o function.o -o interrupt.elf arm-linux-objcopy -O binary -S interrupt.elf interrupt.bin arm-linux-objdump -D -m
[单片机]
51单片机之中断实验
什么叫中断: 中断是指CPU在执行当前程序的过程中,由于某种随机出现的外设请求或CPU内部的异常事件,使CPU暂停正在执行的程序而转去 执行相应的服务处理程序;当服务处理程序运行完毕后,CPU再返回到暂停处继续执行原来的程序。 单片机在执行程序时其程序流程图 引起CPU中断的根源,称为中断源,中断源向CPU提出中断请求,CPU暂时中断原来的事务A,转去处理事件B,对事件B处理完毕后,再回到原来被中断的地方(即断点),称为中断返回。实现上述中断功能的部件称为中断系统(中断机构)。中断的开启与关闭、设置启用哪一个中断等都是由单片机内部的一些特殊功能寄存器来决定的。 当CPU正在处理一个中断源请求的时候(执行相应的中断服务程
[单片机]
51单片机之<font color='red'>中断实验</font>
MSP430G2553定时器中断实验
/////////////////////////////////////////////////////////////////// // msp430G2553的定时器中断控制LED每秒钟进行亮熄变化 /////////////////////////////////////////////////////////////////// #include void led_init(); void timer_init(); void delay(int); //---------------------------------- void led_init() { P1DIR|=(1 6); //P1.6为LED } //--
[单片机]
使用STM32CubeMX开发三:按键中断实验
硬件平台:stm32F407Zet6 软件平台:stm32cubeMX 4.7+MDK5.14 电路连接:PE8-LED0、PE9-LED1、PE10-LED2、PE11-LED3、PE12-KEY0、PE13-KEY1、PE14-KEY2、PE15-KEY3 第一步、使用stm32cubeMX创建工程,选择相应的芯片,配置RCC、SYS、引脚和时钟如下图所示: 注意,由于按键上有上拉电阻,这里选择中断模式的时候,我们选择下降沿触发中断。 第二步,配置输出Keil工程 第三步、编写程序下载验证 STM32CubeMx把代码都生成了,查找函数,分析调用的过程,添加应用层代码就
[单片机]
使用STM32CubeMX开发三:按键<font color='red'>中断实验</font>
STM32F107的通用定时器中断实验总结
1. STM32F107的通用定时器是指: TIM2、TIM3、TIM4、TIM5、 STM32F107的高级定时器是指: TIM1、TIM8 STM32F107的基本定时器是指: TIM6、TIM7 2. STM32F107的通用定时器(TIM2、TIM3、TIM4、TIM5)的模式有向上计数、向下计数、中央对齐模式。 向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。 向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。 中央对齐模式(向上/向下计数):计数器
[单片机]
Tiny210驱动之按键中断实验
third_drv.c驱动源码: #include linux/device.h #include linux/interrupt.h #include linux/module.h #include linux/kernel.h #include linux/fs.h #include linux/init.h #include linux/delay.h #include linux/irq.h #include asm/uaccess.h #include asm/irq.h #include asm/io.h #include mach/gpio.h static struct class *thi
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved