• <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>

            Do What You think !!

             

            (轉(zhuǎn))WinCE驅(qū)動(dòng)開發(fā)問題精華集錦

            如何讓系統(tǒng)加載自己寫的驅(qū)動(dòng)程序?  
            兩種辦法: 
            1、在[HKEY_LOCAL_MACHINE\Drivers\BuiltIn]下添加注冊(cè)鍵。 
            2、在應(yīng)用程序中調(diào)用ActivateDeviceEx。 
             
             在一些文件中用分號(hào)來(lái)表示注釋,例如下面的內(nèi)容  
            ; @CESYSGEN IF SERVERS_MODULES_HTTPD 
            ; @CESYSGEN ENDIF 
            在“CESYSGEN...”前加了“@”,有沒有什么特別的含義? 
            在WINCE的一些文件中,用“;”作為注釋并在注釋文字中用@CESYSGEN作為標(biāo)記,后面接條件語(yǔ)句。Cefilter.exe工具負(fù)責(zé)按照條件來(lái)篩選文件內(nèi)容,所以不要輕易地刪除包含@CESYSGEN的注釋語(yǔ)句。 
             
             通過串口建立ActiveSync聯(lián)接,串口線用三線的可以嗎?  
            不可以,因?yàn)橛么谕綍r(shí)要用到其余口的狀態(tài)。 

              
                 WINCE是否支持MAPI? 
            不支持。WINCE自帶的pmail.exe軟件也不是很好用。建議自開發(fā)郵件收發(fā)軟件。如果需要購(gòu)買WINCE下郵件收發(fā)軟件可以聯(lián)系我。 
             
             如何旋轉(zhuǎn)屏幕顯示的內(nèi)容? 
            例子代碼如下(前提是顯示驅(qū)動(dòng)程序支持旋轉(zhuǎn)): 
            DEVMODE  devmode = {0}; 
             devmode.dmSize = sizeof(DEVMODE); 
             devmode.dmDisplayOrientation = DMDO_90;       ///垂直模式 
             devmode.dmFields = DM_DISPLAYORIENTATION; 
             ChangeDisplaySettingsEx(NULL, &devmode, NULL, 0, NULL);  ///改變顯示的設(shè)置 
             CRect  rcWorkArea(0, 0, 320, 240);    ///整個(gè)屏幕尺寸 
             ///設(shè)置客戶區(qū)大小并廣播消息,這樣所有軟件也就隨之更改顯示 
             SystemParametersInfo(SPI_SETWORKAREA, 0, (void*)&rcWorkArea, SPIF_SENDCHANGE);  
             
             請(qǐng)問如何修改字形緩存的容量? 
            [HKEY_LOCAL_MACHINE\System\GDI\GLYPHCACHE] 
            "limit"=dword:0400 
             
             如何得到從WINCE啟動(dòng)開始到現(xiàn)在的時(shí)間? 
            調(diào)用API GetTickCount,得到的值為32位整數(shù),單位為毫秒。 
             
             如何調(diào)用WINCE的軟鍵盤?
             
            調(diào)用API SipShowIM(SIPF_ON),前提是內(nèi)核加入了軟鍵盤組件。 
             
             基于HIVE的注冊(cè)表,如何在系統(tǒng)關(guān)閉前保存注冊(cè)表的數(shù)據(jù)到文件system.hv? 
            調(diào)用API RegFlushKey函數(shù)。 
             
             使用VirtualAlloc和VirtualCopy的時(shí)候需要注意哪些事項(xiàng)? 
            1、VirtualAlloc的作用是申請(qǐng)?zhí)摂M地址空間,這肯定不是最終的目的,最終目的可能是申請(qǐng)物理內(nèi)存、映射寄存器、提交文件等。沒有一個(gè)目的會(huì)在意虛擬地址空間的位置,所以盡量傳遞參數(shù)1為0,也就是讓W(xué)INCE自動(dòng)分配虛擬地址空間。VirtualAlloc分配地址空間實(shí)際上是以64KB為單位,所以要指定申請(qǐng)的虛擬空間的首地址的話,參數(shù)1應(yīng)該為64KB的整數(shù)倍,申請(qǐng)的長(zhǎng)度也應(yīng)該為64KB的整數(shù)倍,即使你不需要那么大。 
            2、VirtualCopy的主要作用是映射物理地址空間,如果參數(shù)2為物理地址,那么最后一個(gè)參數(shù)要添加PAGE_PHYSICAL,參數(shù)2必須是256的整數(shù)倍。如果參數(shù)2為虛擬地址(0x80000000以上),那么最后一個(gè)參數(shù)就不要添加PAGE_PHYSICAL,WINCE內(nèi)核會(huì)根據(jù)這個(gè)虛擬地址找到對(duì)應(yīng)的物理地址。 
             
             驅(qū)動(dòng)程序和應(yīng)用程序之間傳遞數(shù)據(jù)時(shí)何時(shí)調(diào)用MapPtrToProcess? 
            因?yàn)樵O(shè)備管理器負(fù)責(zé)加載驅(qū)動(dòng)程序DLL,這意味著當(dāng)應(yīng)用程序調(diào)用驅(qū)動(dòng)程序接口函數(shù)的時(shí)候,WINCE內(nèi)核會(huì)將調(diào)用驅(qū)動(dòng)程序接口函數(shù)的線程轉(zhuǎn)移到設(shè)備管理器的進(jìn)程空間然后執(zhí)行具體的驅(qū)動(dòng)程序代碼,應(yīng)用程序和設(shè)備管理器處于兩個(gè)進(jìn)程空間,這就造成設(shè)備管理器無(wú)法訪問應(yīng)用程序傳遞的指針(虛擬地址),所以當(dāng)我們?cè)趹?yīng)用程序中傳遞指針給流驅(qū)動(dòng)程序接口函數(shù)時(shí),WINCE內(nèi)核從中作了一個(gè)地址映射,例如ReadFile、WriteFile、DeviceIoControl函數(shù)的參數(shù)凡是指針都經(jīng)過了映射才傳遞給驅(qū)動(dòng)程序,所以很多驅(qū)動(dòng)程序開發(fā)者并不了解其中的奧秘就可以編程了。但是如果參數(shù)是一個(gè)指向一個(gè)結(jié)構(gòu)體的指針,而結(jié)構(gòu)體里包括一個(gè)或多個(gè)指針,那么WINCE內(nèi)核并不負(fù)責(zé)映射,所以就需要開發(fā)者在驅(qū)動(dòng)程序接口函數(shù)中調(diào)用API函數(shù)MapPtrToProcess來(lái)映射地址。例如:pPointer_retval = MapPtrToProcess(pPointer, GetCallerProcess());  
             
             如何判斷可插拔的設(shè)備是否存在? 
            1、通過查找注冊(cè)表的值。凡是由API ActivateDeviceEx加載的驅(qū)動(dòng)程序都在[HKEY_LOCAL_MACHINE\Drivers\Active]鍵下有注冊(cè)鍵,通過查找“name”或者其它鍵值就能夠找到。設(shè)備管理器就調(diào)用這個(gè)API。如果是PCI設(shè)備,在注冊(cè)表[HLM\Drivers\BuiltIn\PCI\Instance]下查找關(guān)鍵字,例如[HLM\Drivers\BuiltIn\PCI\Instance\WaveDev1],說明音頻驅(qū)動(dòng)已經(jīng)加載。 
            2、調(diào)用驅(qū)動(dòng)程序接口函數(shù),根據(jù)返回值或者執(zhí)行結(jié)果來(lái)判斷。 
             
             如何做到通過串口過來(lái)的一個(gè)信號(hào)啟動(dòng)自己開發(fā)的應(yīng)用程序? 
            創(chuàng)建一個(gè)線程負(fù)責(zé)等待串口過來(lái)的信號(hào),調(diào)用API SetCommMask設(shè)置要等待的信號(hào)種類,具體可以等待的信號(hào)種類參見參數(shù)2的說明。然后再調(diào)用API WaitCommEvent函數(shù)等待這個(gè)信號(hào),接收之后再調(diào)用API CreateProcess啟動(dòng)應(yīng)用程序。 
             
             在WINCE中如何只能啟動(dòng)應(yīng)用程序的一個(gè)實(shí)例? 
            常用的兩種辦法: 
            1、如果應(yīng)用程序?qū)嵗齽?chuàng)建了窗口,可通過API FindWindow函數(shù)通過窗口類名和窗口標(biāo)題名稱來(lái)查找,前提是系統(tǒng)內(nèi)不會(huì)出現(xiàn)窗口名稱重復(fù)的情況。 
            2、應(yīng)用程序初始化的時(shí)候創(chuàng)建一個(gè)事件或互斥等內(nèi)核對(duì)象,因?yàn)閮?nèi)核對(duì)象是由內(nèi)核創(chuàng)建,名稱在系統(tǒng)內(nèi)唯一。 
             
             能不能自己編輯一個(gè)數(shù)字簽名文件導(dǎo)入到手機(jī)上,這樣就可以用這個(gè)簽名簽自己的程序了? 
            WINCE的內(nèi)核簽名機(jī)制的用途是限制非法的可執(zhí)行模塊EXE、DLL等在設(shè)備上運(yùn)行。要求內(nèi)核的加載模塊用公鑰驗(yàn)證請(qǐng)求加載的EXE、DLL的簽名是否合法,而這個(gè)公鑰是在定制內(nèi)核的時(shí)候加進(jìn)去的,所以除內(nèi)核的定制者以外的人無(wú)法修改這個(gè)驗(yàn)證機(jī)制。 
             
             我按照版主的文章《加密WINCE系統(tǒng)》里操作,提示錯(cuò)誤如下: 
            Error 80090016 during CryptSignHash 1! 
            Error signing hash 
            這是因?yàn)閭鬟f了無(wú)效的鑰容器名稱,使CryptoAPI調(diào)用失敗。應(yīng)該在使用signfile工具之前創(chuàng)建一個(gè)鑰容器,在桌面Windows中調(diào)用API CryptAcquireContext創(chuàng)建一個(gè)指定名稱的鑰容器,接著再創(chuàng)建一個(gè)簽名密鑰對(duì),這時(shí)再使用signfile工具就可以了。我在文章里寫成-kfulinlin是因?yàn)槲覄?chuàng)建鑰容器的時(shí)候沒有指定名稱,系統(tǒng)就采用當(dāng)前登錄的用戶名為容器名。 
             
             編譯錯(cuò)誤:CVTRES : fatal error CVT1102: out of memory; 42 bytes required ? 
            多數(shù)情況下出現(xiàn)這種錯(cuò)誤是因EVC的bug而起,應(yīng)該在安裝EVC之后就立刻安裝EVC的SP補(bǔ)丁。另外為了避開BUG,使用EVC編程應(yīng)該養(yǎng)成一些習(xí)慣,比如定期備份工程所有文件,每次編譯時(shí)采用Clean + Rebuild All,正調(diào)試時(shí)不要關(guān)閉模擬器等等。 
             
             在WINCE下是否能夠得到某一進(jìn)程使用的物理內(nèi)存總量? 
            目前沒發(fā)現(xiàn)有這樣一個(gè)API能夠得到指定進(jìn)程使用的物理內(nèi)存總量。只有GlobalMemoryStatus能夠得到整個(gè)系統(tǒng)使用的物理內(nèi)存總量。 
             
             應(yīng)用程序如何控制lcd的亮度?如何獲得電池的電量? 
            從常見的平臺(tái)如Geode、三星ARM系列來(lái)看,的確在驅(qū)動(dòng)方面沒有統(tǒng)一的控制LCD或者其它種類屏幕亮度的接口函數(shù),所以只能根據(jù)具體平臺(tái)提供的接口來(lái)做。從幫助文檔來(lái)看微軟的帶有DirectDraw功能的顯示驅(qū)動(dòng)程序的確有標(biāo)準(zhǔn)的增加亮度的接口函數(shù),關(guān)于背景光參見標(biāo)題為“Enabling a Backlight”的幫助文檔。 
            獲得電池電量有標(biāo)準(zhǔn)的接口函數(shù)GetSystemPowerStatusEx,前提是驅(qū)動(dòng)程序和硬件都要支持。 
             
             WINCE的socket函數(shù)好像不支持發(fā)送/接收超時(shí)? 
            是的,最早版本的WINCE支持選項(xiàng)SO_RCVTIMEO、SO_SNDTIMEO,后來(lái)卻不支持了。 
             
             WINCE下如何設(shè)置窗口最大化和最小化? 
            WINCE的幫助文檔在介紹API ShowWindow函數(shù)的參數(shù)時(shí)指出SW_MAXIMIZE, SW_MINIMIZE, SW_RESTORE, SW_SHOWDEFAULT, SW_SHOWMAXIMIZED, SW_SHOWMINIMIZED, SW_SHOWMINNOACTIVE都不被支持,但實(shí)際上并不完全是這樣,具體來(lái)說: 
            SW_MAXIMIZE            比原來(lái)窗口大,但不是最大化 
            SW_MINIMIZE             編譯成功,但是不起作用 
            SW_SHOWMAXIMIZED     最大化 
            SW_SHOWMINIMIZED      編譯出錯(cuò) 
            SW_RESTORE              能恢復(fù) 
            SW_SHOWDEFAULT        編譯出錯(cuò) 
            SW_SHOWMINNOACTIVE   編譯出錯(cuò) 
            SW_HIDE                  能夠隱藏 
             
             如何用程序調(diào)用控制面板的觸摸屏校對(duì)程序?  
            兩種辦法: 
            1、調(diào)用API TouchCalibrate函數(shù) 
            2、調(diào)用CreateProcess,參數(shù)1為L(zhǎng)"\\windows\\ctlpnl.exe",參數(shù)2為L(zhǎng)"cplmain.cpl,9"。 
             
             如何獲得U盤或者其它類型的存儲(chǔ)器總?cè)萘亢褪S嗫捎萌萘浚?/strong> 
            調(diào)用API GetStoreInfo得到扇區(qū)數(shù)、每扇區(qū)字節(jié)數(shù),相乘即是總?cè)萘俊U{(diào)用API GetDiskFreeSpaceEx得到剩余可用容量。 
             
             三星2440頭文件定義#define IIC_BASE 0xB1400000 // 54000000,datasheet是54000000,那么怎么轉(zhuǎn)成0xB1400000? 
            物理地址映射方法分為兩種,一種靜態(tài)映射另一種為動(dòng)態(tài)映射。在OEMAddressTable中定義了物理地址與虛擬地址的映射關(guān)系屬于靜態(tài)映射,用VirtualCopy映射屬于動(dòng)態(tài)映射,采用哪種辦法都可以。問題中提到的屬于靜態(tài)映射,2440的BSP在map.a文件中定義了IIC控制寄存器的物理起始地址和對(duì)應(yīng)的虛擬地址如下: 
            DCD 0x91400000, 0x54000000, 1 ; 
            在OEMAddressTable中定義的虛擬地址范圍在0x8000 0000—0x9FFF FFFF,這部分可緩存,適合內(nèi)核程序和應(yīng)用程序使用,同時(shí)WINCE內(nèi)核在0xA000 0000—0xBFFF FFFF中映射了另一份,指向了同樣的物理地址,這部分不可緩存,適合驅(qū)動(dòng)程序使用。三星ARM處理器帶有L1級(jí)高速緩存,可緩存會(huì)提高執(zhí)行效率。對(duì)于特殊的設(shè)備寄存器適合映射到不可緩存的虛擬地址。 
            當(dāng)驅(qū)動(dòng)程序調(diào)用VirtualCopy對(duì)0xB1400000地址讀寫時(shí),WINCE自動(dòng)將這個(gè)地址減去0x2000 0000,也就是0x91400000,對(duì)應(yīng)的物理地址就是0x54000000,也就是IIC控制寄存器的物理起始地址。 
             
             基于RAM的注冊(cè)表如何保存數(shù)據(jù)? 
            調(diào)用API RegCopyFile備份注冊(cè)表。調(diào)用API RegRestoreFile恢復(fù)注冊(cè)表,然后調(diào)用KernelIoControl熱啟動(dòng)使恢復(fù)生效。 
             
             如何隱藏和顯示winCE下標(biāo)準(zhǔn)外殼的任務(wù)欄? 
             HANDLE  hTaskBar = FindWindow(L"HHTaskBar", NULL);  
             ShowWindow(hTaskBar, SW_HIDE);  
             ShowWindow(hTaskBar, SW_SHOWNORMAL);  
             
             如果能讓W(xué)INCE的IE瀏覽器播放flash動(dòng)畫? 
            播放flash需要Macromedia Flash Player SDK,參見http://www.adobe.com/products/flashplayer_sdk/。這和real player相似,都需要WINCE平臺(tái)的SDK,都需要申請(qǐng)。 
             
             WINCE下內(nèi)核模式和用戶模式有什么區(qū)別? 
            為了使讀者能夠詳細(xì)了解WINCE的地址映射原理還有兩種模式,在這里我分幾個(gè)部分說明: 
            1、WINCE內(nèi)核nk.exe的任務(wù)是管理操作系統(tǒng)核心功能。按照OEMAddressTable的映射要求,所有物理地址都映射到0x80000000以上,所以對(duì)于內(nèi)核程序nk.exe和內(nèi)核模式下的線程來(lái)說,只要訪問0x80000000以上的有效虛擬地址經(jīng)MMU就能夠訪問物理地址,無(wú)需再映射是內(nèi)核模式的一個(gè)特點(diǎn)。內(nèi)核模式的第二個(gè)特點(diǎn)是沒有地址訪問限制,內(nèi)核模式線程可以訪問任何有效虛擬地址,所謂有效虛擬地址是指有實(shí)際事物對(duì)應(yīng)。 
            2、用戶模式線程只能訪問0x80000000以下的虛擬地址空間,WINCE6.0之前版本的內(nèi)核為每個(gè)進(jìn)程劃分32MB的地址空間,在不調(diào)用特殊函數(shù)的情況下不能相互訪問,這樣的設(shè)計(jì)使得WINCE系統(tǒng)更安全、更穩(wěn)定,限制訪問地址是用戶模式的第一個(gè)特點(diǎn)。第二個(gè)特點(diǎn)就是需要多一層映射,如果線程要訪問物理內(nèi)存的話需要先映射到0x80000000以上,再經(jīng)MMU訪問物理內(nèi)存地址。 
            WINCE的線程具有轉(zhuǎn)移性(參考API GetCallerProcess的說明,有一個(gè)很好的例子),當(dāng)應(yīng)用程序的線程調(diào)用API或者調(diào)用驅(qū)動(dòng)程序接口函數(shù)時(shí),該線程會(huì)轉(zhuǎn)移到gwes.exe、device.exe、filesys.exe等進(jìn)程中執(zhí)行,轉(zhuǎn)移是由WINCE內(nèi)核操作的,它會(huì)修改線程的上下文,記錄線程的當(dāng)前進(jìn)程、調(diào)用者進(jìn)程、擁有者進(jìn)程三個(gè)值。 
            3、如果在定制內(nèi)核的時(shí)候選擇了“Full Kernel Mode”,那么在這個(gè)內(nèi)核上運(yùn)行的所有線程都處于內(nèi)核模式,即使調(diào)用SetKMode(FALSE)后線程仍然具有內(nèi)核模式的特點(diǎn),能夠訪問任何有效的虛擬地址。假設(shè)現(xiàn)有一個(gè)64MB RAM的WINCE產(chǎn)品,RAM映射從0x80000000到0x84000000,如果線程處于內(nèi)核模式,它就直接可以訪問這個(gè)范圍的虛擬地址: 
            在OnButton1()中編寫 
            DWORD oldMode = SetKMode(FALSE); 
            volatile int *piTemp = (volatile int*)(0x20000000+0x84000000-0x00019000); ///或者(0x84000000-0x00019000) 
            *piTemp = 12345; 
            在OnButton2()中編寫 
            DWORD oldMode = SetKMode(FALSE); 
            volatile int *piTemp = (volatile int*)(0x20000000+0x84000000-0x00019000); ///或者(0x84000000-0x00019000) 
            int iTemp = *piTemp; 
            先只執(zhí)行OnButton1()然后關(guān)閉程序,再重啟程序然后執(zhí)行OnButton2(),iTemp仍然等于12345。結(jié)果說明了兩點(diǎn):內(nèi)核模式線程可以直接訪問0x80000000以上的有效虛擬地址;我們寫到RAM中的數(shù)據(jù)沒有丟失,說明虛擬地址有效。 
            如果在定制內(nèi)核的時(shí)候沒有選擇“Full Kernel Mode”,那么在這個(gè)內(nèi)核上運(yùn)行的所有線程都處于用戶模式??梢哉{(diào)用SetKMode(TRUE)使調(diào)用線程暫時(shí)處于內(nèi)核模式,還是原來(lái)的假設(shè)環(huán)境,我再舉個(gè)例子: 
            在OnButton1()中編寫 
            DWORD oldMode = SetKMode(TRUE); 
            volatile int *piTemp = (volatile int*)(0x20000000+0x84000000-0x00019000); ///或者(0x84000000-0x00019000) 
            *piTemp = 12345; 
            在用戶模式下,如果不調(diào)用SetKMode(TRUE),那么執(zhí)行*piTemp = 12345一定會(huì)彈出對(duì)話框,提示地址訪問非法,如果調(diào)用SetKMode(TRUE)就不會(huì)提示地址訪問非法,而且在OnButton2()中仍然能得到12345這個(gè)值。 
            通過這兩個(gè)例子我相信讀者能夠完全了解兩種模式的區(qū)別了。 
            4、WINCE提供了兩個(gè)函數(shù)SetKMode和SetProcPermissions,其中SetKMode能夠把調(diào)用線程切換到內(nèi)核模式,還可以切換回用戶模式。SetProcPermissions + GetCurrentPermissions添加當(dāng)前進(jìn)程訪問權(quán)限給調(diào)用線程,SetProcPermissions (0xFFFFFFFF)能讓調(diào)用線程訪問所有進(jìn)程空間,但是調(diào)用線程仍然處于用戶模式。SetKMode和SetProcPermissions函數(shù)使得用戶模式的特點(diǎn)不那么明晰。 
            如上所說一個(gè)應(yīng)用程序的線程可能轉(zhuǎn)移到其它兩個(gè)進(jìn)程地址空間中讀寫數(shù)據(jù),而每一個(gè)線程在被創(chuàng)建的時(shí)候只有訪問創(chuàng)建它的進(jìn)程地址空間的權(quán)限,所以驅(qū)動(dòng)程序開發(fā)者必須在驅(qū)動(dòng)程序讀寫數(shù)據(jù)前調(diào)用SetKMode或者SetProcPermissions增加調(diào)用此函數(shù)的線程訪問其它進(jìn)程空間的權(quán)限。如果一個(gè)應(yīng)用程序的線程只轉(zhuǎn)移到一個(gè)進(jìn)程地址空間,一般為設(shè)備管理器進(jìn)程device.exe,這種情況下不必增加線程訪問其它進(jìn)程空間的權(quán)限,但如果驅(qū)動(dòng)程序本身創(chuàng)建了一個(gè)線程,那還是要調(diào)用SetKMode或者SetProcPermissions增加新的線程訪問其它進(jìn)程的權(quán)限的,因?yàn)轵?qū)動(dòng)程序創(chuàng)建線程時(shí),當(dāng)前進(jìn)程為設(shè)備管理器,所以新線程只具有訪問設(shè)備管理器進(jìn)程空間的權(quán)限,而不具備訪問應(yīng)用程序進(jìn)程空間的權(quán)限。 
            5、可能一個(gè)編寫過簡(jiǎn)單的流驅(qū)動(dòng)的初學(xué)者會(huì)很疑惑,因?yàn)殚_發(fā)一個(gè)簡(jiǎn)單的流驅(qū)動(dòng)程序根本不需要調(diào)用這些函數(shù),也沒有調(diào)用過MapPtrToProcess,那是因?yàn)槿绻麡?biāo)準(zhǔn)流驅(qū)動(dòng)接口函數(shù)的參數(shù)為指針(ReadFile、WriteFile、DeviceIoControl參數(shù)都有指針),WINCE內(nèi)核會(huì)自動(dòng)映射指針包含的地址,但僅此而已,其余任何情況都要求開發(fā)者自行處理,比如流接口函數(shù)的參數(shù)是一個(gè)指向結(jié)構(gòu)體的指針PA,而結(jié)構(gòu)體中包括指針PB,PB指針就必須在流接口函數(shù)中映射,映射后才能訪問,否則就會(huì)造成地址訪問非法。所以結(jié)構(gòu)體中每個(gè)指針都要映射。 
            為了讓讀者能了解其中的原因,我舉個(gè)例子: 
            假設(shè)設(shè)備管理器被加載到Slot4,應(yīng)用程序A被加載到Slot 8,A只有一個(gè)主線程T,T開始執(zhí)行,按照WINCE的規(guī)定,正獲得CPU的進(jìn)程必須映射到Slot0,那么在執(zhí)行代碼的時(shí)候A的所有虛擬地址都被減去一個(gè)偏移值,也就是8×0x02000000,A調(diào)用DeviceIoControl,傳遞一個(gè)指向一個(gè)結(jié)構(gòu)體的指針B,而這個(gè)結(jié)構(gòu)體中包含一個(gè)指針C,指針C包含的地址假設(shè)為0x00030000,當(dāng)執(zhí)行DeviceIoControl時(shí)WINCE把設(shè)備管理器的進(jìn)程地址空間映射到Slot0,因?yàn)榉旁谧?cè)表[HKLM\Drivers\BuiltIn]下的驅(qū)動(dòng)程序是由設(shè)備管理器加載的,自然驅(qū)動(dòng)程序的代碼段被加載到設(shè)備管理器進(jìn)程空間,但是線程仍然是T,此時(shí)T的當(dāng)前所在進(jìn)程為設(shè)備管理器(CurrentProcess),A變成了T的調(diào)用者進(jìn)程(CallerProcess),T自動(dòng)具有了訪問調(diào)用者進(jìn)程空間的權(quán)限。這時(shí)訪問Slot0中的虛擬地址其實(shí)質(zhì)就是訪問設(shè)備管理器的進(jìn)程地址空間,要把地址加上一個(gè)偏移值,也就是4×0x02000000,所以DeviceIoControl訪問指針C包含的地址時(shí)本應(yīng)該加上8×0x02000000,卻加上4×0x02000000,結(jié)果地址并不是設(shè)備管理器的合法區(qū)域,系統(tǒng)就會(huì)提示地址訪問非法。而如果做了一個(gè)映射,指針C包含的地址就會(huì)被加一個(gè)正確的偏移值,使地址處于A的地址空間Slot 8中,T此時(shí)具有訪問A進(jìn)程空間的權(quán)限,訪問到正確的虛擬地址當(dāng)然會(huì)得到正確的數(shù)據(jù)了。 
             
             為什么WINCE目錄下的例子用build+sysgen能夠編譯成EXE文件,而我添加的例子就不能編譯呢? 
            如果這個(gè)例子是一個(gè)應(yīng)用程序,那么肯定包括代碼文件(.h .c .cpp)和資源文件(.rc和其它資源文件),build工具根據(jù)source文件內(nèi)容把代碼文件編譯成lib文件,資源文件編譯成.res文件,sysgen工具根據(jù)makefile文件內(nèi)容將source文件中列出的需要鏈接的各個(gè)庫(kù)文件合并成一個(gè)EXE文件。所以說關(guān)鍵在于makefile文件,WINCE目錄下凡是能夠用build+sysgen編譯的都在makefile中有如何鏈接的設(shè)置,而我們添加的例子當(dāng)然沒有在makefile中找到如何鏈接的設(shè)置,nmake工具就會(huì)提示不知道如何創(chuàng)建。 
             
             pcienum.exe干什么用的? 
            如果你要開發(fā)某一個(gè)PCI設(shè)備的驅(qū)動(dòng)程序,首先要知道這個(gè)PCI設(shè)備的信息(如VendorID、DeviceID、BaseClass、SubClass)和PCI總線的信息。運(yùn)行這個(gè)pcienum.exe就能得到相關(guān)信息。pcienum.exe提供了源碼,位置\Public\Common\Oak\Drivers\Ceddk\Test\Pcienum。 
             
             wince下如何讓操作系統(tǒng)進(jìn)入待機(jī)模式?又如何把它激活? 
            通過注冊(cè)表就可以設(shè)置,前提是你的驅(qū)動(dòng)和硬件都支持。注冊(cè)表項(xiàng)參見標(biāo)題為“GWES Suspend Time-outs”的幫助文檔。 
            [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power] 
                "BattPowerOff"=dword:300 
                "ExtPowerOff"=dword:0 
                "WakeupPowerOff"=dword:60 
                "ScreenPowerOff"=dword:0 
             
             現(xiàn)有一個(gè)GPRS模塊,如何通過GPRS連接到Internet? 
            1、先在內(nèi)核中加入WAN下面的幾個(gè)組件,如RAS/PPP、TAPI。WINCE采用unimodem驅(qū)動(dòng),所以不必?fù)?dān)心沒有Modem驅(qū)動(dòng)的支持。 
            2、WINCE啟動(dòng)后新建一個(gè)撥號(hào)連接,比如名稱叫“gprs1”,輸入用戶名、密碼、電話號(hào)碼。電話號(hào)碼不同,所采用的模式不一樣,例如“*99#”是GPRS模式,“17201”是普通的數(shù)據(jù)模式,速度差很多,價(jià)錢也差很多。 
            3、開始連接,連接過程會(huì)在對(duì)話框中顯示,直到顯示“連接成功”。 
            4、打開瀏覽器或者自己開發(fā)的通訊軟件測(cè)試網(wǎng)絡(luò)連接情況。 
            5、關(guān)閉連接。 
            6、保存[HKEY_CURRENT_USER\Comm\RasBook\gprs1]下的所有數(shù)據(jù),添加到project.reg中,重新編譯后內(nèi)核中就有了一個(gè)撥號(hào)連接“gprs1”。 
            7、調(diào)用RAS函數(shù)可以修改撥號(hào)連接“gprs1”的參數(shù),如用戶名、密碼、電話號(hào)碼,但是不能修改硬件設(shè)置,如波特率、串口、數(shù)據(jù)位、停止位等。RAS函數(shù)還能夠撥號(hào)、掛斷。為了修改波特率可以多保存幾個(gè)撥號(hào)連接,也可以直接調(diào)用TAPI開發(fā)撥號(hào)軟件,另外WINCE自帶的撥號(hào)連接是有源碼的,位置在\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\CONNMC。 
             
             采用基于HIVE的注冊(cè)表如何刪除用戶保存在注冊(cè)表中的數(shù)據(jù),恢復(fù)到出廠時(shí)的注冊(cè)表? 
            用戶修改的數(shù)據(jù)保存在user.hv文件中,直接刪除一定失敗,所以不能通過刪除文件實(shí)現(xiàn)恢復(fù)出廠設(shè)置。微軟考慮到了這個(gè)問題,在WINCE啟動(dòng)過程中filesys.exe加載注冊(cè)表時(shí)會(huì)調(diào)用OEMIoControl函數(shù)并傳遞一個(gè)IOCTL,這個(gè)IOCTL在pkfuncs.h中定義如下: 
            #define  IOCTL_HAL_GET_HIVE_CLEAN_FLAG  CTL_CODE(FILE_DEVICE_HAL, 49, METHOD_BUFFERED, FILE_ANY_ACCESS) 
            filesys.exe會(huì)分別傳遞參數(shù)HIVECLEANFLAG_SYSTEM和HIVECLEANFLAG_USERS,如果返回值為TRUE那么filesys.exe清除原來(lái)的注冊(cè)表文件,如果返回值為FALSE那么filesys.exe保留原來(lái)的注冊(cè)表文件。默認(rèn)WINCE并沒有實(shí)現(xiàn)這個(gè)IOCTL,所以O(shè)EM要?jiǎng)h除注冊(cè)表文件就必須先編寫這個(gè)IOCTL代碼。代碼的例子可參考標(biāo)題為“IOCTL_HAL_GET_HIVE_CLEAN_FLAG”的幫助文檔。另外必須在ioctl.h和ioctl.c兩個(gè)文件中編寫該代碼。在ioctl.c文件中找到const OAL_IOCTL_HANDLER g_oalIoCtlTable[],添加IOCTL和對(duì)應(yīng)的處理函數(shù)。要進(jìn)一步了解這個(gè)全局?jǐn)?shù)組,參見標(biāo)題為“IOCTL Library”的幫助文檔。 
             
             如何在不刪除必要組件的前提下減小內(nèi)核文件長(zhǎng)度? 
            要減小內(nèi)核文件長(zhǎng)度首先要在使用PB的定制內(nèi)核向?qū)е羞x擇自定義,也就是說對(duì)于每個(gè)組件都由自己來(lái)選擇,而不是選擇PB的標(biāo)準(zhǔn)配置。但減小內(nèi)核文件長(zhǎng)度最有效最直接的辦法是縮小字體,尤其對(duì)于東亞字體,采用字體壓縮技術(shù)并且選擇合理的字庫(kù)文件將明顯縮小文件長(zhǎng)度。 
            1、在定制內(nèi)核時(shí)選擇AGFA AC3 Font Compression組件。SYSGEN變量為SYSGEN_AGFA_FONT。 
            2、參考標(biāo)題為“East Asian Font Versions”的幫助文檔,從中選擇你需要的字庫(kù)文件加到內(nèi)核中,從文檔可以看出加AC3壓縮比不加壓縮在文件長(zhǎng)度方面差距很大。 
             
             如何得到WAV文件播放的總時(shí)間? 
            1、直接讀取wav文件頭信息,從文件起始地址偏移28個(gè)字節(jié)長(zhǎng)度為4個(gè)字節(jié)保存的是每秒鐘播放的字節(jié)數(shù),從文件起始地址偏移40個(gè)字節(jié)長(zhǎng)度為4個(gè)字節(jié)保存的是聲音數(shù)據(jù)的總的字節(jié)數(shù),相除就是播放時(shí)間。 
            2、調(diào)用IGraphBuilder::RenderFile打開一個(gè)wav文件,然后通過IGraphBuilder得到IMediaSeeking指針,再調(diào)用IMediaSeeking::GetDuration得到總的時(shí)間(結(jié)果要除以10000000),IMediaSeeking::GetCurrentPosition得到當(dāng)前播放時(shí)間。 
             
             如何在Dialog-Based程序中加入menubar? 
            先調(diào)用CommandBar_Create再調(diào)用CommandBar_InsertMenubar。 
             
             請(qǐng)問MultiByteToWideChar與_T、L、TEXT的區(qū)別? 
            MultiByteToWideChar函數(shù)轉(zhuǎn)換的對(duì)象可以是常量也可以是變量。其它只能轉(zhuǎn)換常量。_T和TEXT會(huì)根據(jù)當(dāng)前系統(tǒng)是否定義_UNICODE宏來(lái)決定是否轉(zhuǎn)換,而L就是轉(zhuǎn)換成寬字符,當(dāng)然也包括其他類型常量的轉(zhuǎn)換。 
             
             在用UBS線纜通過ActiveSync同步有效的情況下,如何插上USB線纜后WINCE自動(dòng)與PC同步? 
            1、新建一個(gè)撥號(hào)連接,假設(shè)名稱為“usb1”,選擇連接類型為“直接連接”,并在連接設(shè)備里選擇通過USB線纜連接。 
            2、將注冊(cè)表[HKEY_CURRENT_USER\Comm\RasBook\usb1]下的數(shù)據(jù)添加到project.reg或者platform.reg中。 
            3、在[HKEY_CURRENT_USER\ControlPanel\Comm]下添加如下: 
            "AutoCnct"=dword:1  ///直接連接 
            "Cnct"="usb1"       ///連接名稱 
            4、重新編譯內(nèi)核。為了節(jié)省編譯時(shí)間也可以在內(nèi)核工程下搜索*.reg文件,將2、3步驟中的注冊(cè)表數(shù)據(jù)添加其中,然后直接make image。 
             
             如何通過進(jìn)程句柄來(lái)獲得該進(jìn)程的主窗口句柄? 
            好像沒有API能夠通過進(jìn)程句柄直接獲得主窗口的句柄,因?yàn)椴⒎敲總€(gè)應(yīng)用程序都帶UI。但是可以反過來(lái),先枚舉當(dāng)前系統(tǒng)所有主窗口,然后根據(jù)每個(gè)窗口的句柄調(diào)用GetWindowThreadProcessId函數(shù)得到進(jìn)程的ID,再調(diào)用OpenProcess得到進(jìn)程句柄,與現(xiàn)有的進(jìn)程句柄比較。 
             
             我做的顯示驅(qū)動(dòng)DLL已經(jīng)編譯成功了,但是在加載顯示驅(qū)動(dòng)的過程中彈出話框,提示如下: 
            unhandled exception  in  gwes.exe  (0xc0000005 access violation) 
            提示的錯(cuò)誤——地址訪問非法,表明你的驅(qū)動(dòng)程序代碼并沒有在讀寫數(shù)據(jù)前添加SetKMode(TRUE)或者SetProcPermissions(0xFFFFFFFF)函數(shù)讓線程能夠訪問任何進(jìn)程的地址空間。你可以調(diào)用 IsBadReadPtr和IsBadWritePtr函數(shù)檢測(cè)地址是否能夠合法訪問。編寫和gwes有關(guān)的驅(qū)動(dòng)程序應(yīng)該首先調(diào)用SetKMode(TRUE)或者SetProcPermissions(0xFFFFFFFF)函數(shù),這是一個(gè)好習(xí)慣。 
             
             請(qǐng)問在嵌入式系統(tǒng)中如何設(shè)置GPRS拔號(hào)用的APN? 
            對(duì)一個(gè)撥號(hào)連接比如“我的連接”單擊鼠標(biāo)右鍵,在彈出的菜單中選擇“屬性”,然后單擊“配置”—“撥號(hào)選項(xiàng)”,在“附加設(shè)置”中添加AT命令如“+cgdcont=1,"ip","cmnet"”。“cmnet”位置即為APN。 
             
             WINCE的IP Phone功能如何? 
            WINCE的voip需要c-s-c結(jié)構(gòu),既需要服務(wù)器的中轉(zhuǎn),而skype采用第三代p2p技術(shù)就不需要中轉(zhuǎn),但是在gprs下也做不到語(yǔ)音流暢。skype有pocket pc版本,但是無(wú)線方面需要wlan或者cdma。 
             
             三星ARM平臺(tái)如何定義自己的中斷ID? 
            以S3C2410為例,在oalintr.h文件中定義中斷ID,也稱SYSINTR,例如 #define SYSINTR_MYINT  (SYSINTR_FIRMWARE+20),最大值不能超過SYSINTR_FIRMWARE+23。然后在armint.c文件中找到OEMInterruptHandler函數(shù),用if (IntPendVal == INTSRC_XXX) 判斷當(dāng)前發(fā)生的中斷源號(hào),然后返回SYSINTR_MYINT。內(nèi)核分別調(diào)用OEMInterruptDisable(禁止當(dāng)前中斷)、OEMInterruptDone(中斷處理結(jié)束)、OEMInterruptEnable(當(dāng)前中斷有效)三個(gè)函數(shù),參數(shù)都為中斷ID,在這三個(gè)函數(shù)中用 case SYSINTR_MYINT判斷當(dāng)前要處理的中斷。 
             
             如何開發(fā)軟件從PC端復(fù)制文件到基于WINCE的設(shè)備? 
            調(diào)用RAPI(Remote Application Programming Interface)函數(shù),此函數(shù)集由桌面計(jì)算機(jī)調(diào)用,由基于WINCE的設(shè)備執(zhí)行。一旦連接上就可以在桌面計(jì)算機(jī)端調(diào)用RAPI。通過注冊(cè)表還可以限制RAPI能夠訪問目錄的范圍。具體參考RAPI和RDP(遠(yuǎn)程桌面協(xié)議)。 
             
             請(qǐng)問如何對(duì)NandFlash分區(qū)、格式化? 
            你看看WINCE420\PUBLIC\COMMON\OAK\DRIVERS\ETHDBG\BOOTPART\bootpart.cpp,在Eboot中先要調(diào)用BP_LowLevelFormat( 
            DWORD dwStartBlock, DWORD dwNumBlocks, DWORD dwFlags)再flash的一個(gè)區(qū)域建立空的MBR,然后連續(xù)兩次調(diào)用BP_OpenPartition(DWORD dwStartSector, DWORD dwNumSectors, DWORD dwPartType, BOOL fActive, DWORD dwCreationFlags)函數(shù)來(lái)建立BINFS和FAT分區(qū)。建好后,將nk.bin燒入binfs分區(qū)中。 
             
              要做個(gè)彈出對(duì)話框具有 always on top 屬性,如何實(shí)現(xiàn)? 
            調(diào)用SetWindowPos(.. , HWND_TOPMOST, ...., SWP_NOACTIVATE)。 
             
             s3c2410+WINCE下網(wǎng)絡(luò)PING一會(huì)就斷,如何解決? 
            原因在于中斷處理程序把已經(jīng)產(chǎn)生的中斷標(biāo)志清除掉了,這樣就丟失一次中斷。因?yàn)樵?qū)動(dòng)里配置中斷為上升沿觸發(fā),一次中斷丟失就導(dǎo)致不會(huì)再產(chǎn)生中斷信號(hào)跳變,因?yàn)橹挥性谥袛喾?wù)中讀取了cs8900的 Interrupt status queue寄存器后,才會(huì)產(chǎn)生下一次中斷!解決辦法: 
            1、在cfw.c文件中全局定義BOOL Inited = FALSE 
            2、修改OEMInterruptEnable()中case SYSINTR_ETHER: 下面的語(yǔ)句為: 
            if(Inited == FALSE)  
            {  
            s2410IOP->rEINTPEND = 0x200;  
            s2410INT->rSRCPND = BIT_EINT8_23;  
            if (s2410INT->rINTPND & BIT_EINT8_23)  
            s2410INT->rINTPND = BIT_EINT8_23;  
            Inited = TRUE;  
            }  
            s2410IOP->rEINTMASK &= ~0x200;  
            s2410INT->rINTMSK &= ~BIT_EINT8_23;  
            break;  
            注:本解決辦法轉(zhuǎn)載于http://stoned.blogchina.com/stoned/3083045.html,非我本人研究成果。 
             
             已經(jīng)搜索到文件,如何用CListBox以圖標(biāo)形式顯示出來(lái)? 
            CListCtrl        ListCtrl; 
            CImageList      ImageList; 
            ImageList.Create(IDB_BITMAP, 48, 2, RGB(0,0,0)); 
            ListCtrl.SetImageList(&ImageList, LVSIL_NORMAL); 
            ListCtrl.InsertItem(iListIndex, strItem, 1);  
             
             如何改變控制面板中電源屬性對(duì)話框的尺寸?  
            1、需要修改對(duì)話框的尺寸是因?yàn)閷?duì)話框是以資源方式加載的,不會(huì)根據(jù)當(dāng)前系統(tǒng)顯示分辨率而自我調(diào)節(jié)尺寸。 
            2、安裝WINCE后有一些組件(feature)的資源文件*.res就已經(jīng)有了,如果你不改變,那么build內(nèi)核的時(shí)候PB只是把這些.res復(fù)制到工程目錄下,然后與*.obj合并成EXE、DLL、CPL。所以修改了.rc文件里面的對(duì)話框尺寸后要重新編譯.rc文件為.res文件,然后再覆蓋原來(lái)WINCE自帶的.res文件。 
            3、改變對(duì)話框尺寸有兩種辦法:一種方法是更改系統(tǒng)字體字號(hào),系統(tǒng)字體的字號(hào)變化會(huì)影響對(duì)話框的尺寸,但是缺點(diǎn)是所有系統(tǒng)字體有關(guān)的UI都會(huì)改變。另一種是在.rc文件中調(diào)整對(duì)話框尺寸,然后編譯成.res文件,再將.res復(fù)制到對(duì)應(yīng)的語(yǔ)言目錄里,比如目錄名為0804(中文),再執(zhí)行Rebuild命令重新編譯內(nèi)核,或者執(zhí)行sysgen+build。在研究中我發(fā)現(xiàn).res文件雖然能夠直接用EVC打開、修改、保存,但是和其它Obj鏈接成EXE、DLL、CPL后并不能運(yùn)行,所以還是建議讀者用CE自帶的rc工具編譯最好。讀者可在PB的命令行中鍵入“rc /?”了解rc.exe工具的用途和參數(shù)。 
             
             使用EVC build之后連接模擬器的時(shí)候,提示download file等了一會(huì)又出現(xiàn)download failed? 
            一般這樣的問題從下面幾個(gè)步驟解決: 
            1、如果之前能啟動(dòng)模擬器而現(xiàn)在不能,那么先clean然后重啟計(jì)算機(jī)再build。 
            2、如果開發(fā)的主機(jī)為WINXP+SP2,可能存在與EVC模擬器不兼容的情況,檢查C:\boot.ini,將/noexecute=optin改為/execute=optin。 
            3、檢查你的模擬器是否能運(yùn)行,假設(shè)你正用的SDK名稱為MYSDK,單擊菜單tools—configure platform manager,選擇MYSDK—MYSDK emulator,再單擊properties—test,看看模擬器是否能夠啟動(dòng),如果能啟動(dòng)那問題就不大。 
            4、單擊菜單build—update remote output files,看看模擬器是否能夠啟動(dòng)。 
            5、如果上述辦法均不行,關(guān)閉EVC然后重新建立一個(gè)新的工程,編譯,看看模擬器是否能夠啟動(dòng),如果能啟動(dòng)說明原來(lái)工程出了問題,最好恢復(fù)原工程的備份。 
             
             如何設(shè)置能夠自動(dòng)撥號(hào)、禁止自動(dòng)撥號(hào)? 
            在[HKEY_LOCAL_MACHINE\Comm\Autodial]下是自動(dòng)撥號(hào)的注冊(cè)表設(shè)置。 
            Enabled=DWORD:1          ///是否能夠自動(dòng)撥號(hào) 
            FailRetryWaitMS=DWORD    ///如果失敗再次撥號(hào)的等待時(shí)間 
            RasEntryName1= REG_SZ     ///自動(dòng)撥號(hào)采用的撥號(hào)連接名稱 
            更多細(xì)節(jié)請(qǐng)參考標(biāo)題為“Auto Dial Registry Settings”的幫助文檔。 

            posted on 2008-05-09 17:24 零宇 閱讀(2085) 評(píng)論(0)  編輯 收藏 引用


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            導(dǎo)航

            統(tǒng)計(jì)

            • 隨筆 - 8
            • 文章 - 4
            • 評(píng)論 - 60
            • 引用 - 0

            常用鏈接

            留言簿(4)

            隨筆檔案(8)

            文章分類(4)

            文章檔案(4)

            Windows Mobile 論壇

            • www.pdafans.com
            • 國(guó)內(nèi)PDA綜合性網(wǎng)站
            • www.pocketpcdn.com
            • 國(guó)外Win Moible 開發(fā)論壇, 資料比較多。
            • www.winbile.net
            • 國(guó)內(nèi)win moible 開發(fā)論壇,經(jīng)常閑逛,:-)

            道中人

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 17973
            • 排名 - 875

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            国产午夜精品久久久久九九| 久久久久人妻精品一区二区三区 | 久久久久久久人妻无码中文字幕爆| 久久久青草久久久青草| 亚洲精品乱码久久久久久自慰| 人妻无码精品久久亚瑟影视| 久久久久亚洲AV综合波多野结衣| segui久久国产精品| 久久久久99精品成人片三人毛片| 99久久精品免费国产大片| 久久精品国产福利国产琪琪 | 国产亚州精品女人久久久久久 | 午夜精品久久久内射近拍高清 | 国产综合精品久久亚洲| 久久精品国产第一区二区| 亚洲七七久久精品中文国产| 久久久亚洲AV波多野结衣 | 久久国产亚洲精品无码| 国产精品久久久久久影院| 久久播电影网| 久久香蕉国产线看观看精品yw| 成人久久久观看免费毛片| 国产精品激情综合久久| 久久精品国产男包| 久久成人国产精品二三区| 亚洲v国产v天堂a无码久久| 97精品伊人久久久大香线蕉| 成人国内精品久久久久影院| 久久久综合香蕉尹人综合网| 久久精品国产亚洲AV忘忧草18| 国产精品久久久久久久久鸭| 中文成人无码精品久久久不卡 | 精品久久久久久无码人妻热| 国产精品一区二区久久精品涩爱 | 色综合久久中文综合网| 欧美久久久久久| 国产精品无码久久四虎| 久久久久久毛片免费播放| 亚洲欧洲久久av| 国产香蕉97碰碰久久人人| 无码AV波多野结衣久久|