首先是wince驅動的分類問題。按照書上講的說CE下驅動分成單體驅動和分層驅動,而看到另一種說法是本機驅動和流式驅動。經過microsun大哥的指點,把這兩種分類法分開了。在這里引用一下:
“單體與分層只是從代碼的形式上做的分類.分層驅動代碼上分為PDD與MDD,一般的微軟已經實現了MDD,可能也實現了PDD,我們只需要對PDD做些修改就能使用,比如音頻的驅動,顯示的驅動。單層驅動是把PDD與MDD寫在一起,沒有做嚴格的區分,通常這種驅動比較簡單,比如:ATADISK。
嵌入式 嵌入式開發 嵌入式系統 wince驅動開發
至于本地驅動和流式驅動是從驅動與系統其它模塊(調用者)的接口形式上做的分類.其實,本地驅動這個名稱不大恰當,可能叫專用驅動或其它名字更為合適.它是指調用它的模塊給它有特定的接口,比如電源驅動和通用LED驅動。而串口,網卡等就是流接口驅動程序.
所以,一個驅動程序可以是單體的流式驅動,例如:ATADISK.也可以是分層的流式: 如OHCI ”
按照我的理解,單體和分層是驅動實現方式上的分類,而本地和流式則是驅動模型上的分類,所謂本地驅動就是操作系統有保留專門的接口,所謂流式是指編寫的DLL文件里可以導出各種流式接口函數。
第二點:驅動的功能屬性。設備驅動程序是操作系統內核和硬件的接口,操作系統定義了一組標準的接口,編寫驅動的過程也就是實現這些接口。從應用程序到具體硬件間有如下這些環節起作用:應用程序-調用OS函數-操作系統-驅動接口-驅動程序-硬件操作函數-硬件。在wince里驅動都以用戶態的DLL存在,需要通過進程加載到slot里。共有三類系統進程用來加載:Device.exe,GWES.exe,FileSys.exe.絕大多數設備驅動都是通過Device.exe加載的。需要注意的是,不同的OS保留的設備驅動接口是不一樣的,如桌面windows和wince就不同。
第三點:wince下設備的初始化分為兩個階段:Device.exe的初始化;外設的枚舉和加載。其流程是:上電-啟動bootloader-啟動NK-啟動注冊表init鍵(Device.exe啟動)-初始化數據結構,I/O,電源管理等-加載BusEnum.dll(總線枚舉器)-枚舉注冊表下Driver/buildin的所有子鍵。這里的枚舉過程就是循環調用ActivateDeviceEx()函數加載驅動的過程。在OS啟動完畢后,我們可以用PB的Remote Registry Tool查看H_L_M/drivers/active包含的子鍵,看哪些驅動隨啟動而加載 。
第四點:流接口驅動的概念。暴露流式接口函數的驅動即是流驅動,它把外設抽象成一個文件。過程是:應用程序使用文件API對設備進行訪問,OS接受API調用FileSys.exe,轉到device.exe,調用流接口,與硬件交互。所謂流接口函數有十個,包括XXX_Init、XXX_Deinit、XXX_Open、XXX_Close、XXX_Read、XXX_Write、XXX_PowerUp、XXX_PowerDown、XXX_Seek、XXX_IOControl,在wince5.0中增加le了XXX_PreClose,XXX_PreDeinit.而我們在應用程序里對應的文件API有CreateFile、DeviceIoControl、 ReadFile、 WriteFile,CloseHandle,SetFilePointer.
第五點:編寫流驅動的步驟。有兩種實現途徑:1。寫DLL,做成Project,加入到OS里。2。改BSP,把驅動寫在BSP里,再選擇那個BSP做OS。第一種方法步驟是在PB中新建一個DLL項目,編寫一些輸入函數,寄存器,外設的聲明,寫DLLENTRY函數;實現流接口函數;編寫DLL的導出函數文件.DEF;為驅動程序寫入注冊表項,還需要修改bib文件。 第二種方法就是在platform/BSP/drivers下新建一個目錄,然后在drivers目錄中的dirs文件中加入新建的目錄名。在新建的目錄下,新建你的源代碼文件,在其中實現DLL函數。新建名稱分別為sources, makefile, ***.def的文件;修改platform.reg和platform.bib文件
]]>1、 對象存儲(object store)
對象存儲是Windows CE默認的數據存儲機制。任何新創建的內核中都默認包含對象存儲器。對象存儲的實質是在RAM中創建一個文件系統,將文件保存在RAM中,這些文件來源于ROM。當設備啟動時,引導程序將ROM中的內核文件解壓并存放在RAM中。"\windows"目錄就是基于對象存儲的。對象存儲的特點是文件可以壓縮、支持事務機制(和數據庫中的事務機制相似)、數據I/O相對較快。
A、對象存儲中的對象類型包括文件、目錄、數據庫、記錄、數據庫卷。CE為每個對象分配一個對象ID(CEOID)。訪問或者操作任何對象的前提是得到該對象ID。
B、CE能夠自動壓縮所有對象存儲中的文件(CE提供了一個選項供OEM設置是否能夠自動壓縮文件)。所以文件沒有壓縮或不壓縮的標志,但是有一個標志,標明此文件存在于ROM還是RAM中。一個文件最大長度可達到4 GB。
C、CE提供了三種文件系統:基于ROM的文件系統、基于RAM的文件系統、FAT文件系統。
2、 注冊表(registry)
CE下注冊表和其它windows操作系統中注冊表概念和結構基本相同。
A、CE下注冊表限制:鍵名最大長度255個字符; 數據最大 4KB;子鍵深度最大值 16層。
B、根鍵有HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_USERS。
C、操作注冊表函數:
i. 打開RegOpenKeyEx 和創建RegCreateKeyEx
ii. 讀RegQueryValueEx寫RegSetValueEx
iii. 枚舉入口或子鍵RegEnumValue、RegEnumKeyEx
iv. 刪除入口或子鍵RegDeleteValue、RegDeleteKey
v. 關閉RegCloseKey
3、CE下注冊表類型
分為基于RAM的注冊表和基于HIVE的注冊表。
A、基于RAM的注冊表,也叫基于對象存儲(oject storage)的注冊表。用于將注冊表數據全部保存在RAM中。
i. 從CE v1.0開始到CE .NET之前,僅采用此技術來保存注冊表。每個新創建的內核都默認采用此技術來保存注冊表。
ii. 適合頻繁熱啟動而不冷啟動的設備。系統關閉時提供低電源給RAM。如果斷電,重新啟動設備后,系統將從內核中重新讀取注冊表數據到RAM。當然以前保存的用戶數據已經丟失。
iii. 基于RAM的注冊表也能夠永久保存注冊標數據。CE提供了兩個機制。
1) 第一種機制的設計思路是在設備關閉前調用RegCopyFile函數將整個注冊表數據以文件形式保存到永久存儲器上。重新啟動設備時,調用RegRestoreFile函數將文件全部讀出到RAM中。但是這時必須一次熱啟動才能使恢復的注冊表數據有效。所以每次啟動就多出一次熱啟動。好在熱啟動非常快,幾秒鐘的時間。
2) 另一種機制可以避免前一種機制的需要兩次啟動的缺點。但也有它的缺點。OEM(原始設備制造商)可以在OAL層編寫WriteRegistryToOEM and ReadRegistryFromOEM兩個函數,內核在啟動時會自動調用ReadRegistryFromOEM函數來讀注冊表數據。而應用程序調用RegFlushKey函數時,這個函數用調用WriteRegistryToOEM函數寫注冊表數據到永久存儲器上。這個機制避免了兩次啟動的缺陷。但問題出現在內核啟動時,調用ReadRegistryFromOEM之前文件系統驅動程序還沒加載,那就無法打開、讀取文件。CE幫助文件中說解決辦法是將從永久存儲器中讀取數據的代碼加到ReadRegistryFromOEM中。幫助中說的意思可不是調用ReadFile這么簡單的,因為文件系統驅動程 序還沒加載。
3) 個人建議:如果要采用基于RAM的注冊表保存機制,而且要求永久保存注冊表數據,使用第一種機制比較容易。
B、 基于HIVE的注冊表。用于將注冊表數據全部或部分保存到永久存儲器上。
i.它是從CE.NET開始采用的新技術。適合經常冷啟動而不熱啟動的設備。
ii.支持多用戶信息分別保存。當一個用戶登錄時,加載這個用戶的注冊表數據,注銷時卸載這個用戶的注冊表數據。
iii. HIVE是指一組鍵,包括子鍵、鍵值、數據。是保存或者加載注冊表數據的單位。分為系統HIVE(system hive)、用戶HIVE(uer hive)、引導HIVE(boot hive)。
1) 系統HIVE包含了關于系統的設置信息。具體保存注冊表中HKEY_LOCAL_MACHINE、HKEY_CLASSES_ROOT、HKEY_USERS鍵下所有數據。保存系統HIVE的文件的路徑在【HKEY_LOCAL_MACHINE\init\BootVars】下,鍵名為"systemhive",鍵值為文件的路徑。默認為"\Documents and Settings\system.hv"。
2) 用戶HIVE包含了一個用戶的信息。具體保存注冊表中HKEY_CURRENT_USER鍵下所有數據。保存用戶HIVE的文件的路徑同樣為【HKEY_LOCAL_MACHINE\init\BootVars】下,鍵名為"profiledir",鍵值為所有用戶HIVE的共同目錄。默認為"\Documents and Settings",在這個目錄下包含了以每個用戶名命名的子目錄。子目錄里含有一個文件,默認文件名為user.hv。
3) 引導HIVE保存在ROM(內核)中。具體保存內容同系統HIVE一樣。當解壓內核并加載注冊表時,系統先將引導HIVE數據讀出,引導HIVE包含了永久存儲器的驅動程序和文件系統的驅動程序,這些驅動加載后,系統HIVE被加載,然后引導HIVE被釋放。因為引導HIVE被包含在內核中,所以存在一種情況:如果重新做了一個新內核,引導HIVE中的數據同系統HIVE可能不相同。那么系統該加載哪個版本好呢?為此,CE在生成每個內核時都做了一個標志。而系統HIVE也存在這樣一個標志,當加載引導HIVE時,如果引導HIVE和系統HIVE的標志不相同,系統會刪除系統HIVE文件,然后重新創建一個文件并從引導HIVE復制數據。
iv. 永久保存注冊表數據
Windows CE.NET采用新的注冊表保存技術――基于HIVE的注冊表,的確讓人很興奮,在這之前基于Windows CE的設備,大多數采用給RAM供電方式來保存注冊表數據,雖然也可以通過RegCopyFile函數永久保存,但畢竟啟動時還要再熱啟動一次,有了基于HIVE的技術,啟動時系統會自動加載數據,免去了熱啟動的麻煩,而且當內核更新升級時,你不用擔心保存在永久存儲器上的系統HIVE文件影響你新的內核,系統會自動判斷并刪除過時的系統HIVE文件。只有擁有了這樣的技術,基于CE的產品才算是一個真正的電腦。
注:關于基于HIVE的注冊表的實現,暫不講解。
下面簡單說明 RegCopyFile和RegRestoreFile的用法。
///使用基于RAM的注冊表,利用RegCopyFile和RegRestoreFile
///實現永久保存注冊表數據。
#include <Pkfuncs.h>
#include <winbase.h>
CString strRegBackup = L"\\hard disk\\RegBackup.reg";
CString strTmp = L"\\windows\\temp.reg";
////////導出。在系統關閉前。
if(! RegCopyFile(strTmp)) ///導出注冊表,用temp.reg做緩沖用。
{
return FALSE;
}
if(! CopyFile(strTmp, strRegBackup, FALSE)) ///把temp.reg再復制到RegBackup.reg
{
return FALSE;
}
/////////導入。在系統啟動時。
if(! CopyFile(strRegBackup, strTmp, FALSE))
{
return FALSE;
}
if(! RegRestoreFile(strTmp)) ///恢復注冊表
{
return FALSE;
}
if(! KernelIoControl(IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL)) ///重新啟動
{
return FALSE;
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ymzhou117/archive/2009/11/11/4799873.aspx
以下內容含腳本,或可能導致頁面不正常的代碼 |
---|
說明:上面顯示的是代碼內容。您可以先檢查過代碼沒問題,或修改之后再運行. |
unsigned char CSStab2[256]=
{
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x08,0x0b,0x0a,0x0d,0x0c,0x0f,0x0e,
0x12,0x13,0x10,0x11,0x16,0x17,0x14,0x15,0x1b,0x1a,0x19,0x18,0x1f,0x1e,0x1d,0x1c,
0x24,0x25,0x26,0x27,0x20,0x21,0x22,0x23,0x2d,0x2c,0x2f,0x2e,0x29,0x28,0x2b,0x2a,
0x36,0x37,0x34,0x35,0x32,0x33,0x30,0x31,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,
0x49,0x48,0x4b,0x4a,0x4d,0x4c,0x4f,0x4e,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
0x5b,0x5a,0x59,0x58,0x5f,0x5e,0x5d,0x5c,0x52,0x53,0x50,0x51,0x56,0x57,0x54,0x55,
0x6d,0x6c,0x6f,0x6e,0x69,0x68,0x6b,0x6a,0x64,0x65,0x66,0x67,0x60,0x61,0x62,0x63,
0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x76,0x77,0x74,0x75,0x72,0x73,0x70,0x71,
0x92,0x93,0x90,0x91,0x96,0x97,0x94,0x95,0x9b,0x9a,0x99,0x98,0x9f,0x9e,0x9d,0x9c,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x89,0x88,0x8b,0x8a,0x8d,0x8c,0x8f,0x8e,
0xb6,0xb7,0xb4,0xb5,0xb2,0xb3,0xb0,0xb1,0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,
0xa4,0xa5,0xa6,0xa7,0xa0,0xa1,0xa2,0xa3,0xad,0xac,0xaf,0xae,0xa9,0xa8,0xab,0xaa,
0xdb,0xda,0xd9,0xd8,0xdf,0xde,0xdd,0xdc,0xd2,0xd3,0xd0,0xd1,0xd6,0xd7,0xd4,0xd5,
0xc9,0xc8,0xcb,0xca,0xcd,0xcc,0xcf,0xce,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf6,0xf7,0xf4,0xf5,0xf2,0xf3,0xf0,0xf1,
0xed,0xec,0xef,0xee,0xe9,0xe8,0xeb,0xea,0xe4,0xe5,0xe6,0xe7,0xe0,0xe1,0xe2,0xe3
};
unsigned char CSStab3[512]=
{
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,
0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff,0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff
};
unsigned char CSStab4[256]=
{
0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
};
unsigned char CSStab5[256]=
{
0xff,0x7f,0xbf,0x3f,0xdf,0x5f,0x9f,0x1f,0xef,0x6f,0xaf,0x2f,0xcf,0x4f,0x8f,0x0f,
0xf7,0x77,0xb7,0x37,0xd7,0x57,0x97,0x17,0xe7,0x67,0xa7,0x27,0xc7,0x47,0x87,0x07,
0xfb,0x7b,0xbb,0x3b,0xdb,0x5b,0x9b,0x1b,0xeb,0x6b,0xab,0x2b,0xcb,0x4b,0x8b,0x0b,
0xf3,0x73,0xb3,0x33,0xd3,0x53,0x93,0x13,0xe3,0x63,0xa3,0x23,0xc3,0x43,0x83,0x03,
0xfd,0x7d,0xbd,0x3d,0xdd,0x5d,0x9d,0x1d,0xed,0x6d,0xad,0x2d,0xcd,0x4d,0x8d,0x0d,
0xf5,0x75,0xb5,0x35,0xd5,0x55,0x95,0x15,0xe5,0x65,0xa5,0x25,0xc5,0x45,0x85,0x05,
0xf9,0x79,0xb9,0x39,0xd9,0x59,0x99,0x19,0xe9,0x69,0xa9,0x29,0xc9,0x49,0x89,0x09,
0xf1,0x71,0xb1,0x31,0xd1,0x51,0x91,0x11,0xe1,0x61,0xa1,0x21,0xc1,0x41,0x81,0x01,
0xfe,0x7e,0xbe,0x3e,0xde,0x5e,0x9e,0x1e,0xee,0x6e,0xae,0x2e,0xce,0x4e,0x8e,0x0e,
0xf6,0x76,0xb6,0x36,0xd6,0x56,0x96,0x16,0xe6,0x66,0xa6,0x26,0xc6,0x46,0x86,0x06,
0xfa,0x7a,0xba,0x3a,0xda,0x5a,0x9a,0x1a,0xea,0x6a,0xaa,0x2a,0xca,0x4a,0x8a,0x0a,
0xf2,0x72,0xb2,0x32,0xd2,0x52,0x92,0x12,0xe2,0x62,0xa2,0x22,0xc2,0x42,0x82,0x02,
0xfc,0x7c,0xbc,0x3c,0xdc,0x5c,0x9c,0x1c,0xec,0x6c,0xac,0x2c,0xcc,0x4c,0x8c,0x0c,
0xf4,0x74,0xb4,0x34,0xd4,0x54,0x94,0x14,0xe4,0x64,0xa4,0x24,0xc4,0x44,0x84,0x04,
0xf8,0x78,0xb8,0x38,0xd8,0x58,0x98,0x18,0xe8,0x68,0xa8,0x28,0xc8,0x48,0x88,0x08,
0xf0,0x70,0xb0,0x30,0xd0,0x50,0x90,0x10,0xe0,0x60,0xa0,0x20,0xc0,0x40,0x80,0x00
};
void CSSdescramble(unsigned char *sec,unsigned char *key)
{
unsigned int t1,t2,t3,t4,t5,t6;
unsigned char *end=sec+0x800;
t1=key[0]^sec[0x54]|0x100;
t2=key[1]^sec[0x55];
t3=(*((unsigned int *)(key+2)))^(*((unsigned int *)(sec+0x56)));
t4=t3&7;
t3=t3*2+8-t4;
sec+=0x80;
t5=0;
while(sec!=end)
{
t4=CSStab2[t2]^CSStab3[t1];
t2=t1>>1;
t1=((t1&1)<<8)^t4;
t4=CSStab5[t4];
t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
t3=(t3<<8)|t6;
t6=CSStab4[t6];
t5+=t6+t4;
*sec++=CSStab1[*sec]^(t5&0xff);
t5>>=8;
}
}
void CSStitlekey1(unsigned char *key,unsigned char *im)
{
unsigned int t1,t2,t3,t4,t5,t6;
unsigned char k[5];
int i;
t1=im[0]|0x100;
t2=im[1];
t3=*((unsigned int *)(im+2));
t4=t3&7;
t3=t3*2+8-t4;
t5=0;
for(i=0;i<5;i++)
{
t4=CSStab2[t2]^CSStab3[t1];
t2=t1>>1;
t1=((t1&1)<<8)^t4;
t4=CSStab4[t4];
t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
t3=(t3<<8)|t6;
t6=CSStab4[t6];
t5+=t6+t4;
k=t5&0xff;
t5>>=8;
}
for(i=9;i>=0;i--)
key[CSStab0[i+1]]=k[CSStab0[i+1]]^CSStab1[key[CSStab0[i+1]]]^key[CSStab0];
}
void CSStitlekey2(unsigned char *key,unsigned char *im)
{
unsigned int t1,t2,t3,t4,t5,t6;
unsigned char k[5];
int i;
t1=im[0]|0x100;
t2=im[1];
t3=*((unsigned int *)(im+2));
t4=t3&7;
t3=t3*2+8-t4;
t5=0;
for(i=0;i<5;i++)
{
t4=CSStab2[t2]^CSStab3[t1];
t2=t1>>1;
t1=((t1&1)<<8)^t4;
t4=CSStab4[t4];
t6=(((((((t3>>3)^t3)>>1)^t3)>>8)^t3)>>5)&0xff;
t3=(t3<<8)|t6;
t6=CSStab5[t6];
t5+=t6+t4;
k=t5&0xff;
t5>>=8;
}
for(i=9;i>=0;i--)
key[CSStab0[i+1]]=k[CSStab0[i+1]]^CSStab1[key[CSStab0[i+1]]]^key[CSStab0];
}
void CSSdecrypttitlekey(unsigned char *tkey,unsigned char *dkey)
{
int i;
unsigned char im1[6];
unsigned char im2[6]={0x51,0x67,0x67,0xc5,0xe0,0x00};
for(i=0;i<6;i++)
im1=dkey;
CSStitlekey1(im1,im2);
CSStitlekey2(tkey,im1);
本文轉貼自 【 浮游城 - Castle in the Sky | 開放邀請注冊,PS|SS|WII|DC下載研究中心 】 ,原文地址:http://bbs.chinaemu.org/read-htm-tid-93244.html
本方案設計CAN驅動是放在Windows CE操作系統的內核下層,位于OEM adaptation layer(OAL)層的一個真正的驅動,而不是在主程序中的串口操作。在Windows CE的設備管理器可以看到CAN1和CAN2兩個端口,并且可以查看其工作的正常與否和對其進行配置。如:中斷號和I/O地址。
2.1 CAN卡寄存器讀寫函數
CAN卡的通信是通過操作CAN卡上的CAN控制器進行的。在CAN控制器中有很多寄存器,如控制寄存器、命令寄存器、狀態寄存器、中斷寄存器等,通過讀寫這些寄存器中的命令狀態字可以檢測和控制CAN卡的行為。在Windows CE.NET下,通過調用DOK中的API函數HalTranslateBusAddress,將CAN卡分配的物理地址映射為邏輯地址。這樣各個寄存器對應的就是CAN卡基地址的偏移地址,因此,對寄存器的讀寫就轉化為對內存地址的讀寫。下面是CAN卡寄存器的讀寫函數:
*在偏移量為off的地址讀取一個字節的數據inline BYTE CANR(LPCAN_HW_OPEN_INFO hCan,DWORD off)
{
return hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off];
*將一個字節數據寫到偏移量為off的地址中inline VOID CANW(LPCAN_HW_OPEN_INFO hCan,DWORD off,BYTE val)
{
hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr[off]=val;
}
參數LPCAN_HW_OPEN_INFO定義的是CAN卡的數據結構,其中成員lpMappeBaseAddr[0]表示的是映射后基地址,lpMappedBaseAddr[1]就是基地址+1的地址,對應CAN卡的寄存器是命令寄存器。通過上述兩個函數可操作CAN卡上的所有寄存器。
2.2 CAN卡初始化
CAN卡的控制器比較復雜,在通信前必須確認硬件信息正確性、初始化各寄存器。初始化函數的基本流程如圖3所示。
第一步,檢查端口號和硬件信息的正確性,主要是CAN卡中斷號是否有效。
第二卡,設置CAN卡默認參數:
CanCardConfigInfo CAN_DEFAULT_SETTING=
{0X00,0XFF,0X03,0X1C};/*設置默認波特率為125Kbps*/
DWORD dwThreadID =0;
PHYSICAL_ADDRESS phyAddr={hwInfo->dwIOBaseAddr *16,0 };
第三卡,用WinCE API函數LocalAlloc為CAN卡驅動中用到的數據結構分配緩沖區;通過HalTranslateBusAddress和MmMapIoSpace函數映射I/O地址,提供直接訪問設備的虛擬地址:
if(!HalTranslateBusAddress(Isa,0,phyAddr,0,&phyAddr))
goto _ExitInit;
hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr=
(LPBYTE)MmMapIoSpace(phyAddr,CANCARDADDRLEN,FALSE);
if(!hCan->lpCanHWInfo->lpCanObj->lpMappedBaseAddr)
goto _ExitInit;
如果分配內存或映射邏輯地址失敗,則退出初始化程序,CAN卡初始化失敗。
第四步,初始化讀寫屬性、共享模式、讀超時時間和第二個CAN口的基地址。
第五步,創建CAN卡事件和數據接收事件:hCan->lpCanHWInfo->hCanEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
hCan->lpCanHWInfo->hRecvMsgEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
第六步,初始化中斷,如果CAN卡有復位請求就退出初始化程序。設置好中斷后啟動數據接收線程,設置線程優先級繼續線程處理;最后配置CAN卡參數,進入正常運行狀態。
2.3 CAN卡信息發送
CAN卡的信息發送分為兩個步驟。在對CAN卡基本信息進行檢查后,首先設置發送緩沖的ID號。CAN標準模式的ID號為11位,偏移地址10中存放的是ID號的高8位,偏移地址11的高3位存放的是ID號的低3位,剩下5位分別是RTR位(遠程傳送請求位)和數據長度。通過CANW函數將處理后的數據寫入到相應的偏移地址,設置完相應的地址數據后,通過循環將偏移地址12~19的數據采集回來存到數組中。然后,設置CAN卡的傳輸請求為允許并不斷偵測狀態寄存器的變化,當傳輸緩沖滿標志或傳輸結束標志為1時通出程序,完成一次數據采集。傳輸緩沖區的寄存器如表1所列。
表1
ID號 | 10 | ID.10 | ID.9 | ID.8 | ID.7 | ID.6 | ID.5 | ID.4 | ID.3 |
RTR,數據長度碼 | 11 | ID.2 | ID.1 | ID.0 | RTR | DLC.3 | DLC.2 | DLC.1 | DLC.0 |
數據1~8 | 12~19 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 |
表2
ID號 | 20 | ID.10 | ID.9 | ID.8 | ID.7 | ID.6 | ID.5 | ID.4 | ID.3 |
RTR,數據長度碼 | 21 | ID.2 | ID.1 | ID.0 | RTR | DLC.3 | DLC.2 | DLC.1 | DLC.0 |
數據1~8 | 22~29 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 | 數據 |
CAN消息發送函數的實現如下:
BOOL CAN_SendMessage(LPCAN_HW_OPEN_INFO hCan,LPCanCardMessageBuflpMsg)
{
BOOL bSuc=FALSE;
ASSERT(hCan && lpMsg && lpMsg->dwMessageLen <=8); /*防錯處理*/
if(0= =(hCan->dwAccessCode & GENERIC_WRITE))
return FALSE;
:: EnterCriticalSection(&hCan->lpCanHWInfo->
TransmitCritSec); /*進入臨界區*/
BYTE byV=static_cast<BYTE>(1pMsg->dwMsgID>>3);
CANW(hCan,10,byV); /*設置ID值高8位*/
byV=static_cast<BYTE>=((lpMsg->dwMsgID & 7)<<5);
if(lpMsg->bRTR) byV|=0x10;
byV+=static_cast<BYTE>(lpMsg->dwMessageLen);
CANW(hCan,11,byV);/*設置ID值低3位、RTR及數據長度*/
for(UINT i=0;<lpMsg->dwMessageLen;++i)
{
CANW(hCan,12+i,lpMsg->byMsg[i]);
} /*采集數據*/
CANW(hCan,1,1);/*重置傳輸請求*/
while(TRUE)
{byV=CANR(hCan,2);
if(byV & 0X40) /*傳輸緩沖區滿,退出*/
{break;}
if(byV & 0X8){ /*傳輸結束,正確返回退出*/
bSuc = TRUE;
break;}
}
::LeaveCriticalSection(&hCan->lpCanHWInfo->TransmitCritSec); /*離開臨界區*/
return bSuc;
}
2.4 CAN卡信息接收
CAN卡的信息接收是發送的逆過程,當接收緩沖區標志為1時,表示緩沖區已滿可以接收數據,將數據接收到數組后釋放接收緩沖區,然后對接收到的數據進行分解并存儲到CAN卡信息緩沖區的結構體。接收緩沖區的寄存器結構如表2所列。
CAN消息接收函數的實現如下:
BOOL CAN_RecvRecvMessage(LPCAN_HW_OPEN_INFO
HCan,OUT LPCanCardMessageBuflpMsg)
{……
if(CANR(hCan,2)&1){ /*判斷接收緩沖區是否已滿*/
for(UINT i=0;i<10;++i)
recvBuf[i]=CANR(hCan,20+i);/*將數據暫存到臨時緩沖區*/
CANW(hCan,1,4); /*釋放接收緩沖區*/
LpMsg->dwMsgID=recvBuf[0]<<3; /*取出ID的高8位*/
BYTE byV =recvBuf[1];
LpMsg->dwMsgID+=byV >>5;/*取出ID低3位,然后和高8位合并*/
LpMsg->bRTR =byV &0x10?TRUE:/*返回RTR狀態*/
LpMsg->dwMessageLen = byV &0XF; /*返回數據長度*/
……
}
else
{++hCan->lpCanHWInfo->dwErrorMsgCount;}/*沒有收到數據,錯誤計數加1*/
::LeaveCriticalSection(&hCan->lpCanHWInfo->
ReceiveCritSec); /*離開臨界區*/
Return bSuc;
}
2.5 CAN卡事件處理
CAN卡事件處理函數是CAN卡驅動程序中很重要的部分。驅動設計要求具有消息通知的功能,當事件發生時及時捕獲事件并進行消息處理。
下面是事件處理函數的實現:
staric DWORD WINAPI CAN_EventHanle(LPVOID lpParam)
{
ASSERT(lpParam);
LPCAN_HW_OPEN_INFO hCan=(LPCAN_HW_OPEN_INFO)lpParam;
CanCardMessageBuf bufMsg;
while(TEUE)
{ /*循環等待CAN卡消息產生,然后進行處理*/
::WaitForSingleObject(hCan->lpCanHWInfo->hCanEvent,0XFFFFFFFF);
if(hCan->lpCanHWInfo->bKillCanThread) break; /*若CAN線程已關閉則中斷*/
if(CAN_RecvMessage(hCan,&hufMsg)){ /*正確接收數據后*/
CAN_RecvBufPush(hCan,&bufMsg);} /*將數據壓入緩沖*/
BYTE byV=CANR(hCan,3); /*將3號寄存器讀出然后立即寫入*/
CANW(hCan,3,byV);/*能夠獲取每次中斷*/
InterruptDone(hCan->lpCanHWInfo->lpCanObj->dwSysIrqt);
} /*本次中斷結束,等待下次中斷*/
return 0;
}
2.6 其它函數
為了提供更多的功能和更方便地使用CAN卡進行通信,在CAN卡驅動程序中還設計了一些函數如CAN_Config用CAN卡信息配置、CAN_RecvBufPop用于處理接收緩沖區、CAN_Reset用于復位CAN卡、CheckHWInfo用于硬件信息檢查等。這些函數提供了對CAN通信卡的設置、檢查等功能,在這里不再詳述了。
3 CAN卡驅動封裝設計
CAN卡底層驅動函數雖然功能完整,但是對于用戶使用比較復雜并且一般用戶不需要了解底層實現的機制。為了便于使用,最后對CAN卡的驅動進行了封裝,提供CanOpenFile、CanSendMsg等五個函數用于CAN總線的通信,以動態連接庫(DLL)的形式提供給用戶調用。封裝函數及功能如下:
*CanOpenFile;初始化并打開CAN卡的一個端口。
*CanCloseFile;關閉由CanOpenFile打開的CAN卡端口。
*CanRecvMsg;接收CAN卡數據,打開CAN卡時必須具有GENERIC_READ權限。
*CanSendMsg;通過CAN卡發送數據。打開CAN卡時必須具有GENERIC_WRITE權限。
*CanIOControl;設置或獲取CAN卡I/O參數支持的I/O控制包括:IOCTL_CAN_CONFIG,IOCTL_CAN_RESET,IOCTL_CAN_TIMEOUT,IOCTL_CAN_SENDREADY,IOCTL_CAN_RECVREADY。
下面是CanSendMsg函數實現的代碼:
BOOL CanSendMSg(
HANDLE hCan,
LPCanCardMessageBuflpMsg)
{
if(!hCan||INVALID_HANDLE_VALUE= =hCan||
!lpMsg||lpMsg->dwMessageLen>8)return FALSE;
return CAN_SendMessage(LPCAN_HW_OPEN_INFO)
hCan,lpMsg);
該函數就是通過封裝CAN卡的底層驅動函數SendMessage來實現的,這樣將功能集中的五個函數更方便了用戶使用。
結語
程序開發的上位機是普通的PC機,軟件環境是:Windows2000 Professional、Embedded Visual C++4.0、與下位機中WinCE.NET對應的SDK,該SDK是在用Platform Builder 4.0定制WinCE時編譯生成的。下位機使用的硬件是研華的嵌入式PC104主板PCM3346N,操作系統為WinCE.ENT。
本文設計開發的驅動已經在北京懷柔的變電站項目中得到成功的應用,CAN卡通信穩定,系統在WINCE.NET下運行可靠,保證了項目的順利實施。
]]>以下內容含腳本,或可能導致頁面不正常的代碼 |
---|
說明:上面顯示的是代碼內容。您可以先檢查過代碼沒問題,或修改之后再運行. |
數字視頻監控系統是以計算機或嵌入式系統為中心、視頻處理技術為基礎組建的的一種新型監控系統,系統采用符合圖像數據壓縮的國際標準,綜合利用圖像傳感器、計算機網絡、自動控制和人工智能等技術。由于數字視頻監控系統對視頻圖像進行了數字化,所以與傳統的模擬監控系統相比,數字監控具有許多優點。數字化的視頻系統可以充分利用計算機的快速處理能力,對其進行壓縮、分析、存儲和顯示。數字化視頻處理技術提高了圖像的質量與監控效率,使系統易于管理和維護。整個系統是模塊化結構,體積小,易于安裝、使用和維護。正是由于數字視頻監控技術具有傳統模擬監控技術無法比擬的優點,而且符合當前信息社會中數字化、網絡化和智能化的發展趨勢,所以數字視頻監控技術正在逐步取代模擬監控技術,廣泛應用于各行各業。嵌入式系統以體積小、實時性強、性價比高、穩定性好等特點在社會的各個領域中得到了廣泛應用。筆者設計的一種嵌入式系統,以WinCE操作系統和ARM硬件平臺為核心實現了對現場的實時監控,并通過無線網絡把視頻圖像傳輸到主機端,以實現分析、存儲和顯示等功能。
1系統設計
本系統主要由操作系統定制、視頻圖像采集、視頻圖像無線傳輸三部分組成。系統的核心芯片選用基于ARM920T內核的S3C2410嵌入式微處理器,軟件環境選用MicrosoftWindowsCE操作系統。系統首先通過USB攝像頭采集現場實時視頻信息,并對其進行壓縮。然后,使用兩塊無線網卡在ARM開發板與上位機之間構建一個無線局域網絡,從而將壓縮的視頻數據傳輸到主機端,終端用戶即可在主機端通過流媒體播放程序查看遠程視頻影像。視頻監控系統總體結構框圖如圖l所示。
圖l、視頻監控系統總體結構框圖
2操作系統的定制
系統硬件平臺的核心芯片選用了S3C2410處理器,最高頻率可達203MHz。S3C2410處理器是Samsung公司基于ARM公司的ARM920T處理器核,采用O.18μm制造工藝的32位微控制器。該處理器具有較高的集成度,簡化了應用系統的硬件設計,提高了系統的可靠性。開發扳上還擴展了4MB的NORFlash、64MB的NANDFlash和64MB的DRAM。
系統選用了MicrosoftWilldowsCE(簡稱“WinCE”)操作系統。WinCE是一個緊湊的、高效且可擴展的32位操作系統,適用于各種嵌入式系統和產品。它擁有多線程、多任務和確定性的實時、完全搶占式優先級的操作系統環境,專門面向只有有限資源的硬件系統;同時,它的模塊化設計方式使得系統開發人員和應用開發人員能夠為多種多樣的產品來定制它,可以選擇、組合和配置WinCE的模塊和組件來創建用戶版的操作系統。
在WinCE產品開發中,主要有內核定制和應用程序開發兩項非常重要的工作。微軟在兩方面都提供了良好的開發工具,即內核定制工具PlatformBuilder(簡稱“PB”)和應用程序開發工具EmbeddedVisualC++(簡稱“EVC”)。
在系統定制過程中,各部分的關系如圖2所示。
3視頻圖像采集
3.1攝像頭驅動
圖像采集模塊的硬件資源選用了當前市面上應用最廣泛的USB接口的中星微攝像頭。該款攝像頭造價低廉,成像效果好,用于本系統中體現出了較高的性價比。系統在進行視頻采集前,首先要檢測設定視頻源。系統啟動后,WinCE操作系統會自動檢測攝像頭是否連接好。本系統在定制WinCE操作系統時,通過修改操作系統配置和注冊表。可以使系統自動加載攝像頭在WinCE下的驅動程序ZC030x.dll。
系統自動加載驅動程序時,首先要將驅動程序復制到\WINDOWS文件夾下,然后向注冊表中寫入攝像頭的驅動信息:
其中,prefix為設備文件名,D11為驅動的文件名,Order為設備文件名索引。硬件配置完成后啟動操作系統,就可以自動加載驅動,運行應用程序進行圖像采集了。
3.2圖像采集程序
中星微攝像頭采用了中星微301PLUS快速主控芯片。該芯片是一款高性能圖像壓縮芯片,輸出MIPEG視頻流數據。MIPEG(MotionJPEG)主要是基于靜態視頻壓縮發展起來的技術,特點是基本不考慮視頻流中不同幀之間的變化,只單獨對某一幀進行壓縮,通常可達到6:1的壓縮率。它的誤差穩定性非常好,可以獲取清晰度很高的視頻圖像,而且還可以靈活設置各路視頻清晰度,壓縮幀數。
本系統直接從攝像頭驅動中獲取MJPEG視頻流數據,圖像采集流程如圖3所示。
圖像采集模塊用到的主要函數有:
capInitCamera()用來初始化視頻設備,并獲取當前可用的視頻設備數目;
capSetVideoFormat()設置視頻格式和分辨率。本系統使用的視頻格式為RGB24,分辨率為320×240像素;
capGrabFrsme()從驅動中抓取1幀圖像,并存儲在緩存lpFrameBuffer中;
capGetLastJpeg()將抓取的MJPEG格式的圖像轉換成JPEG格式,送到無線發送模塊。
capCloseCamera()關閉視頻設備;
視頻采集部分還有查詢視頻采集格式、設置明暗度、設置對比度等相關函數,不再詳述。
4視頻傳輸部分
4.1配置無線網卡
圖像傳輸模塊主要是通過USB接口的無線網卡來實現的。該無線網卡可與S3C2410集成的USB主機接口直接相連,工作在2.4GHz的ISM頻段,采用直接序列擴頻通信方式,遵從802.11g協議,傳輸速度可達54Mbps,室內有效距離為100m,能夠滿足局域網內視頻傳輸的要求。本系統通過開發板和主機之間的無線網卡構建無線局域網絡,能夠實現點對點的無縫連接,用戶通過此無線網絡可以實現文件傳輸、視頻通信等應用。
開發板端的無線網卡也需要加載驅動才能運行。本系統在定制WinCE操作系統時,首先將無線網卡的驅動程序復制到\WINDOWS文件夾下,然后向注冊表中寫入無線網卡的驅動信息。WinCE操作系統啟動后會自動檢測無線網卡是否連接好,并加載驅動程序,此時,就可以通過應用程序調用此無線網卡了。在無線傳輸時,注意要把開發板和主機設置在同一IP網段。
4.2傳輸視頻數據
實時傳輸協議RTP(RealtimeTransportProtocol)是一種實時流式傳輸協議,能夠保證媒體信號帶寬與當前網絡狀況相匹配,在一對一(umcast,單播)或者一對多(multicast,多播)的網絡環境中實現流媒體數據的實時傳輸。RTP通常使用UDP來進行多媒體數據的傳輸。整個RTP協議由兩個密切相關的部分組成:RTP數據協議和RTCP控制協議。
WinCE中的GWES模塊負責加載和管理Touch Panel驅動,Touch Panel的MDD層向上提供DDI接口,PDD層是針對硬件的實現,對MDD層提供DDSI接口。
1 Touch Panel驅動中的數據結構
(1) TOUCH_PANEL_SAMPLE_FLAGS
用于描述一個采樣點的信息,這些信息被定義在一個枚舉結構中:
enum enumTouchPanelSampleFlags {
TouchSampleValidFlag = 0x01,
TouchSampleDownFlag = 0x02,
TouchSampleIsCalibratedFlag = 0x04,
TouchSamplePreviousDownFlag = 0x08,
TouchSampleIgnore = 0x10,
TouchSampleMouse = 0x40000000
};
TouchSampleValidFlag:一個有效的采樣值
TouchSampleDownFlag:第一次按觸摸屏時,返回該flag
TouchSampleIsCalibratedFlag:采樣的x和y坐標值不需要再被校驗了
TouchSamplePreviousDownFlag:表示上一次采樣狀態是按在觸摸屏上
TouchSampleIgnore:忽略這次采樣值
TouchSampleMouse:預留
(2) TPDC_CALIBRATION_POINT
用于描述一個校驗點的相關信息,結構如下:
struct TPDC_CALIBRATION_POINT {
INT PointNumber;
INT cDisplayWidth;
INT cDisplayHeight;
INT CalibrationX;
INT CalibrationY;
};
PointNumber:校驗點索引值,用于描述校驗點在LCD上的位置
0:中間
1:左上
2:左下
3:右下
4:右上
cDisplayWidth:顯示的寬度
cDisplayHeight:顯示的高度
CalibrationX:校驗點的x坐標值
CalibrationY:校驗點的y坐標值
(3) TPDC_CALIBRATION_POINT_COUNT
用于描述需要校驗的點的個數,結構如下:
struct TPDC_CALIBRATION_POINT_COUNT {
DDI_TOUCH_PANEL_CALIBRATION_FLAGS flags;
INT cCalibrationPoints;
};
flags:一般為0
cCalibrationPoints:需要校驗的點的個數,一般是5
(4) gIntrTouch和gIntrTouchChanged
這是兩個被MDD層用到的中斷,需要在PDD層中定義,如下:
DWORD gIntrTouch = SYSINTR_NOP;
DWORD gIntrTouchChanged = SYSINTR_NOP;
gIntrTouch用于描述觸摸屏中斷,要和硬件的觸摸屏中斷相關聯。
gIntrTouchChanged用于在觸摸屏按下后,每隔一段時間進行一次采樣,應該和硬件的一個定時器中斷相關聯。
這兩個值應該在DdsiTouchPanelEnable(..)函數中和硬件中斷關聯,并在函數DdsiTouchPanelGetPoint(..)中根據情況清除相應的中斷。
2 MDD層API
MDD為上層導出所需的Touch Panel驅動接口函數,上層通過這些函數可以完成對Touch Panel的操作,下面會介紹這些函數的功能。
(1) BOOL TouchPanelEnable(PFN_TOUCH_PANEL_CALLBACK pfnCallback):
使能Touch Panel設備,用于初始化Touch Panel。
pfnCallback:指向處理Touch Panel事件的回調函數
(2) Void TouchPanelDisable(void):
禁用Touch Panel設備。
(3) BOOL TouchPanelGetDeviceCaps(INT iIndex, LPVOID lpOutput ):
獲得Touch Panel設備的相關信息。
iIndex:索引值
TPDC_SAMPLE_RATE_ID:采樣率信息
TPDC_CALIBRATION_POINT_COUNT_ID:采樣點個數信息
TPDC_CALIBRATION_POINT_ID:采樣點坐標信息
lpOutput:指向一個內存區域,用于存放獲得的相關信息
(4) VOID TouchPanelCalibrateAPoint(INT32 UncalX, INT32 UncalY, INT32* pCalX, INT32* pCalY):
將輸入的未經過校驗的坐標信息轉換成校驗后的坐標信息。
UncalX:輸入的X坐標
UncalY:輸入的Y坐標
pCalX:校驗后的X坐標
pCalY: 校驗后的Y坐標
(5) VOID TouchPanelPowerHandler(BOOL bOff):
Touch Panel的電源控制函數。
bOff:TRUE表示關閉電源,FALSE表示打開電源
(6) BOOL TouchPanelReadCalibrationPoint(INT* pRawX, INT* pRawY):
獲得Touch Panel的坐標。
pRawX:觸摸屏的X坐標
PRawY:觸摸屏的Y坐標
(7) VOID TouchPanelReadCalibrationAbort(void):
終止當前的校驗。
(8) VOID TouchPanelSetCalibration(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer):
]]>由于嵌入式設備硬件平臺的多樣性,CPU芯片的快速更新,嵌入式操作系統要求支持常用的嵌入式CPU,如X86, ARM, MIPS, POWERPC等,并具有良好的可移植性。另外還需要支持種類繁多的外部設備。Linux支持以上幾乎所有的主流芯片,并且還在不斷的被移植到新的芯片上。而在這方面,WinCE顯然差得很遠。
2.占有較少的硬件資源
由于多數嵌入式系統具有成本敏感性,處理器速度較低 ,存儲器空間較少,這要求嵌入式OS體積小,速度快。Linux體系結構比較靈活,易于裁減,可以小到2M flash,4M RAM。而WinCE對資源的要求更高。
3.高可定制性
由于不同的嵌入式應用對系統要求各不相同,這要求嵌入式OS具備高可定制性,能夠根據需要方便的增加和減少各項功能模塊。這一點對于嵌入式領域至關重要,而Linux由于圖形系統不在內核中,且支持模塊機制,內核可根據需要加入或去掉功能。其外圍工具擁有眾多選擇,更由于可以自由修改源代碼,具有極強的可定制性。而WinCE/Windows根本無法做到這一點。
4.具有實時處理能力
]]>在事隔Windows Embedded CE 5.0推出兩年后,微軟新版Windows Embedded CE 6.0反應這個嵌入式操作系統后起之秀加緊腳步的決心。 其一的最大作為就是迎擊Linux、Wind River陣營長期以來對其定制化不足的攻擊。
微軟臺灣營銷經理許妙華表示,Win CE 6.0的核心源代碼將悉數開放予硬件合作伙伴,供其修改源代碼開發客制化的文件系統、設備驅動程序與其他元件,而不需分享他們的最終設計給微軟或第三方。
另外,加快產品開發時程也是Win CE 6.0的一大躍進。許妙華指出,Visual Studio Visual Studio 2005專業版將包含在Win CE 6.0的開發工具中。
而Platform Builder成為Visual Studio 2005專業版的外掛程序(plug-in),協助設計人員完成從嵌入式操作系統客制化到應用程序開發等所有工作,縮短產品開發的上市時程。
WinCE 6.0現已開始提供合作伙伴下載。根據微軟所述,許多廠商將在本季推出基于新的WinCE 6.0的應用產品,臺灣地區的合作伙伴包括了精技電腦、研華科技、威盛電子等。產品內容則涵蓋了便攜式導航設備、媒體播放器、遠端監視設備、IP網絡電話與游戲機等。
WinCE是微軟針對嵌入式系統產品開發的精簡型操作系統。微軟約在十年前進入這個領域。所謂的嵌入式產品包括了智能手機、PDA、機頂盒(Set- top-box)等具有運算能力的設備。
在智能手機領域里,微軟的競爭對手包含了Symbian和Linux;在其他嵌入式設備市場,Linux亦和微軟有所角力。
雖然微軟穩坐桌面操作系統龍頭寶座,但是相較其在嵌入式系統市場所遭遇到的對手——Linux和Wind River,微軟一直到前年才終于超越Linux成為第一大的嵌入式操作系統廠商;惟在針對手持設備所推出的Windows Mobile操作系統,微軟在這塊市場的占有比例還甚小。
此次微軟宣布源代碼開放并非首樁,不過確是微軟難得的大動作。該公司在WinCE 4.2版時,也曾提供開放源代碼,不過只針對研究單位,而源代碼較少,為200萬行。
在兩年前推出WinCE 5.0時,則開放250萬行源代碼程序作為評估套件(evaluation kit),凡是個人、廠商都可以下載這些源代碼加以修改使用。
“分享的源代碼比前一版本的Windows Embedded CE大幅增加56%,”許妙華說。
雖然開放分享源代碼,可望提高微軟OEM客戶定制化的能力,但是微軟長期以來另一被詬病之處——授權費過高的問題仍未獲解決。對此微軟仍重提時間就是成本的優勢。
微軟亞洲區嵌入式系統事業部暨全球ODM Ecosystems資深副總經理吳勝雄指出,WinCE嵌入式系統產品平均開發時間為8個月,若以Linux開發則平均得拉長至14個月。
此外WinCE具有各式各樣的模組,在Linux上可能得自行開發或另外授權,事實上Linux不見得免費或比較便宜,嵌入式系統廠商必須以上市時間等整體開發成本為考慮。
除源代碼全數開放、與Visual Studio開發工具整合外,許妙華表示,WinCE 6.0可同時支持32,000個程序和每個程序高達2GB的虛擬內存定址空間,且保有軟件的實時(real-time)功能。讓開發人員可將更多應用程序加入更復雜的設備
]]>