• <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>
            隨筆-16  評論-116  文章-0  trackbacks-0
            原文  http://blog.mcuol.com/User/basicygp/Article/4340_1.htm


            mediaplayer全屏播放的時候,我可以用鍵盤上的某一個鍵調節聲音大小,現在我想在屏幕上顯示調節的結果就跟我們看電視一樣能出來一些標記。當聲音變大在屏幕上就增多,當聲音變小的時候就減少 
            得到播放窗口的DC,然后在上面顯示一個不同顏色的矩形或者其它形狀。 
             
             
            ce自制平臺中如何添加自己的驅動?cec文件和reg,bib文件有何區別?看混了,不知道如何才能讓驅動注冊到平臺中。另外,regbib是我在編寫驅動必須要自己寫的么 
            CE
            的驅動分為本機驅動和流驅動,本機驅動你可以修改源碼(在%_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS),然后 build驅動源碼,之后用PB編譯內核。流驅動是以DLL的形式被系統程序加載的。加載流驅動要在注冊表中添加信息,這和cec文件沒關。如果你想把此驅動DLL和注冊信息作為一個整體給別人使用,那么就要做一個cec文件,PB能夠讀取cec文件內容并加載到內核工程中。cec文件相當于安裝程序。 
             
             
            我安裝的是evc4.0,我開發的系統要顯示中文比如姓名什么的。在編輯的時候是中文顯示,但是到了輸出時,顯示的都是亂碼。不知道應該怎么去解決 
            EVC
            的模擬器不支持中文。所以顯示出來的都是亂碼。1、你可以只顯示英文,調試結束后在改界面為中文。2、安裝PBPB的模擬器支持中文。  
             
             CStatic
            及其控件的文字無法垂直居中顯示,雖然在evc的資源編輯器中可設置,但是一旦運行,卻無法垂直居中顯示 
            這種情況正常,而且除此之外還不能右對齊。 
             
             
            獲取設備ID的種類有哪些 
            除了手機模塊外,還有CF卡有序列號、硬盤有ID號、網卡有MAC號等。這幾種方法數獲取手機模塊ID最簡單。 

              
                 
            在應用程序中,如何向修改本機的ip 地址等網絡參數,并使之立即生效? 
            網絡設置保存在注冊表中,位置[HKEY_LOCAL_MACHINE\Comm\網卡名稱\Parms\TcpIp],例如常見的CS8900網卡設置: 
            [HKEY_LOCAL_MACHINE\Comm\CS89001\Parms\TcpIp] 
               "EnableDHCP"=dword:0 
               "DefaultGateway"="192.168.0.1" 
               "DNS"="111.111.111.111" 
               "UseZeroBroadcast"=dword:0 
               "IpAddress"="192.168.0.2" 
               "Subnetmask"="255.255.255.0" 
            設置之后要生效有兩種辦法:一種熱啟動,調用KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0,  NULL),熱啟動時間很短暫;另外一種調用DevieceIoControl API,傳遞IOCTL IOCTL_NDIS_REBIND_ADAPTER 
             
             
            如何向控制面板中那樣,修改系統聲音的音量 
            調用API waveOutSetVolume(HWAVEOUT, dwVolume ),一般參數10。在[HKEY_CURRENT_USER\ControlPanel\Volume]下是系統聲音的注冊表設置。 
             
             
            在應用程序中如何實現jpggif圖片的顯示 
            有幾種辦法: 
            1
            、在MSDN中搜索標題為“Windows CE .NET Technical Frequently Asked Questions”的文檔,其中有一個問題“How can I display JPEG, GIF, and other graphics files?”,下面就是答案。 
            2
            、如果安裝了Windows CE 5.0,一個例子源碼位于WINCE500\PUBLIC\GDIEX\SDK\SAMPLES\SIMPLE 
            3
            、用IWebBrowser組件實現。 

              
                 
            在應用程序中如何實現系統待機 
            void GwesPowerOffSystem(void); 

              
                 
            WINCE下如何實現鍵盤鉤子 
            我寫了一個簡單的例子,把其中主要部分截取出來放到了我的FTP里。用戶名以及密碼均為winceuser,地址是ftp://211.95.73.26/fllsoft@sina.com/SourceCode/用鉤子禁止系統鍵.rar 

              
                 
            WINCE中如何得到網卡MAC地址 
            事實證明,獲得物理網卡的MAC地址并沒有被統一成一個API或者IOCTL,如果網卡驅動程序沒有提供接口的話只能直接訪問寄存器獲得。讀者可以參考目錄WINCE500\PUBLIC\COMMON\OAK\DRIVERS\NETCARD里的一些驅動源碼。 
             
             Windows XP Embedded 
            Windows CE有何區別 
            簡單地說Windows XP Embedded采用Windows XP內核,只能運行在x86處理器上,優點是能夠運行PC上現有的應用軟件,缺點是授權費太高,標價¥900元;Windows CE采用Windows CE內核,能夠運行在多種處理器上,如x86ARMSHXMIPS等,優點是授權費低,最低Core版標價¥30元。缺點是需要單獨開發應用軟件、定制內核,甚至開發BSPDriver 

              
                 wince
            下只是把調制解調器的驅動掛接在了com1,如何將器驅動掛接在com2上? 
            1
            、在HLM\drivers\buildin\com2\unimodem下復制和com1一樣的數據 2、在HLM\ExtModems\ HayesCompat下改寫PortCOM2:,再改寫FriendlyName"Hayes Compatible  COM2:" 
             
             
            如何定制自己的外殼 
            1
            、先開發一個外殼軟件,假設名稱為MyShell.exe 
            2
            、刪除注冊表[HKEY_LOCAL_MACHINE\init]下如下一行: 
               "Launch50"="explorer.exe" 
            3
            、在注冊表[HKEY_LOCAL_MACHINE\init]下添加如下一行: 
               "Launch50"
            "MyShell.exe" 
            上述的“LaunchXX”中的XX為序列數,內核依據這個序列數按由小到大的順序來分別執行所有子鍵列出的應用程序,具體數值應該為多少請參考幫助文檔的說明。 
            如果原來的內核中添加了標準外殼(standard shell)組件,或者添加了其它組件而這些組件需要依賴標準外殼,那么在PB中是無法刪除標準外殼組件的,解決辦法一是保留explorer.exe在內核中,二是刪除依賴標準外殼的組件。 

              
                 
            我原來的工程是x86版本的,編譯選項只有x86,我如何能夠編譯ARM版本的 
            兩種辦法: 
            1
            、用EVC新建一個工程的時候,建議復選“CPUs”列表,這樣發生了這種事情也能夠輕易通過選擇“WCE Configuration”工具欄中的CPU列表來編譯不同CPU版本的軟件 
            2
            、如果打開工程后CPU列表中只有x86,而此時已經安裝了ARM版本的SDK,那么單擊EVC菜單“build”“configurations”,然后單擊“add”按鈕來添加CPU 

              
                 
            通常情況下WINCE采用串口1作為調試時輸出信息用途,要正式出產品前如何去掉串口1的調試功能 
            正常情況下串口1只有在編譯debug版本的內核時才在BootLoader中初始化串口1用于輸出信息,而編譯release版本會跳過此代碼。而有些 BSP設計成沒有宏定義,也就是說無論什么版本都會在BootLoader中初始化串口1,這樣造成WINCE啟動后串口1無法被應用程序使用。對于這種情況只能在BootLoader源碼中刪除初始化代碼,如OEMInitDebugSerial 
             
             
            基于wince的應用程序能建成console project么? 
            不能 
             
             ARM
            系統外擴一片512K RAM,驅動程序經過映射可以使用這一段RAM1、應用系統如何使用這一段RAM?要加一層驅動嗎?2、如果要將這一段RAM當作RAM盤存儲系統,該如何作呢?應該要加文件系統吧,如何加呢? 
            解答這個問題前,先要說一下WINCE的地址映射機制。對于包含MMU(存儲器管理單元)的處理器來說,如ARMx86WINCE要求OEM在定制內核的時候填寫一個虛擬地址與物理地址映射關系的表,稱為OEMAddressTable,在這個表中定義了所有物理設備的起始物理地址,對應的起始虛擬地址,地址空間大小,RAM就包括在其中(如果是x86平臺還要求RAM起始虛擬地址從0x80000000開始)。如果有多片RAM,應該在 OEMAddressTable中將它們定義在一起,使之地址連續。對于非OEM的開發者來說,他們拿到的是定制好的內核,不能做任何修改,如果在產品中外擴一片RAM,只能通過API函數通知操作系統增加一條虛擬地址與物理地址映射關系表項。相關API函數有兩個,分別是 CreateStaticMappingVirtualCopy。它們的相同之處是都用于建立物理地址和虛擬地址的映射關系。它們的不同之處是 CreateStaticMapping映射的虛擬地址范圍在0xC400 0000  0xE000 0000之間,這個范圍只能由內核訪問,一般用于ISR訪問,因為ISR只能訪問靜態映射的虛擬地址空間,不能用VirtualCopyVirtualCopy通常和VirtualAlloc配合使用,映射的虛擬地址空間在0x8000 0000以下,一般用于驅動程序和應用程序訪問。 
            1
            、應用程序要訪問這片RAM,和驅動程序訪問方法一樣,調用VirtualAllocVirtualCopy 
            2
            、可以做一個流驅動程序專門用于讀寫這片RAM,這樣所有應用程序就可以通過調用流驅動接口函數來訪問,非要加文件系統也是可行的,通過修改注冊表就可以做到,但是麻煩一些。 

              
                 
            我怎么能在PB左邊的定制平臺加進我的驅動呢? 
            兩種辦法: 
            1
            、在platform.bib或者project.bibMODULES部分添加一條語句,例如: 
             MyDriver.dll       C:\Driver\MyDriver.dll                     NK SH 
            這樣編譯內核的時候就會把你的驅動DLL文件添加到內核中,如果有注冊表需要設置,在platform.reg或者project.reg中添加注冊表內容。 
            2
            、通過制作.cec文件來添加驅動,制作.cec文件的優點是只需制作一次,以后就可以通過將.cec文件導入到PBCatalog中,象PB自帶的feature一樣通過菜單“Add to OS Design”添加到左邊的內核工程中。 

              
                 WINCE
            有沒有相對路徑概念?如果沒有如何得到當前模塊的路徑? 
            1
            WINCE沒有相對路徑概念,只有絕對路徑,所以凡是涉及到路徑均為絕對路徑。 
            2
            、調用API GetModuleFileName,傳遞一個模塊的實例句柄就能夠得到模塊的絕對路徑。 

              
                 
            怎樣讓 POCKET WORD打開*.dat格式(里面都是數據)的文件?  
            兩種辦法: 
            1
            、調用API ShellExecuteEx,在結構體SHELLEXECUTEINFO中添加.dat文件的路徑。 
            2
            、調用API CreateProcess,在第二個參數中設置.dat文件的路徑。 

              
                 x86 Rom Boot Loader
            真的可以實現嗎?它確實能代替BIOS啟動計算機?  
            Rom Boot 
            被設計存放在Flash/EEPROM中,也就是原來BIOS的位置,這樣當上電后CPU到固定地址執行代碼,也就是執行了Rom Boot的代碼,它對整個硬件系統進行初始化和檢測,并且支持通過網卡從遠程機器上下載nk.bin或者從本地IDE/ATA 硬盤的活動分區中尋找nk.bin文件加載。 Rom Boot的優點就是引導并且加載速度快,而且它自身完成了所有的操作,這樣就不用BIOSMSDOS,更不用Loadcepc了。 
             
             
            對于x86 Rom Boot Loader,如何Build得到Romboot.rom? 
            1
            、在PB中打開一個內核工程(x86的) 2、單擊PB菜單“Build”“Open Build Release Directory” 3、用cd命令進入 %_WINCEROOT%\Platform\Geode\Romboot 4build 
             
             
            如何設置、更改顯示分辨率 
            能否設置、更改顯示分辨率由顯示驅動程序決定,而沒有統一的標準。例如CEPC,在啟動的時候可以通過設置loadcepc.exe的參數 /L來決定 WINCE啟動后的顯示分辨率,這是由于顯示驅動“VGA Linear Framebuffer”支持,而Geode可以通過在定制內核時修改注冊表項來決定WINCE啟動后的顯示分辨率。 
             
             
            幾個硬件使用同一個IRQ,那么發生中斷的時候系統怎么判斷到底是哪一個硬件發生的中斷呢?ISR里面又應該怎么控制呢
            Windows CE
            支持多個設備中斷共享一個IRQ,當一個共享IRQ發生時,CE內核的異常處理程序檢測設備特定的寄存器,因為大多數設備都有一個單獨的寄存器用于表示設備的活動狀態,所以通過遍歷共享這個IRQ的所有設備的寄存器就可以判斷哪個設備發生中斷。nk.exe加載一個giisr.dll,這個.dll是微軟提供的,它其實是第一個可安裝ISR。默認CE內核就是調用這個dll來檢測寄存器狀態的,當然OEM可以編寫自己的.dll 
            CE
            內部有一個ISR鏈,也就是可安裝ISR。因為CE允許OEM添加自己的ISR處理程序,所以ISR被設計成一個鏈表。排在前面的ISR比后面的ISR優先處理中斷,如果當前ISR能夠處理當前中斷,那就返回中斷IDIST處理或者返回SYSINTR_NOP,如果當前ISR不能夠處理當前中斷,那就返回 SYSINTR_CHAIN讓下一個ISR處理。 
             
             
            請問在wince中如何在內核中增加一個與\windows同級的目錄? 
            platform.dat或者project.dat中添加語句。例如要創建根目錄下子目錄Program Files,語句如下: 
            root:-Directory("Program Files")   
             
             
            文件格式如下所示,我想把每行的4個值讀到4個變量中,用EVC如何編程? 
            第一行: 460.000,  3384672.357342,  521268.972763 
            第二行: 475.117,  3384663.772419,  521281.415271 
            偽代碼如下: 
            FILE  *stream; 
            stream = _wfopen(L"\\a.txt", L"r+"); 
            if( stream == NULL ) 
                return; 
            fseek(stream, 0L, SEEK_SET ); 
            while( !feof( stream ) ) 

            fwscanf(stream, L"%s", WCHAR1); 
                fwscanf(stream, L"%f", float1); 
                fwscanf(stream, L"%f", float2); 
                fwscanf(stream, L"%f", float3); 

            fclose( stream ); 
             
             GWES
            組件的功能有哪些? 
            GWES
            不僅負責GDI、窗口、消息,還負責管理本機設備驅動程序,負責加載顯示、鍵盤鼠標、觸摸屏驅動程序,而且GWES本身包含電源、LED驅動程序。 
             
             
            如何在PB中預先設定好存儲內存和程序內存的大小,我想多劃分一些空間給程序內存?  
            兩種辦法: 
            1
            、在定制內核時在config.bib文件中設置FSRAMPERCENT = number,具體number可參考標題為“FSRAMPERCENT ”的幫助文檔。這種辦法是修改內核的設置,所有一直有效。 
            2
            、在應用程序中調用API SetSystemMemoryDivision,如果函數返回SYSMEM_CHANGED表示成功,如果返回SYSMEM_MUSTREBOOT表示需要熱啟動才能有效。這種辦法需要每次啟動后調用API才有效。 
             
             
            如何取消鼠標光標? 
            通過取消SYS變量來實現此目的,在PB命令行下鍵入“set SYSGEN_CURSOR=”,然后回車確認。 
             
             EVC
            下調用TextOut如何編譯會出錯? 
            類似這樣的問題很多,這是因為EVC的幫助文檔內容有錯誤。可能EVC的幫助文檔內容是從桌面Windows幫助文檔復制過來的,所以很多API函數還有例子代碼都有錯誤,例如幫助文檔中包含一個API函數的說明,但是實際編譯的時候提示沒有這個API,有的例子代碼采用ANSI字符串,而WINCE API都是寬字符版本,造成直接復制過來編譯失敗。 
            因為MFC for WINCECDC類中沒有TextOut成員函數,所以編譯會出錯,可以用其它類成員函數ExtTextOut或者DrawText替換。 
             
             
            我如何將我的dll軟件讓現有的ce系統認可?盡管我也知道應該使用signfile.exe程序進行簽名,但是我并不知道那個ce系統認可的簽名應該是啥 
            如果你說的WINCE系統內核已經加入了簽名認證機制,那么沒有私鑰對你的DLL文件簽名肯定是無法運行在此內核中的,一般簽名密鑰的密鑰長度都是1024位,很難破解。 
             
             
            如果查看WINCE注冊表中的內容? 
            兩種辦法: 
            1
            、建立同步后,用EVC自帶的工具“Remote Registry Editor”打開查看。 
            2
            、從網上下載注冊表查看工具,放到WINCE設備中。 
             
             
            調用directshow出現鏈接錯誤,如何解決?  
            player.obj : error LNK2001: unresolved external symbol _IID_IVideoWindow 
            player.obj : error LNK2001: unresolved external symbol _IID_IMediaControl 

             
            這是因為鏈接器沒有找到合適的.lib文件。兩種辦法: 
            1
            、在EVC菜單Tools—options—directories 里把library files的路徑重新調整一下。如果你只安裝了EVC自帶的 Standard SDK而沒有其它SDK,可以指定WINCE目錄中的.lib文件路徑,例如D:\WINCE500\PUBLIC\DIRECTX\ OAK\LIB\X86\RETAIL。注意CPU的類型。 
             2
            、安裝SDK,前提是導出SDKPB內核工程必須包括DirectShow或者其它組件。 
              
                 
            PBconfig.bib文件中,“IMGFLASH”表示什么意思呢? 
            表示能夠刷NKROM中,具體請查看標題為“IMG Environment Variables”的幫助文檔。 
             
             x86
            平臺如何映射各種地址空間?如何編寫中斷服務例程? 
            如果是x86平臺,可以調用HalTranslateBusAddress轉換物理總線地址到物理系統地址,調用 HalTranslateSystemAddress轉換物理系統地址到邏輯總線地址,也可以不調用這兩個函數,因為x86平臺除32位物理地址外還有 16位的IO地址空間,對于16位的IO地址空間,可以直接調用WRITE_PORT_UCHAR或者READ_PORT_UCHAR等函數直接讀寫端口。對于32位物理地址可以調用VirtualAllocVirtualCopy來映射。這樣做思路清晰,簡單明了。 
            x86平臺要實現ISR,有如下幾個步驟(以Geode BSP為例): 
            1
            、用SETUP_INTERRUPT_MAP宏關聯SYSINTRIRQ。以“SYSINTR_”為前綴的常量由內核使用,用于唯一標識發生中斷的硬件,又稱為中斷ID。在Nkintr.h文件中預定義了一些SYSINTROEM可以在Oalintr.h文件中自定義SYSINTR 
            2
            、用HookInterrupt函數關聯硬件中斷號和ISR。這里提到的硬件中斷號為物理中斷號,IRQ為邏輯中斷號。在InitPICs函數的最后調用了HookInterrupt函數,如下: 
            for (i = 64; i < 80; i++) 
            HookInterrupt(i, (void *)PeRPISR);  ///
            ISR關聯16個中斷號  
            3
            、調用InterruptInitialize函數關聯SYSINTRIST創建的事件對象,也是IST等待的事件對象。詳細內容請參考Geode BSP源碼。 
            x86 平臺要實現可安裝ISR,先調用LoadIntChainHandler函數注冊在注冊表中指定的ISR DLL,然后填充GIISR_INFO結構體并調用KernelLibIoControl函數將此結構體傳遞給可安裝ISR。詳細內容請參考WINCE幫助文檔或者我著的《Windows CE下驅動開發基礎》。 
             
             
            修改了WINCE自帶的驅動程序后如何編譯?如果是自己開發的驅動程序如何編譯? 
            1
            、分為IDE方式和命令行方式。 
            IDE
            方式的編譯很簡單,以PB5.0為例,打開定制內核的工程,在左邊的“workspace”—“FileView”中找到你已經修改了的目錄,然后單擊右鍵彈出菜單,在菜單中選擇“Build and Sysgen Current Project”,這樣PB就會編譯指定的目錄中的項目源碼文件,然后執行sysgen命令根據source文件中的內容生成目標文件并復制到當前內核工程目錄下。 
            命令行方式的編譯需要打開“Build OS” —“Open Release Directory”,以cd命令進入你已經修改的驅動程序目錄中,然后鍵入“build –cfs”,然后鍵入 “sysgen –p 項目名稱,一般項目名稱為source文件中的“TARGETNAME” 
            2
            、如果想完全自己開發驅動程序,建議直接采用EVC或者PB來編寫編譯。 
             
             
            開發PCI設備驅動時,InterruptInitialize函數的第一參數是否是PCI卡配置空間信息中的InterruptLine 參數?是否需要在HKLM\Drivers\BuiltIn\PCI\Template 加一個自己的 subkey,并填寫相應內容?如何填? 
            1
            InterruptInitialize的第一參數是IRQ,也就是邏輯中斷號,而不是物理中斷號,InterruptLine是指物理中斷號 
            2
            、需要在template下加自己的PCI設備的信息,例如: 
               [HKEY_LOCAL_MACHINE\Drivers\PCI\Template\Serial] 
                "Dll"="Com16550.Dll" 
                "Class"=dword:07 
                "SubClass"=dword:00 
                "ProgIF"=dword:02 
                "VendorID"=multi_sz:"0AF0","B320","B320" 
                "DeviceID"=multi_sz:"0020","0300","0302" 
                "Prefix"="COM" 
            而這些信息就來自于你執行pcienum.exe的結果。  
             
             
            編譯器報錯:error C2065: ''CFileFind'' : undeclared identifier,如何解決? 
            MFC for WINCE
            版本沒有CFileFind類,所以要查找文件只能調用API FindFirstFile FindNextFile 
             
             
            如何設置WINCE系統字體、字號?如何設置自己開發的軟件的字體、字號? 
            1
            、系統字體通過注冊表設置。如下: 
            [HKEY_LOCAL_MACHINE\System\GDI\SysFnt]   ///
            系統字體 
            Wt=420 
            Ht=18 
            Nm=Arial 
            [HKEY_LOCAL_MACHINE\System\GWE\Menu\BarFnt]   ///
            菜單欄字體 
            [HKEY_LOCAL_MACHINE\System\GWE\Menu\PopFnt]   ///
            彈出窗口字體 
            [HKEY_LOCAL_MACHINE\System\GWE\Menu]         ///
            菜單字體 
            HKEY_LOCAL_MACHINE\System\GWE\Button          ///
            按鈕字體 
            2
            、創建字體時把字體高度參數設置大點就可以了。如CFont::CreateFont(nHeight,...),也可以在LOGFONT結構中設置字體高度或者字體種類。如果是控件,調用控件的SetFont成員函數。如果是直接畫,在OnPaint響應函數中調用SelectObject選字體到DC  
             
             nk.bin
            nk.nb0有什么區別? 
            這里提到的bin是一種二進制鏡像格式,以片斷(section)為單位組織數據,每個片斷都包括一個頭,頭里指定了起始地址,長度,校驗值。Platform Builder調用工具將WINCE內核所有文件以bin格式合并成一個文件,默認文件名為nk.binBootLoader又以同樣的格式將nk.bin分解成多個文件放到RAM中。可以在命令行中鍵入 “viewbin nk.bin”來查看bin文件中具體包括了哪些內容。鍵入Cvrtbin命令轉換.bin格式文件為.sre格式或者.abx格式。  
            nb0
            格式是原始的二進制鏡像,它不包括頭,一般情況下將內核下載到設備的RAM中運行都采用nb0格式。要生成nbx格式的文件,需要在相關.bib文件中確定如下值:ROMSTARTROMWIDTHROMSIZE 
             
             
            在不采用硬件計時器的情況下如何創建更精確的計時器?最精確周期能否達到1毫秒? 
            對于精確值的要求不同,所采用的辦法不同。以下闡述幾種辦法。 
            1
            、在單線程中循環調用API Sleep函數,Sleep函數精確程度為如果Sleep(N),那么實際睡眠時間在NN+1毫秒之間。而且還要注意調用Sleep的線程優先級的問題。如果任務過多并且此線程優先級低,那誤差就更大些。 
            2
            、調用API QueryPerformanceCounter函數,舉例如下: 
            LARGE_INTEGER  liFrequency; 
            if (QueryPerformanceFrequency(&liFrequency))  // 
            查詢系統時鐘的頻率,這里將返回1000 

               liFrequency.QuadPart /= 1000;    
               LARGE_INTEGER  liTimeOut;    
               if (QueryPerformanceCounter(&liTimeOut))   //
            得到截至到當前累計發生的系統時鐘中斷次數 
               { 
                  liTimeOut.QuadPart += liFrequency.QuadPart;   ///
            計算下一秒到來時總的中斷次數是多少 
                  LARGE_INTEGER  liCurrent; 
                  do 
                  {          
                     QueryPerformanceCounter(&liCurrent);    // 
            循環查詢累計的的中斷次數 
                  } while (liCurrent.QuadPart < liTimeOut.QuadPart); ///
            到達下一秒 
               } 

            調用QueryPerformanceCounter同調用Sleep在本質上都是一樣的,都是在單線程中無限循環等到周期一到執行任務,相比較 QueryPerformanceCounter要比Sleep更精確些,越精確就越要求線程的優先級,保障線程能夠正常得到處理器。 
            3
            、以上辦法難以保證周期精確到1毫秒并且WINCE系統穩定地運行,所以要從中斷入手。以x86平臺為例,先在Timer.c中將默認的SetTimer0 (TIMER_COUNT)中的TIMER_COUNT /2SetTimer0函數負責設置系統時鐘的頻率,默認1毫秒發生一次中斷,如果除以2就是0.5毫秒發生一次中斷。然后在fwpc.c文件中修改ISR函數PeRPISR,因為原來默認是1毫秒發生一次中斷,在處理INTR_TIMER0時系統負責累計計數、管理線程的調度,返回相應的SYSINTR值,而我們沒有辦法再添加代碼返回自己定義的SYSINTR值,所以現在要修改原來的處理代碼,例如設置一個BOOL型變量,TRUE就執行原來默認的代碼,而FALSE就返回我們自己定義的SYSINTR值,這樣即不影響原來的ISR處理,又加入了我們的中斷響應代碼。ISR返回我們定義的SYSINTRWINCE內核激活相對應的EVENT事件,我們就可以在我們編寫的IST里處理任務了。 
             
             flash
            中存放了BootLoader和內核鏡像,如何把剩余flash部分劃分為一個存儲區域供應用程序讀寫? 
            WINCE 提供的驅動(FAT文件系統和MSFLASH驅動)來舉例說明。如果采用默認common.reg中的注冊表設置,那么MSFLASH驅動默認把整個 flash作為存儲區域來讀寫,這不符合問題的要求,所以必須告訴MSFLASH驅動程序可供讀寫的區域的起始地址和長度。以下是一個注冊表例子: 
            [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\FASLD] 
                "Dll"="fasld.dll"        ///
            實際Flash存儲器的驅動程序 
                "Order"=dword:2       ///
            該驅動程序相對于其它驅動程序的加載順序 
                "Prefix"="DSK"        ///
            前綴 
                "Ioctl"=dword:4        ///IOCTL
            碼,設備管理器加載驅動的時候調用IOControl函數,傳遞這個IOCTL碼。 
            "Profile"="MSFlash"    ///Profile
            名稱,也就是[HLM\System\StorageManager\Profiles\MSFlash] 
            ///
            當設備管理器加載此驅動程序的同時發送通知給系統,IClassGUID)的值表明這是一個存儲設備的驅動程序。 
            "IClass"="{A4E7EDDA-E575-4252-9D6B-4195D48BB865}"    
                "MemBase"=dword:00000000    ///Flash
            中可供讀寫區域的起始物理地址,也就是Flash的首地址+偏移量 
                "MemLen"=dword:00000000     ///Flash
            中可供讀寫區域的長度 
            [HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\MSFlash] 
                "DefaultFileSystem"="FATFS"   ///MSFlash
            驅動默認采用的文件系統 
                "PartitionDriver"="mspart.dll"    ///
            采用的分區驅動程序 
                "MountAsRoot"=dword:1        ///
            此目錄作為文件系統的根目錄 
                "Folder"="NOR Flash"          ///
            目錄名稱 
                "Name"="FLASH Disk Block Device"   ///Flash
            驅動名稱 
             "PartitionDriverName"="MSPART" ///
            分區驅動名稱 
             "AutoMount"=dword:1         ///
            自動裝載檢測到的分區 
                "AutoPart"=dword:1            ///
            自動分區 
                "AutoFormat"=dword:1          ///
            自動格式化分區 
            [HKEY_LOCAL_MACHINE\System\StorageManager\AutoLoad\MSFlash] 
                "DriverPath"="Drivers\\BuiltIn\\FASLD"    ///Flash
            驅動在注冊表中的位置 
                "LoadFlags"=dword:1                 ///
            這個值可以被設置為0121表示同步加載,其它表示異步加載 
                "Order"=dword:0 
            [HKEY_LOCAL_MACHINE\System\StorageManager\FATFS] 
                "FriendlyName"="FAT FileSystem"    ///
            文件系統名稱 
                "Dll"="fatfsd.dll"                   ///
            文件系統驅動程序 
                "Flags"=dword:00000064             ///
            標志,詳見幫助文檔 
                "Paging"=dword:1                   ///
            是否分頁 
                "EnableCache"=dword:1              ///
            是否允許緩存數據 
                "CacheSize"=dword:0                ///
            指定緩存大小,0表示默認 

              
                 
            驅動程序如何發通知給應用程序? 
            這里介紹一下常見的兩種辦法。 
            1
            、驅動程序調用API SendNotifyMessage,發送特定的消息給應用程序,這就要求應用程序要有消息循環機制并且要事先做好消息的處理。參數 1為窗口句柄,可以設置HWND_BROADCAST表示廣播消息。要注意的是不要在參數中傳遞指針(虛擬地址),因為執行驅動程序的線程和應用程序并不在同一個進程空間中。解決辦法可以利用內存映射文件技術,比如在驅動程序中創建一個內存映射文件對象,申請一塊物理內存,然后把對象名稱和內存長度傳遞給應用程序,應用程序打開同名的內存映射文件對象,讀取里面的數據。對象名稱可以事先協定好,也可以通過注冊表來傳遞,內存長度是32位值,通過消息參數就可以傳遞,也可以通過注冊表來傳遞。另外一種解決辦法是在定制內核時候預留一塊物理內存,這樣驅動程序和應用程序都可以通過VirtualAlloc VirtualCopy來映射到同一塊物理內存,其原理同內存映射文件技術一樣,但是這塊物理內存不具備通用性。最后一個辦法是應用程序事先將一個緩沖區地址傳遞給驅動程序,驅動程序調用MapPtrToProcess映射應用程序傳遞過來的地址,當驅動程序調用SendNotifyMessage后應用程序可以直接到該地址中讀取數據。 
            設備管理器就是調用此函數廣播WM_DEVICECHANGE消息的。另外WINCE的一個例子程序RNAApp在撥號連接建立的時候也是調用這個函數廣播WM_NETCONNECT消息的。 
            2
            、驅動程序調用API CeEventHasOccurred指明一個事件A發生,在此之前應用程序調用API CeRunAppAtEvent將驅動程序指明的A事件和一個應用程序名稱相關聯,或者和一個事件B相關聯。這樣當A事件發生時,如果指明和一個應用程序名稱關聯,那這個應用程序就會被啟動。如果指明了和一個事件B相關聯,那么等待事件B的線程將被激活。如果想了解當前系統內部所有驅動程序支持哪些類似事件A的事件,調用 API CeNotifyPublic_FilterEvent,在該API的幫助文檔里也列舉了常見的事件,例如 NOTIFICATION_EVENT_NET_CONNECT NOTIFICATION_EVENT_NET_DISCONNECT 
             
             EVC
            創建的工程名稱如果用中文就出錯,該怎么辦?  
            EVC創建的工程名稱如果為中文將導致資源文件打不開和編譯出錯,可以改資源文件名稱為英文,再編輯.rc文件中的資源文件名稱。但建議盡量不要用中文為工程名稱。 
            作為習慣,應該在EVC創建一個工程后,立刻在“project”—“settings”中設置資源的語言屬性,然后在“resource view”中設置每個資源的語言屬性,這些工作做完后再修改資源就沒有問題了。有人詢問對話框的標題為亂碼,其原因就是在沒有修改語言屬性的情況下設置標題為中文。 
             
             WinCE
            下如何讀寫幾百兆的大文件呢使用內存映射文件嗎?  
            一般嵌入式設備配備128MB物理內存就算頂級的了,所以要讀寫幾百MB的文件用內存映射文件技術是最好的選擇了。映射文件之后讀數據是非常容易的,要注意的是寫數據,內存映射方面的API沒有提供改變文件長度的功能,所以要在關閉映射文件對象后用文件API改變文件長度。 
             
             
            請問如何改系統調度的默認時間片值? 
            更改schedule.c文件中的dwDefaultThreadQuantum 變量,然后重新編譯該文件并SYSGEN。調用API CeGetThreadQuantum就知道更改是否生效。 
             
             
            如何讓系統加載自己寫的驅動程序?  
            兩種辦法: 
            1
            、在[HKEY_LOCAL_MACHINE\Drivers\BuiltIn]下添加注冊鍵。 
            2
            、在應用程序中調用ActivateDeviceEx 
             
             
            在一些文件中用分號來表示注釋,例如下面的內容  
            ; @CESYSGEN IF SERVERS_MODULES_HTTPD 
            ; @CESYSGEN ENDIF 
            “CESYSGEN...”前加了“@”,有沒有什么特別的含義? 
            WINCE的一些文件中,用“;”作為注釋并在注釋文字中用@CESYSGEN作為標記,后面接條件語句。Cefilter.exe工具負責按照條件來篩選文件內容,所以不要輕易地刪除包含@CESYSGEN的注釋語句。 
             
             
            通過串口建立ActiveSync聯接,串口線用三線的可以嗎?  
            不可以,因為用串口同步時要用到其余口的狀態。 

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

            posted on 2008-09-16 10:35 greatws 閱讀(1926) 評論(0)  編輯 收藏 引用
            18禁黄久久久AAA片| 国产精品久久久久9999高清| 国产精品久久久久久一区二区三区| 日韩久久无码免费毛片软件| 久久精品三级视频| 91视频国产91久久久| 97精品久久天干天天天按摩| 精品国产VA久久久久久久冰| 久久久久女人精品毛片| 国产精品一区二区久久国产| 久久夜色精品国产噜噜噜亚洲AV| 久久久久久久久久久| 久久久久亚洲AV成人网人人网站 | 亚洲熟妇无码另类久久久| 久久伊人影视| 欧美黑人激情性久久| 欧美亚洲国产精品久久高清| 伊人久久综合无码成人网| 久久精品九九亚洲精品| 久久精品9988| 色综合久久天天综线观看| 免费精品国产日韩热久久| 久久丫精品国产亚洲av| 好久久免费视频高清| 久久久久国色AV免费看图片| 热久久最新网站获取| 99久久综合狠狠综合久久止| 久久免费高清视频| 亚洲国产精品成人AV无码久久综合影院 | 国产精品无码久久四虎| 久久无码一区二区三区少妇 | 欧美亚洲国产精品久久蜜芽| 久久久精品久久久久特色影视| 久久无码高潮喷水| 久久精品一区二区国产| 亚洲国产精品无码久久青草| 精品蜜臀久久久久99网站| 欧洲国产伦久久久久久久 | 无码任你躁久久久久久久| 色欲久久久天天天综合网| 国产精品亚洲综合专区片高清久久久|