• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            唐吉訶德

              C++博客 :: 首頁 :: 聯系 :: 聚合  :: 管理
              5 Posts :: 75 Stories :: 3 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(2)

            我參與的團隊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            Windows Embedded CE 6.0的中斷處理過程主要分為兩部分:

            •  中斷服務例程(ISR):處于內核中的低級處理程序,中斷發生時首先被調用。
            • 中斷服務線程(IST):處于驅動或者應用中的中斷處理線程,由系統調度,完成大部分的中斷處理工作。

            ISR的實現在OALOEM適配層)中,它只處理最低級的中斷響應,通常是獲取IRQSYSINTR并設置MCU內部的中斷控制寄存器。中斷處理的主要部分在驅動或者應用的中斷處理線程中。中斷處理線程與其他普通線程一樣,使用同一個線程優先級管理系統。ISRIST之間通過事件對象進行同步。IST中創建一個事件對象,并使用函數WaitForSingleObject()等待該事件被觸發。ISR中通知內核觸發相應的事件對象。Windows Embedded CE 6.0的中斷處理的過程如下圖所示。

                                  Windows Embedded CE 6.0的中斷處理過程

              在其他的一些嵌入式操作系統中,在介紹中斷處理時經常會提到一個中斷向量表的概念,如uC/OS。當中斷發生時它會進入IRQ的處理程序,并根據IRQ的值跳轉到事先分配好的中斷向量表相應的中斷處理函數中。但在WinCE中實際上并不存在中斷向量表的概念,而只有一個異常向量表,對應于MCU的幾種運行模式。WinCE的中斷處理對應于兩個異常IRQHandlerFIQHandler,通常我們使用的是IRQHandler。當外部中斷產生時,系統執行IRQHandler(),IRQHandler()中調用OEMInterruptHandler()獲取IRQ對應的SYSINTR,然后根據SYSINTR調用函數OEMNotifyIntrOccurs()觸發與SYSINTR關聯的事件,最后由IST完成主要的中斷處理工作。這種中斷處理機制在一定程度上影響了系統的實時性,但提高了IST的靈活性。有關WinCE系統實時性分析,將在另外一篇中描述。

                 下面結合C:\WINCE600\PLATFORM\DEVICEEMULATOR\SRC\DRIVERSPWRBUTTON驅動進行分析。該驅動也是一個流驅動,所以可以用驅動調試助手進行動態加載和卸載,但需要對代碼進行相應的修改,否則會出問題。

                首先看PBT_Init()函數,代碼如下:


            DWORD
            PBT_Init(DWORD dwContext)
            {
                DWORD   IDPowerButtonThread;
                DWORD   IDResetButtonThread;
                HMODULE hmCore;

                
            //
                
            // 從CORE Library中獲取電源管理器"SetSystemPowerState"的函數指針/
                pfnSetSystemPowerState = NULL;

                hmCore 
            = (HMODULE) LoadLibrary(_T("coredll.dll"));

                
            if(hmCore != NULL)
                
            {
                    pfnSetSystemPowerState 
            = (PFN_SetSystemPowerState) GetProcAddress(hmCore, _T("SetSystemPowerState"));

                    
            if(pfnSetSystemPowerState == NULL)
                    
            {
                        FreeLibrary(hmCore);
                    }

                }


                
            //初始化相關的虛擬內存地址
                InitializeAddresses();

                
            // 創建POWER Button的IST和RESET Button的IST
                ResetButtonIntrThreadHandle = CreateThread(00, (LPTHREAD_START_ROUTINE) ResetButtonIntrThread, 00&IDResetButtonThread);
                
            if (ResetButtonIntrThreadHandle == 0)
                
            {
                    RETAILMSG(
            1, (TEXT("PBT: CreateThread() Fail\r\n")));
                }

                PowerButtonIntrThreadHandle 
            = CreateThread(00, (LPTHREAD_START_ROUTINE) PowerButtonIntrThread, 00&IDPowerButtonThread);
                
            if (PowerButtonIntrThreadHandle == 0)
                
            {
                    RETAILMSG(
            1, (TEXT("PBT: CreateThread() Fail\r\n")));
                }


                
            return (dwContext);
            }

                  RESET ButtonISTPOWER ButtonIST基本一致,所以這里只分析POWER ButtonIST,代碼如下。      


            static DWORD
            PowerButtonIntrThread(PVOID pArg)
            {
                
            //初始化中斷寄存器,使能相應的中斷
                EnablePowerButtonInterrupt();

                
            //創建一個事件
                PwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                
            //
                
            // 根據IRQ獲取一個SYSINTR
                
            //
                if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &PwrButtonIrq, sizeof PwrButtonIrq, &PwrButtonSysIntr, sizeof PwrButtonSysIntr, NULL))
                
            {
                    RETAILMSG(
            1, (TEXT("PBT: Error! Failed to request sysintr value for power button interrupt.\r\n")));
                    
            return(0);
                }

                
                
            //關聯SYSINTR和之前創建的事件
                if (!(InterruptInitialize(PwrButtonSysIntr, PwrButtonIntrEvent, 00)))
                
            {
                    RETAILMSG(
            1, (TEXT("ERROR: PwrButton: Interrupt initialize failed.\r\n")));
                }


                
            //POWER Button按下的處理程序
                for (;;)
                
            {
                    WaitForSingleObject(PwrButtonIntrEvent, INFINITE);
                    
                    
            if (PowerButtonIsPushed()) //確認按鍵確實被按下,消除抖動
                    {
                        Sleep(
            200);         //延遲200ms,排除長按的情況
                        if (!PowerButtonIsPushed())    //按鍵被有效釋放
                        {
                            
            //
                            
            //關閉系統 
                            
            //
                            if(pfnSetSystemPowerState != NULL)
                            
            {
                                RETAILMSG(
            1,(TEXT("PBT: Signalling power manager to suspend\r\n")));
                                pfnSetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
                            }
             else {
                                RETAILMSG(
            1,(TEXT("PBT: Suspending by calling PowerOffSystem\r\n")));
                                PowerOffSystem();
                            }

                            
            //
                            
            //結束當前線程的時間片
                            Sleep(0);
                        }

                        
            else
                            RETAILMSG(
            1,(TEXT("PBT: Button held too long (ignored)\r\n")));
                    }

                    
            else
                        RETAILMSG(
            1,(TEXT("PBT: Feeble button press or noise triggered it (ignored)\r\n")));

                    InterruptDone(PwrButtonSysIntr);
                }

            }

                以上代碼結構清晰,不再贅述。但這樣編譯出來的驅動是不能通過驅動調試助手動態加載的,必須進行相應的修改才行。主要原因是沒有善始善終,分配的系統邏輯中斷沒有釋放,系統邏輯中斷與事件的關聯也沒有取消。實驗現象是,能通過驅動調試助手加載卸載,但中斷并不能正常工作了。下面介紹一下解決這個問題的辦法。

              首先定義一個全局變量g_bThreadExit初始化為FALSE。IST修改后的代碼如下:


            static DWORD
            PowerButtonIntrThread(PVOID pArg)
            {
            //初始化中斷寄存器,使能相應的中斷
                EnablePowerButtonInterrupt();

                
            //創建一個事件
                PwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

                
            //
                
            // 根據IRQ獲取一個SYSINTR
                
            //
                if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &PwrButtonIrq, sizeof PwrButtonIrq, &PwrButtonSysIntr, sizeof PwrButtonSysIntr, NULL))
                
            {
                    RETAILMSG(
            1, (TEXT("PBT: Error! Failed to request sysintr value for power button interrupt.\r\n")));
                    
            return(0);
                }

                
                
            //關聯SYSINTR和之前創建的事件
                if (!(InterruptInitialize(PwrButtonSysIntr, PwrButtonIntrEvent, 00)))
                
            {
                    RETAILMSG(
            1, (TEXT("ERROR: PwrButton: Interrupt initialize failed.\r\n")));
                }

                
                
            // POWER Button按下的處理程序
                for (;;)
                
            {
                    WaitForSingleObject(PwrButtonIntrEvent, INFINITE);
                            
                    
            if(g_bThreadExit)
                    
            {
                        
            break;    
                    }


                    
            if (PowerButtonIsPushed())     //確認按鍵確實被按下,消除抖動
                    {
                        Sleep(
            200);         //延遲ms,排除長按的情況
                        if (!PowerButtonIsPushed())    //按鍵被有效釋放
                        {
                            
            //
                            
            //關閉系統
                            
            //
                            if(pfnSetSystemPowerState != NULL)
                            
            {
                                RETAILMSG(
            1,(TEXT("PBT: Signalling power manager to suspend\r\n")));
                                pfnSetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
                            }
             else {
                                RETAILMSG(
            1,(TEXT("PBT: Suspending by calling PowerOffSystem\r\n")));
                                PowerOffSystem();
                            }

                            
            //
                            
            //結束當前線程的時間片
                            
            //
                            Sleep(0);
                        }

                        
            else
                            RETAILMSG(
            1,(TEXT("PBT: Button held too long (ignored)\r\n")));
                    }

                    
            else
                        RETAILMSG(
            1,(TEXT("PBT: Feeble button press or noise triggered it (ignored)\r\n")));

                    InterruptDone(PwrButtonSysIntr);
                }

                
                
            //取消IRQ與SYSINTR之間的關聯
                KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&PwrButtonSysIntr, sizeof(UINT32),NULL,0, NULL);
                
                
            //取消Event與PwrButtonSysIntr之間的關聯
                InterruptDisable(PwrButtonSysIntr);

                CloseHandle(PwrButtonIntrEvent);
                
                RETAILMSG(
            1, (TEXT("PowerButtonIntrThread Exit.\r\n")));
                
            return 0;
            }

              PBT_Deinit()修改后的代碼如下:


            BOOL
            PBT_Deinit(DWORD dwContext)
            {
                RETAILMSG(
            1, (TEXT("PBT: PBT_Deinit()\r\n")));
                
            //設置退出線程的標志
            g_bThreadExit = TRUE;
                
            //模擬一個中斷事件
            SetInterruptEvent(PwrButtonSysIntr);
                
            //延遲500ms,確保IST退出
            Sleep(500);

                
            return (TRUE);
            }

              經過以上修改,該中斷驅動程序就可以通過驅動調試助手動態加載和卸載,并能正常工作了。另外,在模擬器中由于沒有外部中斷按鍵,可以通過創建一個特定名稱的事件與中斷關聯,并在另外一個應用或者驅動中設置該事件以模擬一個外部中斷按鍵的觸發,這種方法也可以在實際平臺中根據需要使用。示例代碼如下:


            //打開與中斷關聯的事件
            gIntrEvent = CreateEvent(NULL, FALSE, FALSE, _T("PBTINTR"));
            //設置該事件,模擬一個中斷的觸發
            SetEvent(gIntrEvent);
            IST中創建與中斷關聯的事件代碼修改如下:
            PwrButtonIntrEvent 
            = CreateEvent(NULL, FALSE, FALSE, _T("PBTINTR"));

              總的來說,WinCE中斷處理過程結構清晰,方便開發人員靈活設計IST。在使用驅動調試助手調試有關中斷的驅動程序時,需要善始善終,否則會出現中斷不能正常工作的情況。

            posted on 2011-03-01 10:55 心羽 閱讀(747) 評論(0)  編輯 收藏 引用 所屬分類: wince
            久久精品99久久香蕉国产色戒 | 久久国产乱子伦免费精品| 色狠狠久久AV五月综合| 国产精品久久久亚洲| 一本久久a久久精品综合夜夜| 久久免费美女视频| 久久久久久国产精品美女| 亚洲国产精品成人久久蜜臀| 亚洲中文字幕无码一久久区| 97超级碰碰碰久久久久| 久久久久女教师免费一区| 亚洲综合日韩久久成人AV| 99久久婷婷国产综合精品草原| 久久天天日天天操综合伊人av| 久久国产高潮流白浆免费观看| 热久久国产欧美一区二区精品| 久久99精品久久久久久久久久| 欧美性大战久久久久久| 9久久9久久精品| 久久精品国产亚洲αv忘忧草| 亚洲精品国产成人99久久| 一本一本久久a久久综合精品蜜桃| 欧美久久久久久午夜精品| 久久久久AV综合网成人| 中文字幕精品无码久久久久久3D日动漫| 麻豆亚洲AV永久无码精品久久| 亚洲午夜无码久久久久小说 | 99久久国产亚洲高清观看2024| 色偷偷88888欧美精品久久久| 亚洲精品tv久久久久| 久久国产综合精品五月天| 91精品日韩人妻无码久久不卡| 精品久久久久久无码中文字幕一区| 精品久久久无码21p发布| 2020国产成人久久精品| 热RE99久久精品国产66热| 亚洲国产精品成人久久蜜臀| 欧美午夜A∨大片久久| 久久精品一区二区三区AV| 亚洲欧美伊人久久综合一区二区| 久久婷婷是五月综合色狠狠|