Chinaunix首页 | 论坛 | 博客
  • 博客访问: 234629
  • 博文数量: 60
  • 博客积分: 1509
  • 博客等级: 上尉
  • 技术积分: 882
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-15 10:30
文章分类

全部博文(60)

文章存档

2012年(2)

2011年(58)

分类: 嵌入式

2011-03-08 15:27:03

    处理应用程序或驱动程序的中断需要两个步骤。首先,中断必须使用关联的事件进行初始化。其次,IST 必须等待响应内核中断的中断事件。以下是我在做平时应用中的一个例子。
 
一、中断初始化。简单来说,主要有以下步骤
    首先定义一个中断信息结构体,用于提供中断和线程的信息。
  1. //中断信息
  2. typedef struct tagINSTINFO{
  3.     HANDLE m_hIntThread; //中断处理线程
  4.     HANDLE m_hIntEvent;  //事件
  5.     BOOL m_bRunning;     //是否在运行
  6. } INTRINFO, *LPINTRINFO;
    然后创建事件
  1. //创建事件
  2.     s_TIMER1.m_hIntEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
    事件创建以后,创建一个线程用于等待事件的发生,事件何时何怎么发生呢?在下面会有提到。之所以要创建挂起的 IST (中断服务线程),是因为如果创建不挂起的IST的话可能会导致 InterruptInitialize 失败,因为该事件已经处于等待状态。
  1. //创建等待信号线程
  2.     s_TIMER1.m_hIntThread = ::CreateThread(
  3.         NULL, 0,
  4.         TIMER1ThreadIST,
  5.         NULL,
  6.         CREATE_SUSPENDED,
  7.         NULL
  8.     );
    线程创建以后,由于我这里用了CREATE_SUSPENDED,线程就会调用WaitForSingleObject一直的等待,等待有人把他唤醒。该怎么唤醒,这就是接下来这一步要做的。我接下来调用InterruptInitialize函数把定时器1中断与上文创建的事件绑定,绑定之后当定时器1中断发生时,即触发中断,进而激活事件,WaitForSingleObject等待结束,上文创建的中断线程也得以运行。
  1.   InterruptInitialize(
  2.             SYSINTR_TIMER1,
  3.             s_TIMER1.m_hIntEvent,
  4.             NULL,
  5.             0))
    整个过程的实现代码如下:
  1. //中断信息
  2. typedef struct tagINSTINFO{

  3.     HANDLE    m_hIntThread;    //中断处理线程
  4.     HANDLE    m_hIntEvent;        //事件
  5.     BOOL    m_bRunning;        //是否在运行

  6. } INTRINFO, *LPINTRINFO;

  7. static INTRINFO s_TIMER1 = {NULL, NULL, TRUE};

  8. BOOL StartupTIMER1Interrupt(VOID)                //启动定时器1中断线程
  9. {
  10.     //创建事件
  11.     s_TIMER1.m_hIntEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);

  12.     if (s_TIMER1.m_hIntEvent == NULL)
  13.         return FALSE;

  14.     //创建等待信号线程
  15.     s_TIMER1.m_hIntThread = ::CreateThread(
  16.         NULL, 0,
  17.         TIMER1ThreadIST,
  18.         NULL,
  19.         CREATE_SUSPENDED,
  20.         NULL
  21.     );

  22.     if (s_TIMER1.m_hIntThread == NULL)
  23.         return FALSE;

  24.     //初始化中断,InterruptInitialize把定时器1中断与上文创建的事件绑定,
  25.     //当定时器1中断发生时,即触发中断,进而激活事件,上文创建的线程也得以运行。
  26.     if (::InterruptInitialize(
  27.             SYSINTR_TIMER1,
  28.             s_TIMER1.m_hIntEvent,
  29.             NULL,
  30.             0))
  31.     {
  32.         //设置线程优先级
  33.         ::CeSetThreadPriority(
  34.             s_TIMER1.m_hIntThread,
  35.             PRIORITY_TIMER1
  36.         );

  37.         //启动线程
  38.         ::ResumeThread(s_TIMER1.m_hIntThread);
  39.     }

  40.     s_TIMER1.m_bRunning = TRUE;
  41.     return TRUE;
  42. }
    中断线程函数如下
  1. DWORD TIMER1ThreadIST(LPVOID lpdata)            //时钟1中断线程函数
  2. {
  3.     DWORD dwStatus;
  4.     INT i;

  5.     while (s_TIMER1.m_bRunning)
  6.     {
  7.         dwStatus = ::WaitForSingleObject(
  8.             s_TIMER1.m_hIntEvent,
  9.             INFINITE
  10.         );

  11.         if (!s_TIMER1.m_bRunning)    break;
  12.     
  13.         if (dwStatus == WAIT_OBJECT_0)
  14.         {    
  15.             if (g_systemStatus.m_playingRscan)
  16.             {
  17.                 g_systemInfo.m_playCounter++;
  18.             }
  19.     
  20.             g_timer1Counter++;
  21.             g_gatherInfo.m_readEnabled = FALSE;

  22.             if (!g_systemStatus.m_freezeState)
  23.             {
  24.                 i = IOMEMADDR(IO_ULTRASOINC_PULSER_R);
  25.             }

  26.             ::InterruptDone(SYSINTR_TIMER1);    
  27.         }
  28.     }

  29.     return 0;
  30. }
    ps:这里没有把全部变量和函数的定义写出来。


阅读(3110) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~