昨天簡單介紹如何存取環控晶片暫存器後,今天就把概念轉換為函式實作,一樣是暫時將函式實作在Non-Pnp驅動程式範例裡的測試程式。
testapp.c
DeviceIoControl
,將對應的I/O control code傳到指定的裝置,使指定的裝置執行對應的函式,詳細參數內容可以自行閱讀參考內容。IO_PORT_INPUT
作為input buffer,傳遞I/O埠號和寫入I/O埠的資料。unsigned char
所宣告的變數傳入,因為我們的回傳值都是一個byte。bytesReturned
則是用來承接回傳的長度。nsigned char ReadIoPort(
HANDLE hDevice,
unsigned int Index
)
BOOL Result = FALSE;
unsigned char Output;
unsigned long bytesReturned;
IO_PORT_INPUT Input;
Input.PortNumber = Index;
Result = DeviceIoControl(hDevice,
(DWORD)IOCTL_CUSTOM_READ_IO_COMMAND,
&Input,
sizeof(Input),
&Output,
sizeof(Output),
&bytesReturned,
NULL
);
return Output;
``
``c
OOL WriteIoPort(
HANDLE hDevice,
unsigned int Index,
unsigned int Data
)
BOOL Result = FALSE;
IO_PORT_INPUT Input;
unsigned char Output;
Input.PortNumber = Index;
Input.IoPortData.CharData = (unsigned char)Data;
Result = DeviceIoControl(hDevice,
(DWORD)IOCTL_CUSTOM_WRITE_IO_COMMAND,
&Input,
sizeof(Input),
&Output,
sizeof(Output),
NULL,
NULL
);
return Result;
``
oid OpenSioConfig(HANDLE hDevice)
unsigned int Index = SIO_INDEX_PORT;
printf("OpenSioConfig\n");
WriteIoPort(hDevice, Index, 0x87);
WriteIoPort(hDevice, Index, 0x87);
return;
``
``c
oid CloseSioConfig(HANDLE hDevice)
unsigned int Index = SIO_INDEX_PORT;
printf("CloseSioConfig\n");
WriteIoPort(hDevice, Index, 0xAA);
return;
``
nsigned char ReadSio(
HANDLE hDevice,
unsigned int Index
)
unsigned int IndexPort = SIO_INDEX_PORT;
unsigned int DataPort = SIO_DATA_PORT;
unsigned char Output;
WriteIoPort(hDevice, IndexPort, Index);
Output = ReadIoPort(hDevice, DataPort);
return Output;
``
``c
OID WriteSio(
HANDLE hDevice,
unsigned int Index,
unsigned int Data
)
unsigned int IndexPort = SIO_INDEX_PORT;
unsigned int DataPort = SIO_DATA_PORT;
BOOL Result = FALSE;
Result = WriteIoPort(hDevice, IndexPort, Index);
Result = WriteIoPort(hDevice, DataPort, Data);
return;
``
DoIoctls
後。
OpenSioConfig
進入Extended Function Mode。CloseSioConfig
離開Extended Function Mode。OID
oIoPortTest(
HANDLE hDevice
)
unsigned char res;
printf("\nDoIoPortTest\n");
OpenSioConfig(hDevice);
WriteSio(hDevice, 0x07, 0x0D);
res = ReadSio(hDevice, 0x30);
printf("SIO read result: 0x%2X\n", res);
CloseSioConfig(hDevice);
printf("\n");
return;
``
以上函式連同Day11驅動程式的部分加入Non-Pnp driver sample後,重新編譯Non-Pnp driver sample,依照Day08的步驟執行nonpnpapp.exe
會得到以下畫面,可以看到DoIoPortTest
有成功讀取到logical device D,暫存器位置0x30的值,讀出的數值為0xA0。
為了正確性,使用第三方軟體RW來驗證,一樣切換到logical device D,可以看到暫存器位置0x30的值與測試程式結果一致,測試成功。
環控晶片 - NCT6796D
DeviceIoControl
RWEverything