6

私はいくつかの科学機器と相互作用する新しい機器のソフトウェアに取り組んでいます。ユーザーインターフェイスは、Windows CE Pocket PC(Windows CE 600 V3.01 Build 195)を介して行われます。機器は、フレックスケーブルの一方の端が常にPCのSDカードスロットに差し込まれている状態でセットアップされます。ケーブルは機器に接続され、もう一方の端は、取り付けられているSDカードが存在する場合は接続されます。SDカードには、機器で使用するためのチップ、必要に応じてソフトウェア/ファームウェアのアップデート、およびチップに関連するデータファイルが含まれています。WinCEの起動時に実行されるac#ソフトウェアアプリケーションがあります。このアプリケーションは、特定の機能について付属のチップに関連するデータに依存するため、SDMMCカードの存在をチェックします。

私の問題:WinCEの起動時にSDカードがフレックスケーブルのもう一方の端に挿入されると、winCEがカードの存在を検出し、ソフトウェアがデータを読み取れるように\SDMMCフォルダーが作成されます。フレックスケーブルのみが接続されていて、もう一方の端にSDMMCカードがない場合、Windowsはフォルダーを作成しません。これは私が期待しています。ただし、フィールドエンジニアは、ソフトウェアがアクティブなときにチップを交換するために、さまざまな理由でカードを交換します。これは、カードが挿入される前にWindowsが起動された場合に問題になります。フレックスケーブルが原因で、WinCEはカードが挿入されたことを検出しません。また、削除されたことを検出することもありません。

ソフトウェアは5秒ごとにSDカードをポーリングします。ファームウェアは、ビットの設定を介してカードが挿入されているかどうかを判断でき、この情報をソフトウェアに中継します。カードが以前は存在していなかったが、現在は検出されているが、\ SDMMCフォルダーが存在しない場合は、ソフトウェアでWinCEをトリガーして検出を再試行する必要があります。レジストリ値を使用することを考えましたが、HKEY_LOCAL_MACHINESDMMc値の存在を記述できるかどうかは明確ではありません。また、値が何を意味するのかよくわかりません。これらをリセットできますか?StorageManagerレジストリがこれを次のように定義しているようです。

[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMMC] 
"Name"="SD MMC device"
"Folder"="SD Card

このレジストリを読み書きしてwinCEを調べ、ケーブルのもう一方の端にカードが挿入されていることを確認する方法はありますか?私はこの考えで完全にベースから外れていますか?これを行う他の方法はありますか?

長い質問をお詫び申し上げます。私は通常、アプリケーションレベルでプレイします。この問題をグーグルで検索しても、必要な答えが得られませんでしたが、適切な質問をするのに十分な知識がない可能性があります。あなたが私に与えることができるどんな助けにも感謝します。

更新:私はまだこの問題の解決策を見つけようとしています。私の現在の考えは、機器のファームウェアがカードが挿入されたことを検出したときに、WindowsCEにデバイスを再列挙させることです。私のコードはファームウェアをポーリングして、私のc#アプリケーションでこの通知を受け取ります。私の機器/アプリケーションでは、SDカードは常に「Dsk2:」にあります。c#アプリケーションは、SDカードが挿入されたという通知を受け取ると、次のことを行うメソッドを呼び出します。

コード

     hDevice = CreateFile("\\Dsk2:", (0x80000000) | (0x40000000), 0,
        IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

     if (hDevice == INVALID_HANDLE_VALUE)
     {
        int hDeviceError = Marshal.GetLastWin32Error();
        // THis is an error - call GetLastERror to find
        // out what happened.
        using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append)))
        {
           String iua = "DevDriverInterface: error from CreateFile: " + hDeviceError.ToString();
           bw.WriteLine(iua);
        }
        return false;
     }

     bResult = DeviceIoControl(hDevice,
        IOCTL_DISK_UPDATE_PROPERTIES, 
        null,
        0,
        null,
        0,
        ref nBytesReturned,
        nOverLapped);

/コード

上記では、CreateFile()呼び出しはエラー55で失敗します:「指定されたネットワークリソースまたはデバイスは使用できなくなりました」。

私の質問:デバイスを再列挙するために私がやろうとしていることは合理的ですか?CreateFileエラーは、代わりにActivateDevice()呼び出しを行う必要があることを示していますか?ここに例があります: 起動時にデバイスドライバーをロードする際の問題 -c#コードからActivateDevice()を呼び出す人のWM6.1は、WindowsCEにSDカードが現在あることを認識させる問題を処理するかどうか疑問に思います挿入されました。誰かがウィンドウのActivateDevice()コマンドに送信するパラメータを理解するのを手伝ってもらえますか?私はこのアプローチでオフベースですか?

これは私にとってすべて新しい領域であり、あなたが提供できるどんな助けにも感謝します。ありがとう。

4

3 に答える 3

2

興味のある方は、問題を修正したコードをご覧ください。このメソッドは、電源投入後に SD カードが挿入または削除されたことをファームウェアが検出したときに呼び出されます。本質的に、デバイス ドライバーをアンロード/ロードします。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
 public struct DEVMGR_DEVICE_INFORMATION
 {
  public uint dwSize;
  public IntPtr hDevice;
  public IntPtr hParentDevice;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
  public string szLegacyName;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  public string szDeviceKey;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  public string szDeviceName;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
  public string szBusName;
}

public enum DeviceSearchType : int
{
  DeviceSearchByLegacyName = 0,
  DeviceSearchByDeviceName = 1,
  DeviceSearchByBusName = 2,
  DeviceSearchByGuid = 3,
  DeviceSearchByParent = 4
}
class DevDriverInterface
{
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  public struct SECURITY_ATTRIBUTES
  {
     public int nLength;
     public IntPtr lpSecurityDescriptor;
     public bool bInheritHandle;
  }

