はじめに
MOXA社製UPort11xxもRasPiで使用が可能
ただし、HPでDLできるものはSRCのため、ARMアーキテクチャ用(RasPiCPU用)にビルドする必要がある。
Kernel6.x対応
MOXA社のHP↓
ドライバDLサイト
対応するLinuxカーネルの選択
対応するLinuxカーネルを選択するためにRasPi側のOSカーネルバージョンを調べる↓
uname -r
uname -a
uname -m
Kernel 6.xにおける不具合
不具合 rasPi5 kernel6.6.x時
2024年10月10日時点ではRaspberry Pi(5)のKernel6.6.51+rpt-rpi-2712に合わせて
最新版6.0をセットアップしたところ以下の不具合が確認されている。
************************************************************************
Debian GNU/Linux 12
\l 6.6.31+rpt-rpi-2712
MOXA UPort 11x0 series driver ver 6.0
Release Date: 2023/03/14
************************************************************************
**********************************WARNING*******************************
MOXA UPort 11x0 series driver hes been tested under kernel 6.2.0
That may not be compatible with Linux Kernel version 6.6.31+rpt-rpi-2712 .
Please download the latest driver at http://www.moxa.com first.
If you still have issue, you can contact support@moxa.com
************************************************************************
*******************************************************************
MOXA UPort 11x0 series USB to Serial Hub Driver v6.0
release date : 2023/03/14
*******************************************************************
Build unsuccessfully! Please check build.log for further information
make[1]: *** [Makefile:63: module] Error 1
make: *** [Makefile:16: install] Error 2
*現時点でのUPortドライバの確認はkernel6.2.0での確認まで
*6.6.31xxxでのコンパチは確認できない
*実際ビルドエラーが発生している
エラーの内容は以下の理由による。
- usb_serial_driver構造体の.break_ctl変数(関数へのポインタ)に割り当てられる関数の戻り値仕様の変更による(build.logの内容より)
- 従来はvoid型
- 最新はint型 おそらく→ に記載(面倒くさいので確認はしていない)
対策
- カーネルを旧バージョンに戻してもよいが、最新カーネルを使いたいので、ソースを変更する。
- 変更ソースはmxu11x0.cのみ
- 修正関数はmxu1_break関数(の戻り値)
修正箇所は以下:
199行目付近
- static void mxu1_break(struct tty_struct *tty, int break_state); # ←void型
+ static int mxu1_break(struct tty_struct *tty, int break_state); # ←int型
1737行目付近 (-をコメントアウトまたは削除/+を追加)
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
static void mxu1_break(struct usb_serial_port *port, int break_state)
{
#else
- static void mxu1_break(struct tty_struct *tty, int break_state)
+ static int mxu1_break(struct tty_struct *tty, int break_state)
{
struct usb_serial_port *port = tty->driver_data;
#endif
struct mxu1_port *mxport = usb_get_serial_port_data(port);
dbg("%s - state = %d", __FUNCTION__, break_state);
if (mxport == NULL)
//return;
+ return 0;
mxu1_drain(mxport, (mxport->mxp_closing_wait*HZ)/100, 0);
if(break_state == -1)
mxport->mxp_send_break = MXU1_LCR_BREAK;
else
mxport->mxp_send_break = 0;
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
mxu1_set_termios(mxport->mxp_port,NULL);
#else
mxu1_set_termios(NULL, mxport->mxp_port,NULL);
#endif
+ return 0;
}
- 修正したら再度ビルドする
- 上記ソース変更については過去のカーネルの動作は保証できないので各々で修正方法は工夫すること
不具合 kernel6.1時
2023年5月9日時点ではRaspberry Pi(4)のKernel6.1.21に合わせて
最新版6.xがUPされている。
Driver for UPort 1100 Series (Linux kernel 6.x)
本Verにおいては、V5.1xでの不具合とmxu11x0.cのソース修正は対策されており不要である。
ただし、Raspberry Pi側の不具合により以下の対応が必要になる。
RasPi OS 32bitをkernelアップデートした場合に64bit表示になってしまう。
当方所有のRasPi OSは32bitでセットアップしているにもかかわらず
2023年5月時点においてupdateしたところカーネルはv6.1.21にUpdateされたが
どうやら64bitの設定にセットアップされてしまっているようであった。
(本件はバグかどうか現時点で不明)
現象としては以下のコマンドにより確認できる。
uname -r
-> 6.1.21-v8+
uname -m
-> aarch64
対策方法
/boot/config.txt
に
arm_64bit=0
を追記する
sudo nano /boot/config.txt
uname -r
-> 6.1.21-v7l+
uname -m
-> armv7l
Kernel 5.xにおける不具合
2021年9月2日時点での最新版5.1がUPされているが↓
Driver for UPort 1100 Series (Linux kernel 5.x)
本Verは5.10.103-v7lまでは動作確認済
ただし5.15.32-v7lでは動作しないので注意
mxu11x0/driver/mxu11x0.c:341:21: error: initialization of ‘unsigned int (*)(struct tty_struct *)’ from incompatible pointer type ‘int (*)(struct tty_struct *)’ [-Werror=incompatible-pointer-types]
暫定対策 (kernel v6.1.21では不要)
・mxu11x0\mxu11x0.cを修正する
具体的には以下の2つの関数の戻り値をint⇒unsigned intに修正する。
static int mxu1_write_room(struct tty_struct *tty);
static int mxu1_chars_in_buffer(struct tty_struct *tty);
ソースの修正箇所については以下の通り
static unsigned int mxu1_write_room(struct tty_struct *tty);
static unsigned int mxu1_chars_in_buffer(struct tty_struct *tty);
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
static int mxu1_write_room(struct usb_serial_port *port)
{
#else
static unsigned int mxu1_write_room(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
#endif
struct mxu1_port *mxport = usb_get_serial_port_data(port);
int room = 0;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->port_number);
if (mxport == NULL)
return -ENODEV;
spin_lock_irqsave(&mxport->mxp_lock, flags);
room = mxu1_buf_space_avail(mxport->mxp_write_buf);
spin_unlock_irqrestore(&mxport->mxp_lock, flags);
dbg("%s - returns %d", __FUNCTION__, room);
return room;
}
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27))
static int mxu1_chars_in_buffer(struct usb_serial_port *port)
{
#else
static unsigned int mxu1_chars_in_buffer(struct tty_struct *tty)
{
struct usb_serial_port *port = tty->driver_data;
#endif
struct mxu1_port *mxport = usb_get_serial_port_data(port);
int chars = 0;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->port_number);
if (mxport == NULL)
return -ENODEV;
spin_lock_irqsave(&mxport->mxp_lock, flags);
chars = mxu1_buf_data_avail(mxport->mxp_write_buf);
spin_unlock_irqrestore(&mxport->mxp_lock, flags);
dbg("%s - returns %d", __FUNCTION__, chars);
return chars;
}
DLと解凍
moxa-uport-1100-series-linux-kernel-6.x-driver-v6.x.tgzを解凍
moxa-uport-1100-series-linux-kernel-6.x-driver-v6.x\readme.txt を参照(手順が記載されている)
2. System Requirements
3. Installation
はななめ読みする。
3.3 Module driver configuration
3.3.1 Build the MOXA driver
3.3.2 Load the MOXA driver
を実施する(以下の方法で) 3.4は不要
インストール
事前知識↓
Raspi上でドライバをインストールする。
インストールの方法は
・クロス環境(PC等)でビルドし、ターゲットシステムにロードする
・ネイティブ環境(この場合ターゲットシステムで直接)でビルドし、設定の上使用する。
今回はネイティブ環境でビルドする。 すなわち後者で行う。
ワークフォルダ(例)
RasPiのセットアップ例にて
/home/pi/share/driver
の作成および実行権限、読書権限をしている前提での説明となる。
準備
1.ビルド
ネイティブ環境でビルドする場合でもカーネルの機能にアクセスするためのカーネルヘッダ等が必要になります。下記コマンドでインストールする
sudo apt-get install raspberrypi-kernel-headers
/usr/srcにファイルが展開される
参考URL
https://qiita.com/iwatake2222/items/1fdd2e0faaaa868a2db2
2.MOXA UPortドライバDLファイルの配置(例)
以下にドライバを展開する(mxu11x0フォルダ)
cd /home/pi/share/driver
/home/pi/share/driver/mxu11x0に移動する
cd mxu11x0
必要に応じて実行権限をつける
chmod -R 0755 .
以下のコマンドでインストール
sudo make clean
sudo make install
カーネルモジュールをロードし、確認する
sudo modprobe mxu11x0
lsmod
###【参考】
以下mの通りlibフォルダへのコピーまで実施してくれる
@cp -f ./$(TARGET).ko /lib/modules/$(KVER)/misc/
インストールは以上
SetserialによるConfiguration
setserialのインストール
インストール後、UPort1150の機能設定を行うためにインストールが必要
マルチポート動作できるのでRS422で動かしたい場合は明示的にRS422で動作させる設定が必要
インストールは以下でできる
sudo apt install setserial
portの設定をすることでRS422に設定できる。
port 0 RS-232
1 RS-485 2W
2 RS-422
3 RS-485 4W
setserial /dev/ttyUSB0 port 2
どうやら電源断により上記設定は失われる。
保存の方法は別途調査する。