Armadilloフォーラム

ホストで定義したudev/rules.dのデバイスをコンテナで使いたい

urasue

2023年10月16日 9時46分

お世話になっております。
浦末です。
USB-シリアル変換デバイスを複数繋いでCOMを増設しています。
ポートの順序が

ホスト側でudevのルールを定義しSYMLINKで名称を付けました。
このデバイスをコンテナ側で使いたい場合、コンテナのconfigをどのように記述すればよいでしょうか。

armadillo:~# cat /etc/udev/rules.d/10-ftdi_board_1.rules
KERNELS=="3-1.2.1.1" , \
SUBSYSTEMS=="usb",\
DRIVERS=="usb", \
ATTRS{idVendor}=="0403", \
ATTRS{idProduct}=="6001",\
SYMLINK+="ttyUSB_BORD1_%n"
コメント

at_dominique.m…

2023年10月16日 10時55分

浦末さん、

お世話になっています、
マルティネです。

> このデバイスをコンテナ側で使いたい場合、コンテナのconfigをどのように記述すればよいでしょうか。

生成されているリンクを普通に使えます。

起動前に接続されていて、コンテナの起動前に ttyUSB が認識されている場合は add_devices で symlink も使えます。
コンテナを以下のコンフィグで起動すれば、/dev/ttyUSB_BOARD0 は正しい char device として生成されます。

set_image docker.io/alpine
set_command sleep infinity
add_devices /dev/ttyUSB_BOARD0

USB の場合は認識が遅いか接続が切れる恐れもありますので、「add_devices /dev/ttyUSB...」 ではなく、 「add_hotplugs ttyUSB」を推奨します。
以下のコンフィグで、リンクが追加された際にすぐ使えるようになります。

set_image docker.io/alpine
set_command sleep infinity
add_hotplugs ttyUSB

ちなみに、

> KERNELS=="3-1.2.1.1" , \

これはパス(USB ポート)で固定したいように見えますが、/dev/serial/by-path にリンクがすでに生成されると思います。
よろしければ使ってください。
ファイルパスに: の文字がある場合に add_devices を使えませんが、add_hotplugs で問題ありません。add_device (s無し、一つのデバイスだけ追加するコマンド)にもワークアラウンドも入ってます。

SUBSYSTEMS=="usb",\

/dev/ttyUSBx のリンクでしたら、SUBSYSTEMS=="tty" ですが、usb でもマッチしていますか?

> SYMLINK+="ttyUSB_BORD1_%n"

(BORD -> BOARD の typo があります)
%n を使う場合にファイル名が固定されてませんが、よろしいでしょうか?

よろしくお願いします。

urasue

2023年10月16日 15時21分

マルティネさん
お世話になっております。
ご回答ありがとうございます。

>これはパス(USB ポート)で固定したいように見えますが、/dev/serial/by-path にリンクがすでに生成されると思います。

はい。その通りです。
接続される機器の場所は決まっているので、ruleは使わずにby-pathを使いたいと思います。
add_hotplugs の追加でコンテナ側も認識できるようになりました。

今回、USB-シリアル変換には、FTDIのFT4232Hを使用しています。
4232Hを4つ載せて16ポートにしており、そのうちの2ポートのみRS485で使用するため、
EEPROM上のRI(TXDEN)のフラグを立てようとしています。

FTDIのドライバからFT_Openでポート番号(整数)を指定して、EEPROMへ書き込んでいるのですが、
物理的なポート位置とOS(ドライバ?)が認識しているポート番号がどのように紐づいているのかがわからず、
狙ったデバイスにデータを書き込めない状態です。
デバイスを一つずつ繋げば問題ないのですが、デバイスを基板に実装する予定ですので、4つ繋いだ状態でEEPROMへ
書き込みたいと考えております。

at_dominique.m…

2023年10月16日 16時10分

浦末さん、

マルティネです。

> 今回、USB-シリアル変換には、FTDIのFT4232Hを使用しています。
> 4232Hを4つ載せて16ポートにしており、そのうちの2ポートのみRS485で使用するため、
> EEPROM上のRI(TXDEN)のフラグを立てようとしています。
>
> FTDIのドライバからFT_Openでポート番号(整数)を指定して、EEPROMへ書き込んでいるのですが、
> 物理的なポート位置とOS(ドライバ?)が認識しているポート番号がどのように紐づいているのかがわからず、
> 狙ったデバイスにデータを書き込めない状態です。
> デバイスを一つずつ繋げば問題ないのですが、デバイスを基板に実装する予定ですので、4つ繋いだ状態でEEPROMへ
> 書き込みたいと考えております。

FT4232H や他の FTDI チップを手元にありませんが、以下の「D2XX Programmer's Guide」を参考にすると「FT_Open」でデバイスを選択することは不可能になっていますね。
代わりに、「FT_OpenEx」で指定することはできそうです。
https://www.ftdichip.com/Support/Documents/ProgramGuides/D2XX_Programme…

