ソリューションを検索
- 自分で考えてみてください
- 技術サポートにお問い合わせください
最も抵抗の少ない道を歩み、何が行われたのか技術サポートに尋ねることが決定されました。 留守番電話は、休暇中の全員が1週間半後に戻ると私に書いた。 今回は待つことにしました。 私は約2週間後に再び書き込み、 私は答えを得る 。
私の質問への答えから、彼らはCドライバーを持っていて、Linuxの下でしかいなかったので、私には合わなかった。
登録検索
ユーザーリファレンスマニュアルを開きます 。 見る、見る: 0500-053F PCH GPIO構成ポート 。 範囲を決定し、特定のアドレスを探しています。説明には、 PCH BD82QM67への動作不能なリンクがあります。
検索、発見: インテル®6シリーズチップセットおよびインテル®C200シリーズチップセットデータシート 。 あまりにも多くのGPIOが見つかりました。 よく見ると、必要なGPIOはGP_LVL3 —入力または出力3レジスタの GPIOレベルとGP_LVL2 —入力または出力2レジスタのGPIOレベルであることがわかります。 アドレスを見ると、それぞれGPIOBASE + 48hおよびGPIOBASE + 38hです。 GPIOBASE-0x500 これは0x500-0x53Fの範囲外にあります。 ユーザーリファレンスマニュアルにもう1つエラーがあると仮定します(結局、既に間違ったリンクがあった)。
特権アクセスライブラリ
住所は見つかりましたが、連絡する必要があります。 特権アクセスが必要です。 IOPort、Jioportが試されましたが、何か問題が発生しました(私に特権の増加を要求しました(つまり、特権アクセス))。 何か間違ったことをしたかもしれませんが、うまくいきませんでした。 その後、UserPortプログラムのアドバイスを受けました。 プログラムの説明では、Windows NT / XPでの作業について説明しています。
試行番号1
UserPort.sysを実行し、C:\ Windows \ System32 \ driversに配置します。 UserPort.exeを起動します。 入力されたアドレススペースがあることがわかります。 0x500-0x53Fを追加します。 [停止]-> [更新]-> [開始]をクリックし、OSを再起動します。
試行番号2
起動間の唯一の違いはUserPortです。 セーフモードで起動し、UserPort.sysを削除して再起動すると、システムが起動し、すべてが正しくなります。 理由を探しています。 ドライバーをその場所に戻します。 デフォルトで入力されたアドレススペースを削除し、再起動して...システムが起動しました。 理由が見つかりました:デフォルトで入力されたのと同じアドレススペース。
C ++ライブラリ
UserPortにはサンプルコードツールが付属しています。
サンプル
void outport(unsigned int portid, unsigned int value) { __asm mov edx, portid; __asm mov eax, value; __asm out dx, ax; } void outportb(unsigned int portid, unsigned char value) { __asm mov edx, portid __asm mov al, value __asm out dx, al } unsigned char inportb(unsigned int portid) { unsigned char value; __asm mov edx, portid __asm in al, dx __asm mov value, al return value; } unsigned int inport(unsigned int portid) { auto value = 0; __asm mov edx, portid __asm in ax, dx __asm mov value, eax return value; }
ライブラリコードの記述
ここで、 JavaとC ++で友達を作る方法の記事が役に立ちました。 パート1とプログラムは、jnaerator-0.11シェーディングのBridjライブラリです。 自動生成ヘッダー:
dllmain.cpp
// dllmain.cpp: DLL. #include "stdafx.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
javahから取得したファイル:
NativeGPIO.h
#pragma once #include <jni.h> /* Header for class NativeGPIO */ #include "stdafx.h" /** * », ¤ ¤ ¤ (.dll) */ extern "C" { #define GPIO1 0x538 #define GPIO2 0x548 /**„ gpio1 1 integer*/ extern __declspec(dllexport) unsigned int readGPIO1(); /**„ gpio2 1 integer*/ extern __declspec(dllexport) unsigned int readGPIO2(); /**¤ */ extern __declspec(dllexport) unsigned char inportb(unsigned int portid); /**¤ int */ extern __declspec(dllexport) unsigned int inport(unsigned int portid); /**¤ int */ extern __declspec(dllexport) void outport(unsigned int portid, unsigned int value); /**¤ */ extern __declspec(dllexport) void outportb(unsigned int portid, unsigned char value); }
関数の操作を説明するファイル:
NativeGPIO.cpp
// dllmain.cpp: DLL. // NativeGPIO.cpp: DLL. // #include "stdafx.h" #include "NativeGPIO.h" #include <windows.h> void outport(unsigned int portid, unsigned int value) { __asm mov edx, portid; __asm mov eax, value; __asm out dx, ax; } void outportb(unsigned int portid, unsigned char value) { __asm mov edx, portid __asm mov al, value __asm out dx, al } unsigned char inportb(unsigned int portid) { unsigned char value; __asm mov edx, portid __asm in al, dx __asm mov value, al return value; } unsigned int inport(unsigned int portid) { auto value = 0; __asm mov edx, portid __asm in ax, dx __asm mov value, eax return value; } unsigned readGPIO2() { jint value = inportb(GPIO2); return value; } unsigned readGPIO1() { jint value = inportb(GPIO1); return value; }
念のため、inport / outportメソッドを転送しました。 .dllでコンパイルすると、ライブラリの準備ができました。
プログラムに紹介します
JNAetratorを使用し、次のものを受け取ります。
NativeGPIOLibrary
import org.bridj.BridJ; import org.bridj.CRuntime; import org.bridj.ann.Library; /** * Created by Koksharov on 04.09.2015. * package = com.astra.app.neptun.applicationmanager * project = ApplicationManager */ @Library( "NativeGPIO" ) @org.bridj.ann.Runtime( CRuntime.class ) class NativeGPIOLibrary { { BridJ.register(); } public final int GPIO2 = ( int ) 1352; public final int GPIO1 = ( int ) 1336; /** * Original signature : <code>int readGPIO1()</code> * <i>native declaration : line 8</i> * GPIO 1, 0x538 * * @return , 1-4 */ native public int readGPIO1 (); /** * Original signature : <code>int readGPIO2()</code> * <i>native declaration : line 9</i> * GPIO 2, 0x548 * * @return , 5-8 */ native public int readGPIO2 (); /** * Original signature : <code>char inportb(unsigned int)</code> * <i>native declaration : line 10</i> * , ( , * ) * * @return , (-) */ native public byte inportb ( int portid ); /** * Original signature : <code>int inport(unsigned int)</code> * <i>native declaration : line 11</i> * , ( , * ) * * @return , (-) */ native public int inport ( int portid ); /** * Original signature : <code>void outport(unsigned int, unsigned int)</code> * <i>native declaration : line 12</i> * , ( , * , * ) */ native public void outport ( int portid, int value ); /** * Original signature : <code>void outportb(unsigned int, unsigned char)</code> * <i>native declaration : line 13</i> * , ( , * , * ) */ native public void outportb ( int portid, byte value ); }
次に、無限ループで読み取り値を記述します。
使用例
for (;;){ System.out.println(NativeGPIOLibrary.readGPIO1()); System.out.println(NativeGPIOLibrary.readGPIO2()); int GPIOValue1 = (NativeGPIOLibrary.inport(NativeGPIOLibrary.GPIO1)); int GPIOValue2 = (NativeGPIOLibrary.inport(NativeGPIOLibrary.GPIO2)); int GPIOValue_34 = (NativeGPIOLibrary.inport(NativeGPIOLibrary.GPIO_34)); int GPIOValue_44 = (NativeGPIOLibrary.inport(NativeGPIOLibrary.GPIO_44)); System.out.println(GPIOValue1 + " " + GPIOValue2 + " " + GPIOValue_34 + " " + GPIOValue_44); int gp1 = GPIOValue1;// & 0b1111110; int gp2 = GPIOValue2;// & 0b1111111; if ( (gp1 & 0b00001000) == 0 ){ System.out.println("button 1 1 pressed"); } if ( (gp1 & 0b00010000) == 0 ){ System.out.println("button 1 2 pressed"); } if ( (gp1 & 0b00100000) == 0 ){ System.out.println("button 1 3 pressed"); } if ( (gp2 & 0b00100000) == 0 ){ System.out.println("button 2 1 pressed"); } if ( (gp2 & 0b00010000) == 0 ){ System.out.println("button 2 2 pressed"); } if ( (gp2 & 0b01000000) == 0 ){ System.out.println("button 2 3 pressed"); } if ( (gp2 & 0b10000000) != 0 ){ System.out.println("button OFF pressed"); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }
始めます、私たちは見ます:特権の欠如。 次に、何が間違っていたのかを考え、0x500-0x53Fと0x500 + 0x48について思い出す必要がありました。 獲得可能な拡張スペース。
おわりに
実際、ほぼすべての段階で、この記事で説明されているよりもはるかに多くの時間が費やされたので、この記事が他の誰かに役立つことを願っています。