Armadilloフォーラム

シリアル送受信で受信できない

shsuga

2025年2月25日 18時05分

==========
製品型番:Armadillo440
Debian/ABOSバージョン:
カーネルバージョン:2.6.26-at24
3G/LTE モジュール情報 (Debianのみ):
その他:
==========

Armadillo440付属のシリアルコネクタ(CON3)を使用して他機器との通信プログラムを作成しています。
送受信は、標準関数(open,write,read,close)を使用しています。
送信(write)は問題ないのですが、受信(read)が上手くできません。

シリアルアナライザーで確認したところ、送受信とも出来ているのですが、read関数にて受信すると以下のエラーになります。
EAGAIN (11): リソースが一時的に利用できない。
デバイスファイル(/dev/ttymxc1)は非ブロックモードでオープンしていますので(open(”(/dev/ttymxc1”,O_RDWR|O_NONBLOCK))
50ms WAITしてリトライを40回するのですが受信できません。
以上にように受信データはArmadilloに届いているのに、読みだせないか、廃棄されている?

シリアル設定は以下の通り
 ボーレート   57600bps
 データ     8bit
 パリティ   奇数
 ストップビット   1
 デバイスファイル /dev/ttymxc1

[シリアル設定確認]
stty -F /dev/ttymxc1 -a
speed 57600 baud; rows 0; columns 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb parodd cs8 hupcl -cstopb cread clocal crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

/etc/inittab は編集済みです(コンソール未使用)

他のアプリなどが、/dev/ttymxc1 をつかんでいる可能性を考え、以下を確認
ps aux | grep tty
1289 root 400 S /bin/setstty
1290 root 636 S sh -c /sbin/getty -L 115200 ttymxc2 vt102
1510 root 760 S /sbin/pppd /dev/ttyUSBmodem 115200 connect /etc/ppp/ppp-on-dialer
1541 root 2028 S sshd: root@ttyp0

対処方法または確認事項などご教示頂けると幸いです。
以上、よろしくお願いいたします。

コメント

at_dominique.m…

2025年2月25日 18時14分

shsugaさん

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

> EAGAIN (11): リソースが一時的に利用できない。
> デバイスファイル(/dev/ttymxc1)は非ブロックモードでオープンしていますので(open(”(/dev/ttymxc1”,O_RDWR|O_NONBLOCK))
> 50ms WAITしてリトライを40回するのですが受信できません。

O_NONBLOCK でオープンするとデーターがない場合に EAGAIN が帰ってきて、受信できたら読めるようになるはずです。

いくつかを確認させてください:
* read の間に close/open を繰り返すとデーターが廃棄されますので、同じ fd を利用しつづけていますか。
* 確認のため、O_NONBLOCK を外すといずれ受信できるようになっていますか。(アプリのままで難しい場合はテストプログラムで試していただければと思います)

両方とも問題なければ心当たりがないので、もしよろしければ問題を再現するコードを見せていただければ確認します。

よろしくお願いします。

早速ご確認いただきありがとうございます。

以下にご質問に回答いたします。

> * read の間に close/open を繰り返すとデーターが廃棄されますので、同じ fd を利用しつづけていますか。
データ送信時の最初にオープンして、受信完了までオープンしたままで問題が発生します。
送信時完了時にクローズして受信時に再オープンしてみましたが、現象は変わらずでした。

> * 確認のため、O_NONBLOCK を外すといずれ受信できるようになっていますか。(アプリのままで難しい場合は
> テストプログラムで試していただければと思います)
相手が起動しているかは不明のため、O_NONBLOCK で受信して40回失敗するとエラーで戻って繰り返すので、
O_NONBLOCK を解除しても、いずれ相手と通信が確立すれば受信するようになっています。
試しに、O_NONBLOCK を外すと、想定通り、受信時の最初の read から戻ってきません。

> 両方とも問題なければ心当たりがないので、もしよろしければ問題を再現するコードを見せていただければ確認します。
実ソースは投稿できないので、テスト用プログラムを作成しましたので添付します。

お手数をおかけしますが、何卒よろしくお願いいたします。

ファイル ファイルの説明
rs232c_test.c

at_dominique.m…

2025年2月26日 17時46分

shsugaさん

> > * read の間に close/open を繰り返すとデーターが廃棄されますので、同じ fd を利用しつづけていますか。
> データ送信時の最初にオープンして、受信完了までオープンしたままで問題が発生します。
> 送信時完了時にクローズして受信時に再オープンしてみましたが、現象は変わらずでした。

了解です。
送信と受信の間にクロースするとその間に受信した文字があればなくなりますので、クロースしない方がいいです。
こちらに関してはいただいたテスト用のコードで問題なさそうです。

> > * 確認のため、O_NONBLOCK を外すといずれ受信できるようになっていますか。(アプリのままで難しい場合は
> > テストプログラムで試していただければと思います)
> 相手が起動しているかは不明のため、O_NONBLOCK で受信して40回失敗するとエラーで戻って繰り返すので、
> O_NONBLOCK を解除しても、いずれ相手と通信が確立すれば受信するようになっています。
> 試しに、O_NONBLOCK を外すと、想定通り、受信時の最初の read から戻ってきません。

確認しますが、O_NONBLOCKを外しても read から戻らないということは、文字を受信できてないということですね(少なくともソフトまでに)
となると NONBLOCK の問題ではなく、stty の設定から確認した方がいいと思います。
例えば、stty で parenb を設定して parity bit を有効にしますが、対向機で parity bit の設定が合わないと送信された文字が認識されず read で受け取れません。

stty の設定を変更して受信できるようになりますでしょうか?
シリアルコンソールを何かのデバイスに接続していると思いますが、もし可能でしたら一度別の armadillo や PC に接続しなおして設定を合わせた状態で受信できるかを確認してみるのもいいかもしれません。(そこまで確認できれば後は機器と合わせるだけなので)

> > 両方とも問題なければ心当たりがないので、もしよろしければ問題を再現するコードを見せていただければ確認します。
> 実ソースは投稿できないので、テスト用プログラムを作成しましたので添付します。

おそらく不具合の原因になってないですが recv_data() 内の retry の初期値がないのですぐ一度だけ read してすぐ止める可能性がありますので、 `int retry = 0` 等で初期化してください。

よろしくお願いします

> 確認しますが、O_NONBLOCKを外しても read から戻らないということは、文字を受信できてないということですね(少なくともソフトまでに)
> となると NONBLOCK の問題ではなく、stty の設定から確認した方がいいと思います。

はい、NONBLOCKを外しても文字を受信できませんでした。

> 例えば、stty で parenb を設定して parity bit を有効にしますが、対向機で parity bit の設定が合わないと送信された文字が認識されず read で受け取れません。

こちらでも、stty設定を色々と変更して確認していますが、不具合を解消できません。
因みに、相手機とWindows上でのシリアルデバッグツールでシリアル設定を合わせて通信すると、正しく送受信できます。
同様に本プログラムが稼働しているArmadilloとWindows上のシリアルデバックツールで送受信すると、やはり受信エラーになります。
以上のことから、こちらも、stty設定の問題と考えているのですが、通信速度、パリティあり、奇数パリティ、ストップビット1つ、データサイズ8bit を合わせても、受信できません。

> stty の設定を変更して受信できるようになりますでしょうか?

現在、色々と試していますが、相変わらず受信できません。
何が悪いかを判断する方法があれば良いのですが、sttyはオプションが多数あるので大変です。

> シリアルコンソールを何かのデバイスに接続していると思いますが、もし可能でしたら一度別の armadillo や PC に接続しなおして設定を合わせた状態で受信できるかを確認してみるのもいいかもしれません。(そこまで確認できれば後は機器と合わせるだけなので)
>
前述したように、PCとは接続確認しましたが、Armadilloだけ上手く受信できません。
他のArmadilloとの通信は確認してみます。

> おそらく不具合の原因になってないですが recv_data() 内の retry の初期値がないのですぐ一度だけ read してすぐ止める可能性がありますので、 `int retry = 0` 等で初期化してください。

大変失礼しました。
テストプログラムを作成する際に初期化を忘れました。
本プログラムでは、初期化されています。

以上、よろしくお願いいたします。

at_dominique.m…

2025年2月27日 12時00分

マルティネです。

ご確認ありがとうございます。

> > 例えば、stty で parenb を設定して parity bit を有効にしますが、対向機で parity bit の設定が合わないと送信された文字が認識されず read で受け取れません。
>
> こちらでも、stty設定を色々と変更して確認していますが、不具合を解消できません。
> 因みに、相手機とWindows上でのシリアルデバッグツールでシリアル設定を合わせて通信すると、正しく送受信できます。
> 同様に本プログラムが稼働しているArmadilloとWindows上のシリアルデバックツールで送受信すると、やはり受信エラーになります。

まとめると以下の組み合わせを試していただきましたね:

* 相手機 -> Armadillo: NG
* Windows PC -> Armadillo: NG
* 相手機 -> Windows PC: OK
* Armadillo -> 相手機/Windows PC: OK?

> 以上のことから、こちらも、stty設定の問題と考えているのですが、通信速度、パリティあり、奇数パリティ、ストップビット1つ、データサイズ8bit を合わせても、受信できません。

このシリアルで以前(他の機器と)受信したことがないとすれば、一旦今の設定から離れて、PC/Armadillo と Armadillo を動くはずの設定で確認した方がいいかもしれません。
(マニュアルに記載されているデフォルトの設定でしたら、armadillo で受信できないはずがないですね:
https://manual.atmark-techno.com/armadillo-4x0/armadillo-400_series_sof… )

Armadillo 440 でのソフトウェアを確認したところソフトウェア的に常に有効になっているみたいなので、別の設置で受信できたらひとまずハードウェアの故障がないかを確認できますので、まずは「何かの動く状態」にたどり着いて設定を一つずつ変更して最終的に目的の設定に合わせることはできるはずです。

> 他のArmadilloとの通信は確認してみます。

お手数ですが、そちらの確認もお願いします。

ちなみに、parity のエラー等の場合に /proc/tty/driver/ttymxc に何かのカウンターが表示されると思いますので、その点もご確認いただければと思います
(すみません Armadillo 440 で実際にまだ試してませんので、linux バージョンの変更で違うファイルになってるかもしれません)

また、少し時間をいただきますが、来週までにできなかったら月曜日に Armadillo 440 を準備して PC と試してみます。

よろしくお願いします

横から口を挟んで済みません。齊藤と申します。

> [シリアル設定確認]
> stty -F /dev/ttymxc1 -a
> speed 57600 baud; rows 0; columns 0;
> intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ; eol2 = ; start = ^Q; stop = ^S; susp = ^Z;
> rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
> -parenb parodd cs8 hupcl -cstopb cread clocal crtscts
> -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel
> opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
> isig icanon iexten -echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

これ、stty raw(-icanon -opost など)しておく必要はありませんか?time 0 と設定しても -icanonにしないと効きません。