• <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++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
              5 Posts :: 75 Stories :: 3 Comments :: 0 Trackbacks

            常用鏈接

            留言簿(2)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

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

            •  中斷服務(wù)例程(ISR):處于內(nèi)核中的低級處理程序,中斷發(fā)生時首先被調(diào)用。
            • 中斷服務(wù)線程(IST):處于驅(qū)動或者應(yīng)用中的中斷處理線程,由系統(tǒng)調(diào)度,完成大部分的中斷處理工作。

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

                                  Windows Embedded CE 6.0的中斷處理過程

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

                 下面結(jié)合C:\WINCE600\PLATFORM\DEVICEEMULATOR\SRC\DRIVERSPWRBUTTON驅(qū)動進(jìn)行分析。該驅(qū)動也是一個流驅(qū)動,所以可以用驅(qū)動調(diào)試助手進(jìn)行動態(tài)加載和卸載,但需要對代碼進(jìn)行相應(yīng)的修改,否則會出問題。

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


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

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

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

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

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

                }


                
            //初始化相關(guān)的虛擬內(nèi)存地址
                InitializeAddresses();

                
            // 創(chuàng)建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)
            {
                
            //初始化中斷寄存器,使能相應(yīng)的中斷
                EnablePowerButtonInterrupt();

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

                
            //
                
            // 根據(jù)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);
                }

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


                
            //POWER Button按下的處理程序
                for (;;)
                
            {
                    WaitForSingleObject(PwrButtonIntrEvent, INFINITE);
                    
                    
            if (PowerButtonIsPushed()) //確認(rèn)按鍵確實(shí)被按下,消除抖動
                    {
                        Sleep(
            200);         //延遲200ms,排除長按的情況
                        if (!PowerButtonIsPushed())    //按鍵被有效釋放
                        {
                            
            //
                            
            //關(guān)閉系統(tǒng) 
                            
            //
                            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();
                            }

                            
            //
                            
            //結(jié)束當(dāng)前線程的時間片
                            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);
                }

            }

                以上代碼結(jié)構(gòu)清晰,不再贅述。但這樣編譯出來的驅(qū)動是不能通過驅(qū)動調(diào)試助手動態(tài)加載的,必須進(jìn)行相應(yīng)的修改才行。主要原因是沒有善始善終,分配的系統(tǒng)邏輯中斷沒有釋放,系統(tǒng)邏輯中斷與事件的關(guān)聯(lián)也沒有取消。實(shí)驗(yàn)現(xiàn)象是,能通過驅(qū)動調(diào)試助手加載卸載,但中斷并不能正常工作了。下面介紹一下解決這個問題的辦法。

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


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

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

                
            //
                
            // 根據(jù)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);
                }

                
                
            //關(guān)聯(lián)SYSINTR和之前創(chuàng)建的事件
                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())     //確認(rèn)按鍵確實(shí)被按下,消除抖動
                    {
                        Sleep(
            200);         //延遲ms,排除長按的情況
                        if (!PowerButtonIsPushed())    //按鍵被有效釋放
                        {
                            
            //
                            
            //關(guān)閉系統(tǒng)
                            
            //
                            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();
                            }

                            
            //
                            
            //結(jié)束當(dāng)前線程的時間片
                            
            //
                            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之間的關(guān)聯(lián)
                KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR,&PwrButtonSysIntr, sizeof(UINT32),NULL,0, NULL);
                
                
            //取消Event與PwrButtonSysIntr之間的關(guān)聯(lián)
                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")));
                
            //設(shè)置退出線程的標(biāo)志
            g_bThreadExit = TRUE;
                
            //模擬一個中斷事件
            SetInterruptEvent(PwrButtonSysIntr);
                
            //延遲500ms,確保IST退出
            Sleep(500);

                
            return (TRUE);
            }

              經(jīng)過以上修改,該中斷驅(qū)動程序就可以通過驅(qū)動調(diào)試助手動態(tài)加載和卸載,并能正常工作了。另外,在模擬器中由于沒有外部中斷按鍵,可以通過創(chuàng)建一個特定名稱的事件與中斷關(guān)聯(lián),并在另外一個應(yīng)用或者驅(qū)動中設(shè)置該事件以模擬一個外部中斷按鍵的觸發(fā),這種方法也可以在實(shí)際平臺中根據(jù)需要使用。示例代碼如下:


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

              總的來說,WinCE中斷處理過程結(jié)構(gòu)清晰,方便開發(fā)人員靈活設(shè)計IST。在使用驅(qū)動調(diào)試助手調(diào)試有關(guān)中斷的驅(qū)動程序時,需要善始善終,否則會出現(xiàn)中斷不能正常工作的情況。

            posted on 2011-03-01 10:55 心羽 閱讀(760) 評論(0)  編輯 收藏 引用 所屬分類: wince
            久久精品综合一区二区三区| 久久精品国产精品亚洲艾草网美妙| 亚洲精品乱码久久久久久不卡| 亚洲欧美国产日韩综合久久| 久久久久国产精品人妻| 久久久久99精品成人片直播| 色成年激情久久综合| 久久精品国产99久久久古代| 99久久er这里只有精品18| 国产亚州精品女人久久久久久 | 久久久久久久久久久久中文字幕 | 色诱久久久久综合网ywww| 伊人久久综在合线亚洲2019| 深夜久久AAAAA级毛片免费看| 久久久精品人妻一区二区三区蜜桃| 久久精品国产亚洲沈樵| 久久久久国产精品嫩草影院| 伊人久久免费视频| 久久久久亚洲av无码专区喷水| 亚洲伊人久久成综合人影院 | 久久香蕉国产线看观看99| 伊人久久精品无码av一区| 久久国产成人午夜AV影院| 精品999久久久久久中文字幕| 亚洲色欲久久久综合网东京热| 日韩久久无码免费毛片软件| 国产精品禁18久久久夂久| 亚洲精品无码久久千人斩| 99精品国产综合久久久久五月天| 青青久久精品国产免费看| 久久精品国产亚洲一区二区| 久久精品国产亚洲av高清漫画| 伊人久久大香线焦AV综合影院 | 青青青国产成人久久111网站| 狠狠综合久久综合88亚洲| 久久www免费人成看国产片| 精品国产91久久久久久久a| 久久久久久久亚洲Av无码| 久久发布国产伦子伦精品| 久久99精品久久久久久动态图| 亚洲AV日韩精品久久久久久久|