AndroidタブレットをUSBデバイス(STM32 Nucleo)と通信させようとしています。私はgithubで利用可能なスケッチを開発しました:
- モバイル アプリケーションは Xamarin と VS Studio で開発されています。USBホストとして機能します
- STM32 Nucleo アプリケーションは STMCube で開発され、その USB スタックを使用して CDC デバイスとして機能します。
- 「登録」ID/値を交換するための小さなマスター/スレーブプロトコルを開発しました。デバイスはスレーブです。
Android.hardware.usb API を使用して動作させることができました。しかし、他のプラットフォームで使用されているように、ネイティブ C 共有オブジェクト ライブラリを通信に使用する必要があり、それが現在問題になっています。swig を使用してライブラリを埋め込み、VS Studio でビルドします。ライブラリがデバイスと通信するようにするには、次の 2 つの方法を試しました。
- Android 側から許可と fd を取得し、標準の読み取り/書き込み操作を行うライブラリに渡します。
- Android から上記と同じことを行いますが、Linux の usbdevice_fs API を使用してバルク転送を呼び出すエンドポイント番号も fd で渡します。その質問で提示したような多かれ少なかれ。
どちらの方法も失敗し、存在しない fd に関するエラーが返されます。fd と enpoints の値を確認しましたが、Android と同じです。Android USB デバイス モニターを起動しましたが、作成した fd が見つかりません。termux のような Android シェルを使用して、プロセス /proc ツリーを一覧表示することはできません。それでも、Android 側で tehm を使用できます。
コミュニティから、fd をネイティブ ライブラリに渡すことが正しい方法であることを確認しました。私は今何をすべきかわかりません。他に許可を求めることはできますか?
以下は、 fd を取得する方法です。
_devHandle.usbdev = _devHandle.usbManager.DeviceList[name];
// Ask for permission to access the created device
if (!_devHandle.usbManager.HasPermission(_devHandle.usbdev))
{
PendingIntent pi = PendingIntent.GetBroadcast((ContextWrapper)_context, 0, new Intent(ACTION_USB_PERMISSION), 0);
_devHandle.usbManager.RequestPermission(_devHandle.usbdev, pi);
/* We check the permission was given
*/
if (!_devHandle.usbManager.HasPermission(_devHandle.usbdev))
{
// Loose !
Log.Debug("pandavcom", "FAILED : did not have persmission to open device" + _devHandle.usbdev.DeviceName);
return;
}
}
// Now open the port, with the USB Manager : we get the fd/enpoints and pass it to library, no more
_devHandle.connection = _devHandle.usbManager.OpenDevice(_devHandle.usbdev);
if (_devHandle.connection != null)
{
if (OpenInterface(_devHandle.usbdev, _devHandle.connection, ref _devHandle.usbIface, ref _devHandle.ep_in, ref _devHandle.ep_out) == 0)
{
_devHandle.fd = _devHandle.connection.FileDescriptor;
Log.Debug("pandavcom", "opened device endpoint" + _devHandle.usbdev.DeviceName + "with descriptor: " + _devHandle.fd);
}
else
{
Log.Debug("pandavcom", "FAILED : open device endpoint" + _devHandle.usbdev.DeviceName);
}
}