  [DllImport("coredll.dll", SetLastError = true)]
  public extern static int ActivateDeviceEx(string device, IntPtr regEnts,
     UInt32 cRegEnts, IntPtr devKey);

  [DllImport("coredll.dll", SetLastError = true)]
  public extern static bool DeactivateDevice(int handle);

  [DllImport("coredll.dll", SetLastError = true)]
  public static extern int FindFirstDevice(DeviceSearchType
  searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi);

  // Constructor
  public DevDriverInterface() { }

  public bool MountSDCardDrive()
  {
     const int INVALID_HANDLE_VALUE = -1;

     string mRegPath1 = "";
     int handle = INVALID_HANDLE_VALUE;
     DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName;

     DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION();
     di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION));

     String searchParamString = "SDH1";

     IntPtr searchParam = Marshal.StringToBSTR(searchParamString);

     handle = FindFirstDevice(searchType, searchParam, ref di);

     if (handle == INVALID_HANDLE_VALUE)
     {
        // Failure - print error
        int hFindFirstDeviceError = Marshal.GetLastWin32Error();
        using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, 
            FileMode.Append)))
        {
           String iua = "DevDriverInterface: error from FindFirstDevice: " + 
                  hFindFirstDeviceError.ToString();
           bw.WriteLine(iua);
        }
        return false;
     }
     else
     {
        mRegPath1 = di.szDeviceKey;
        bool deactBool = DeactivateDevice((int) di.hDevice);
        if (deactBool == false)
        {
           using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile,
              FileMode.Append)))
           {
              String iua = "DevDriverInterface: DeactivateDevice: returned false -
                          FAILED";
              bw.WriteLine(iua);
           }
           return false;
        }

        Thread.Sleep(50);
        // Call ActiveDevice to setup the device driver
        handle = ActivateDeviceEx(mRegPath1, IntPtr.Zero, 0, IntPtr.Zero);
        if (handle == INVALID_HANDLE_VALUE)
        {
           // Failure - print error
           int hActivateDeviceError = Marshal.GetLastWin32Error();

           using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, 
              FileMode.Append)))
           {
              String iua = "DevDriverInterface: error from ActivateDevice: " + 
                     hActivateDeviceError.ToString();
              bw.WriteLine(iua);
           }
           return false;
        }

     }

     return true;
  }

}; // end class
于 2013-01-21T19:19:13.327 に答える
1

この問題は、Advantech の同僚の助けを借りて解決されました。彼らは、デバイス ドライバーのロード/アンロードによって、SD カードが挿入されたことを認識するために wince がトリガーされることを確認した、小さな C++ 実行可能ファイルを提供してくれました。私の問題は、これを私のC#アプリケーションで動作させることになりました。このスレッド(私自身の投稿)の助けを借りて:

c# FindFirstDevice マーシャリング

デバイスを識別する文字列として "SDH1" を使用して FindFirstDevice() を呼び出し、次に DeactivateDevice()/ActivateDeviceEX() を呼び出すことで、これを機能させることができました。誰かが特定のコードに興味を持っている場合は、後で投稿できます (私は今家にいて、コードは職場のラップトップにあります)。

于 2013-01-20T23:32:40.790 に答える
0

適切に機能しているシステムでのイベントの順序を見てみましょう。

  1. デバイスが起動し、SD/MMC ドライバーをロードします
  2. カードスロットにカードが挿入されている
  3. ハードウェア割り込みが発生します (おそらく電源検出、おそらくデータ - これは OEM に依存します)
  4. 割り込みハンドラは、カードが存在することを SDMMC ドライバに通知しました
  5. ドライバーがカードの種類を問い合わせる
  6. 適切な関数ドライバー (ストレージなど) が読み込まれます (またはストレージの場合は通知されます)。
  7. ファンクション ドライバーは、ハードウェアを OS およびアプリケーションに公開する役割を果たします。

問題は、カードがスロットに既にある場合、起動時に #3 が適切に行われないことです。これは、SD または USB のプラットフォーム開発では珍しいことではありません。スロットに電源が投入される前に、割り込みハンドラーが機能し、マスクを解除する必要があります。

特に OAL (Microsoft ではなく、ハードウェアの製造元によって開発された OS の一部) がブラック ボックスである場合、これに対するソフトウェアの回避策を作成することは非常に困難です。この場合だと思います。

明確にするために、これは間違いなくプラットフォームのバグです。最初のアクションは、デバイスの OEM のサポート グループに連絡して、バグがあることを伝え、修正してもらうことができるかどうかを確認することです。

それが失敗した場合 (多くのデバイスを購入していない場合、またはデバイスが古い場合、サポートを取得するのは....困難です)、プラットフォームの SDMMC ドライバーを掘り下げて、何らかの方法でアクセスできるかどうかを確認することをお勧めします。プロセスの途中。私は試したことがありません (私は常にこれの OEM 側にいて、ドライバーまたはプラットフォーム コードを修正しただけです)、解決策があるかどうかさえわかりませんが、一見の価値があります。

Platform Builder の評価版をダウンロードしてインストールすると、ソース コードを無料で入手できます (必ず「ソースのインストール」オプションを選択してください)。それはすべて C であり、ブラウズしようとするのはあまり楽しいことではありませんが、「ソースを使用してください、ルーク」ということわざがあります。

于 2013-01-03T14:41:58.213 に答える