少しややっこしいですが、例えば「udevadm info /dev/serial/by-path/platform....」で ID_SERIAL を取得してそちらをFT_OPEN_BY_SERIAL_NUMBER で使えれば USB port で選択できるように見えます。

ちなみに、そのライブラリは /dev/bus/usb のデバイスも使ってますので、書き込みの際に add_hotplugs に "usb_devices" も追加する必要がありそうです。

それ以上の確認はあまり取れないと思いますが、何かあればまた聞いてください。

urasue

2023年10月16日 17時01分

マルティネさん
浦末です。
ご回答ありがとうございます。

>FT4232H や他の FTDI チップを手元にありませんが、以下の「D2XX Programmer's Guide」を参考にすると「FT_Open」でデバイスを選択することは不可能になっていますね。
>代わりに、「FT_OpenEx」で指定することはできそうです。

FT_OpenExでFT_OPEN_BY_SERIAL_NUMBERしてOpenする機能ですが、EEPROMに書き込まれているシリアル番号(実際には文字列)を
使うようです。
EEPROMに既に書き込まれている場合は有効なのですが、これから書き込もうとしていますので指定する事ができません。
ジャンパー等で機器が一つだけ有効になるようにして書き込むか、もしくはTEDENを485以外のポートでも有効にして影響がないか確認して、
影響が無ければ設定を共通にしてみようかと思います。

at_dominique.m…

2023年10月16日 17時38分

浦末さん、

マルティネです。

> FT_OpenExでFT_OPEN_BY_SERIAL_NUMBERしてOpenする機能ですが、EEPROMに書き込まれているシリアル番号(実際には文字列)を
> 使うようです。
> EEPROMに既に書き込まれている場合は有効なのですが、これから書き込もうとしていますので指定する事ができません。

なるほど、シリアルポートのシリアル番号ではなく、自分で書き込むようなものですね。
確かに、空の状態では使える物ではないです。

> ジャンパー等で機器が一つだけ有効になるようにして書き込むか、もしくはTEDENを485以外のポートでも有効にして影響がないか確認して、
> 影響が無ければ設定を共通にしてみようかと思います。

そうですね、ジャンパーまでじゃなくても、linux の USB ドライバーでデバイスを無効化すれば ftd2xx で認識されないところまで設定できるかもしれません。

FT232R と ftd2xx の FT_CreateDeviceInfoList/FT_GetDeviceInfoList だけで試して見たところ、ftdi の /sys ディレクトリに「echo 1 > remove」でデバイスを認識しないようにすれば、書き込みしたくないデバイスを一時的に無効化して他のデバイスを書き込みできるかもしれません。

armadillo:~# lsusb | grep FTDI
Bus 001 Device 033: ID 0403:6001 FTDI FT232R USB UART
 
# 親の USB FTDI デバイスのパスを確認します
armadillo:~# udevadm info -a /dev/serial/by-path/platform...
...
  looking at parent device '/devices/platform/soc@0/32f10100.usb/38100000.dwc3/xhci-hcd.1.auto/usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{manufacturer}=="FTDI"
    ATTRS{product}=="FT232R USB UART"
...
 
# デバイス無効化
armadillo:~# cd /sys/bus/usb/devices/1-1/1-1.2
armadillo:/sys/bus/usb/devices/1-1/1-1.2# echo 1 > remove
armadillo:/sys/bus/usb/devices/1-1/1-1.2# lsusb | grep FTDI
# この状態で ftd2xx でもリストできなくなっているみたいです
 
# デバイスの再スキャン
armadillo:/sys/bus/usb/devices/1-1# cd /sys/bus/usb/devices/1-1/driver/
armadillo:/sys/bus/usb/devices/1-1/driver# echo 1-1 > unbind 
armadillo:/sys/bus/usb/devices/1-1/driver# echo 1-1 > bind 
armadillo:/sys/bus/usb/devices/1-1/driver# lsusb | grep FTDI
Bus 001 Device 037: ID 0403:6001 FTDI FT232R USB UART

それ以上は難しいかもしれません、FTDI のライブラリーのコードがないので FTDI に問い合わせしないと何ともいえません。

おっしゃるとおり、デバイスすべてを書き込んでいいなら、その方が楽ですね。そちらを確認した上で、usb ドライバの操作も試してみてください。

よろしくお願いします。

urasue

2023年10月17日 19時37分

マルティネさん
お世話になります。
浦末です。

>FT232R と ftd2xx の FT_CreateDeviceInfoList/FT_GetDeviceInfoList だけで試して見たところ、ftdi の /sys ディレクトリに「echo 1 > remove」でデバイスを認識しないようにすれば、書き込みしたくないデバイスを一時的に無効化して他のデバイスを書き込みできるかもしれません。
情報ありがとうございます。
無効化する事が出来ました。
同じパラメータで動作する事も確認できましたので、こちらで進めたいと思います。