2020/03/01(日)XBee のプログラマブルモジュールとノーマルタイプの違い《お勧めは「ノーマルタイプ」!!》
2020/03/01 5:54
昨年からこの無線通信モジュールを使用するシステム開発に関わっています。
実際に関わってみると、何と言っても「これほど判りずらいモジュールはない!!」という印象が強いです。
日本語による情報が殆ど無い、説明書通りの挙動をしない、情報が古い、という現状も判りずらさを助長しています。
更に、名前の紛らわしさが判りずらさを更に助長しています。
XBee (「じぐびいぃ」と発音する模様)は、この無線モジュールの商標だが、ZigBee はXBee が採用している通信規格。発音が日本人に言わせると全く同じ。
更に XBee と書いて別の読み方をする日本メーカの小型乗用車なんかもあって、調べる際に結構な割合で検索結果に混同してきます。
そもそも、ノーマル版とPro版が先ず最初にあり、これは無線通信の電波の強さの違いのようです。
Pro 版の方が高出力で通信距離を稼げます。
要するに、「Pro版」はプログラマブルモジュールのことではなく、「高出力版」ということのようです。
次に、ノーマル版とプログラマブルモジュール版があります。
プログラマブルモジュールは、機能的にはMicrochip社のPIC16FシリーズとPIC18Fシリーズの中間的な機能を有するマイコンが内蔵され、こういうのに欲張りな当方は「値段が殆ど同じなら、プログラマブルモジュールを使う」という選択肢が自然と行くのですが、これは駄目です。全くお勧めできません。とても苦労する羽目になります。
先駆者諸氏のブログ等を拝見すると、当方と同じような思考で結果的に使用を断念してしまったり、間違って購入して苦労しているのを散見します。
両者はよくよく見ないと区別できないのもこの状況を助長しています。
ここで、「ノーマルタイプ」と「プログラマブルモジュール」を並べた様子です。
全く『違い』が判りませんね。実は、裏面を見ると辛うじて判ります:
型番の最後が
「003」になっているのが「プログラマブルモジュールなXBee」、
「004」になっているのが「ノーマルタイプの XBee」なのです。(赤枠で囲った部分)
こういうのは、表に大きな文字で型番を印刷するとか、色を変えるとかして区別できるようにするべきだと個人的には思います。
蛇足ですが、プログラマブルモジュールに内蔵しているマイコンは、Freescale社の MC9508QE32CFT という型番のマイコンのようです。
実は、XBee プログラマブルモジュール用のSDK(プログラム開発ツール)が無償提供されてはいるのですが、
全く使えないのです。どうもCコンパイラが吐き出す命令コードがおかしい。
サブルーチンの前後で引数が突然変わるんです。
何か回避できるトリックがあるのでしょうが、そういうのも見当たらず、一般人には使い物にならない。
これは想定外の大きな誤算でした。
どうりで XBee プログラマブルモジュールの応用事例が殆ど皆無なわけです。
メーカの方でもそういうのは判っていると思うのですが・・・ 現状は何も対策無しです。
なので、プログラマブルモジュールの XBee は、現状ではお勧めできないわけです。
2020/01/23(木)Raspberry Pi 3 Model B+ FreeBSD12.1 その他の情報
2020/01/23 5:14
・FreeBSD RaspBerry Pi 3 は FreeBSD/ARM 対応プロジェクトの一環で開発作業が続けられており、
位置づけは、Tire 2 となっています。
従って、Tire 1 サポート(i386、amd64 が該当)のみとなっている FreeBSD UPDATE は使えません。
・FreeBSD/ARM 対応プロジェクトは、Tire 1 に乗せる準備が進められている模様。
FreeBSD が組み込み機器用途で使用できる最初のプラットフォームになれるかも。
・FreeBSD における GPIO 制御は、gpioctl コマンドが使用できます。
Perl には、これと同じことを Perl スクリプトで行うための Device::BCM2835 なるモジュールや、
RPi::Pin、WiringPi::API などありますが、FreeBSD12.1 ではどれも使えません。
以下のような感じでピン情報を取得します(例):
$result = qx(gpioctl -l) ; chomp ($result) ; my @iostat = split("\n",$result) ; foreach my $getpin (@iostat) { $getpin =~ /\Apin\s(\d+):\s+(\d)/ ; next if ($pinnum ne $1) ; $lvlstat = $2 ; last ; }# $pinnum に文字列でピン番号を与え、$lvlstat に 0か1 が入ります。
# 0 がL、1 がHです。
2020/01/23(木)Raspberry Pi 3 Model B+ に FreeBSD12.1 をインストール (3)
2020/01/23 4:53
.cshrc や .profile でお好みな環境をセットアップしますが、ここは個人の好みの部分なので、
説明省略。
筆者の環境では、基本的に Perl5 を使いたいので、
このあと、ports にてパッケージインストールを行います。
以下のような感じで root ユーザにて導入します:
# cd /usrportupgrade のインストールにて、依存するパッケージとして、ruby や Perl がインストールされます。
# mkdir ports
# portsnap fetch extract
# cd /usr/ports/editors/vim-console
# make install
# make clean
# cd /usr/ports/misc/lv
# make install
# make clean
# cd /usr/ports/ports-mgmt/portupgrade
# make install
# make clean
途中、青地画面で、インストールオプションの選択画面が何度か出るが、適当にデフォルト値に任せずに、必ず内容を確認して作業しましょう。
2020/01/23(木)Raspberry Pi 3 Model B+ に FreeBSD12.1 をインストール (2)
2020/01/23 4:39
/etc/rc.conf に最初に記述されている、イーサネット関連のデフォルト設定値は、
ifconfig_DEFAULT="DHCP"となっています。
この状態で起動すると、DHCPネゴシエーションで通知された参照用DNS設定ファイル /etc/resolv.conf が自動生成されています。
当然のことながら、LAN上にDHCPサーバが無い場合、このファイルは自動生成されません。
筆者の場合は以下のようになりました:
search deverop.basekernel.ne.jp#セキュリティ対策上、IPアドレスは伏せてあります。
nameserver xxx.xxx.xxx.xxx
nameserver yyy.yyy.yyy.yyy
見てのとおり、IPv4 で機能しています。
適宜変更が必要かもしれません。
先ずは、ユーザ名 freebsd の削除・変更と、root パスワードの変更。
初期値は、ユーザ名 freebsd パスワード freebsd でログインでき、root のパスワードは、root なので、変更すべきです。(メンテナンスを簡単に始められるようにこうなっている)
先ず、ユーザ名 freebsd を削除して、新たに任意のユーザ名を追加、root のパスワードは変更しましょう。
更に、/etc/group の wheel 行に、root ユーザになれるように 新たに追加した任意のユーザ名を追加し、ユーザ名 freebsd は削除することを忘れないように。
次に /etc/rc.conf の変更。以下のようにします:
hostname="bypass_ctl"ホスト名、IPアドレスやネットマスク、デフォルトルータあたりの設定は、使用中のネットワークポリシーに合わせます。
defaultrouter="172.16.15.1"
ifconfig_ue0="inet 172.16.15.188 netmask 0xffffff00"
ntpd_enable="YES"
ntpd_sync_on_start="YES"
inetd_enable="YES"
sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"
growfs_enable="YES"
keymap="jp.kbd"
/etc/ntp.conf はデフォルト値でも大丈夫ですが、ネットワーク内に公開NTPサーバがある場合や、指定されている場合は、そのサーバを設定します。
基本インストールの最後に、タイムゾーンの設定です。
日本時間の指定は、以下のコマンドを root ユーザにて実行します:
# tzsetup /usr/share/zoneinfo/Asia/Tokyo一度設定すれば、次回の起動以後もこのタイムゾーンで動作します。
設定の最後に
# shutdown -r nowで、再起動します。
2019/04/17(水)新元号の対応
2019/04/17 5:39
#限りなくゼロに近いと思っているが。。
ま、こんな感じにしました。西暦2019年は、4/30,5/2 も祝日法に基づくと、
西暦2019年限定で休日になります。
ちなみに今年と来年は、オリンピックもあり、特例の祝日が結構あるんです。
2019/03/01(金)ディジタル証明書の形式 pem と der
2019/03/01 18:15
※現在、実運用で使っていませんが念のため一部端折っています。
-----BEGIN CERTIFICATE----- MIIC4TCCAkqgAwIBAgIBADANBgkqhkiG9w0BAQUFADB4MQswCQYDVQQGEwJKUDER MA8GA1UECBMISG9ra2FpZG8xGzAZBgNVBAoTEkJhc2UgS2VybmVsIENvIEx0ZDEg MB4GA1UECxMXTmV0d29yayBPcHJhdGlvbiBDZW50ZXIxFzAVBgNVBAMTDkJhc2Ug S2VybmVsIENBMB4XDTA4MDcxMzEzMTU0NVoXDTI4MDcxMzEzMTU0NVoweDELMAkG ・・・・一部省略・・・・ A1UEBhMCSlAxETAPBgNVBAgTCEhva2thaWRvMRswGQYDVQQKExJCYXNlIEtlcm5l +6EEruiOlNKYnViRTdjEoAPRYfgM+eqjnfbVOxB0wEV7w5GjcqbGe9ePrEUs1wYS ktnZC7H0p5H01z92udKE3BaCEACQ -----END CERTIFICATE-----これは、pem 形式と呼ばれるディジタル証明書で、通常はこの形式で管理します。
ところが、時々、 der 形式しか受け付けないディジタル証明書アプリケーションがあるのです。
今回、コントロールパネルのサーバ設定部分の一部が時代に合わなくなっていて、この部分の改良を施しているところで、その一環でサーバ証明書をある程度自力管理できるようにしているのですが、その過程でディジタル証明書の内容を解析する Perl モジュールに Crypt::X509 という便利なものがあってそれを使おうとしたら、このモジュールが der 形式しか対応していないのです。
もっと便利そうなものに Crypt::OpenSSL::X509 というのがあるが、今のところ、OpenSSL 1.x 系への対応があまり芳しくなく、避けざるを得ない状況。
der 形式はバイナリファイルなので扱いにくいのです。ただ、具体的中身まではよく知りません。
調べると、 pem 形式ファイルの -----BEGIN CERTIFICATE----- 行と、-----END CERTIFICATE----- 行を取っ払った残りの部分を、Base64 デコードしてあげればいいだけであることが判りました。
つまり、pem 形式は、der 形式で生成したディジタル証明書のデータ構造を Base64 エンコードして、-----BEGIN CERTIFICATE----- 行と、-----END CERTIFICATE----- 行を付け足しただけなのです。
ここまで判れば、ディジタル証明書の内容確認は、Perl でやる場合は以下の要領で出来ます:
#!/usr/local/bin/perl use MIME::Base64 ; # Base64ライブラリ使用宣言 use Crypt::X509 ; # 証明書内容参照ライブラリ使用宣言 $csr_pem = "" ; $status = open (CSRPEM,"hoge.pem") ; if ($status) { local $/ = undef ; $csr_pem = <CSRPEM> ; close(CSRPEM) ; } $csr_pem =~ /\-\-\-\-\-BEGIN\s+CERTIFICATE\-\-\-\-\-(.+)\-\-\-\-\-END\s+CERTIFICATE\-\-\-\-\-/s ; $x509_tmp = $1 ; %outstr = {} ; $x509_decode = Crypt::X509->new(cert => decode_base64($x509_tmp)) ; @nb = localtime($x509_decode->not_before) ; @na = localtime($x509_decode->not_after) ; @jw = ('日','月','火','水','木','金','土') ; $outstr{'not_before'} = sprintf("%d/%02d/%02d(%s) %02d:%02d:%02d",$nb[5] + 1900,$nb[4] + 1,$nb[3],$jw[$nb[6]],$nb[2],$nb[1],$nb[0]) ; $outstr{'not_after'} = sprintf("%d/%02d/%02d(%s) %02d:%02d:%02d",$na[5] + 1900,$na[4] + 1,$na[3],$jw[$na[6]],$na[2],$na[1],$na[0]) ; $outstr{'subj_country'} = $x509_decode->subject_country ; $outstr{'subj_state'} = $x509_decode->subject_state ; $outstr{'subj_local'} = $x509_decode->subject_locality ; $outstr{'subj_org'} = $x509_decode->subject_org ; $outstr{'subj_ou'} = $x509_decode->subject_ou ; $outstr{'subj_cn'} = $x509_decode->subject_cn ; $outstr{'issuer_cn'} = $x509_decode->issuer_cn ; $serial16 = sprintf("%X",$x509_decode->serial) ; $serial16 = '0' . $serial16 if (length($serial16) % 2) ; 1 while $serial16 =~ s/^([\da-fA-F]+)([\da-fA-F][\da-fA-F])/$1\:$2/ ; $outstr{'issuer_serial'} = $serial16 ; $outstr{'issuer_country'} = $x509_decode->issuer_country ; $outstr{'issuer_state'} = $x509_decode->issuer_state ; $outstr{'issuer_local'} = $x509_decode->issuer_locality ; $outstr{'issuer_org'} = $x509_decode->issuer_org ; $outstr{'sigalgo'} = $x509_decode->sig_algorithm ;上記サンプルにて、連想配列 %outstr に表示可能な文字列にて解析内容が入ります。
参考:https://metacpan.org/pod/Crypt::X509
2019/02/13(水)perl にて IPv4 と IPv6 のデュアルスタックサーバを作る
2019/02/13 3:13
ちまたにはこれを、IO::Socket::IP に変えるだけで IPv4/IPv6 デュアルスタックが実現するかのような話が広く知られているようだが、実際はどうも違う模様。。
今まで IPv4 で動作していたこのコード:
#!/usr/local/bin/perl # use utf8 ; binmode(STDOUT, ":utf8") ; use IO::Socket::INET ; # ソケットインタフェース使用宣言 $comm_queue = 5 ; # コネクション待ち受けキューの数 $port = 9999 ; # port no. ### 通信ソケット生成 # ソケットオープン $reqsock = IO::Socket::INET->new (LocalPort => $port, Listen => $comm_queue, Proto => 'tcp', Reuse => 1, ) ; if (not $reqsock) { err_trap("通信ソケットが作成できません。",$!) ; exit ; } ### サーバメインルーチン for (;;) { $sock = $reqsock->accept() ; if (not $sock) { err_trap("クライアントの要求受け付けに失敗しました。(accept error)",$!) ; exit ; } if ($child = fork()) { # 親プロセスの実行コード $sock->close() ; waitpid($child,0) ; next ; # 次のコネクション要求を待つ } elsif (defined($child)) { # 子プロセスの実行コード(メインルーチン) $reqsock->close() ; select($sock) ; $| = 1; # 常に flash するようにする select(STDOUT) ; binmode $sock ,':encoding(UTF-8)' ; 以下、サーバの処理プログラム・・・・ } }IO::Socket:INET の部分を、IO::Socket::IP に書き換えても、IPv6 しか受け付けない状態になります。
もしかしたら、IPv4射影アドレスを使えばいいのかもしれないですが、現状環境には全く合わない。
試行錯誤の結果、以下で動作する模様:
#!/usr/local/bin/perl # use utf8 ; binmode(STDOUT, ":utf8") ; use IO::Socket::INET ; # IPv4 Socket インタフェースライブラリ使用宣言 use IO::Socket::INET6 ; # IPv6 Socket インタフェースライブラリ使用宣言 use IO::Select ; $comm_queue = 5 ; # コネクション待ち受けキューの数 $port = 9999 ; # port no. ### 通信ソケット生成 $select = IO::Select->new ; # ソケットオープン[IPv6] $psock6 = IO::Socket::INET6->new (LocalPort => $port, Listen => $comm_queue, Type => SOCK_STREAM, Reuse => 1, Proto => "tcp" ) ; if (not $psock6) { err_trap("通信ソケットが作成できません。[IPv6]",$!) ; exit ; } else { $select->add($psock6) ; } # ソケットオープン[IPv4] $psock4 = IO::Socket::INET->new (LocalPort => $port, Listen => $comm_queue, Type => SOCK_STREAM, Reuse => 1, Proto => "tcp" ) ; if (not $psock4) { err_trap("通信ソケットが作成できません。[IPv4]",$!) ; exit ; } else { $select->add($psock4) ; } ### サーバメインルーチン for (;;) { while (my @ready = $select->can_read) { foreach my $reqsock (@ready) { $sock = $reqsock->accept() ; if (not $sock) { err_trap("クライアントの要求受け付けに失敗しました。(accept error)",$!) ; exit ; } if ($child = fork()) { # 親プロセスの実行コード $sock->close() ; waitpid($child,0) ; next ; # 次のコネクション要求を待つ } elsif (defined($child)) { # 子プロセスの実行コード(メインルーチン) select($sock) ; $| = 1; # 常に flash するようにする select(STDOUT) ; binmode $sock ,':encoding(UTF-8)' ; 以下、サーバの処理プログラム・・・・ } } } }参考になったのは、これ → How best to support IPv4/v6 in Perl server
2019/01/25(金)FreeBSD 12.0 カーネルにバグか
2019/01/25 5:30
ログメッセージにこんな感じで現れます:
Jan 25 04:15:46 uranus kernel: Fatal trap 12: page fault while in kernel mode Jan 25 04:15:46 uranus kernel: cpuid = 1; apic id = 01 Jan 25 04:15:46 uranus kernel: fault virtual address = 0xd8 Jan 25 04:15:46 uranus kernel: fault code = supervisor read data, page not present Jan 25 04:15:46 uranus kernel: instruction pointer = 0x20:0xffffffff8091527d Jan 25 04:15:46 uranus kernel: stack pointer = 0x28:0xfffffe00185b9560 Jan 25 04:15:46 uranus kernel: frame pointer = 0x28:0xfffffe00185b96b0 Jan 25 04:15:46 uranus kernel: code segment = base 0x0, limit 0xfffff, type 0x1b Jan 25 04:15:46 uranus kernel: = DPL 0, pres 1, long 1, def32 0, gran 1 Jan 25 04:15:46 uranus kernel: processor eflags = interrupt enabled, resume, IOPL = 0 Jan 25 04:15:46 uranus kernel: current process = 0 (if_io_tqg_1) Jan 25 04:15:46 uranus kernel: trap number = 12 Jan 25 04:15:46 uranus kernel: panic: page fault Jan 25 04:15:46 uranus kernel: cpuid = 1 Jan 25 04:15:46 uranus kernel: time = 1548357259 Jan 25 04:15:46 uranus kernel: KDB: stack backtrace: Jan 25 04:15:46 uranus kernel: #0 0xffffffff8077a8c7 at kdb_backtrace+0x67 Jan 25 04:15:46 uranus kernel: #1 0xffffffff8072e4b3 at vpanic+0x1a3 Jan 25 04:15:46 uranus kernel: #2 0xffffffff8072e303 at panic+0x43 Jan 25 04:15:46 uranus kernel: #3 0xffffffff80a6496f at trap_fatal+0x35f Jan 25 04:15:46 uranus kernel: #4 0xffffffff80a649c9 at trap_pfault+0x49 Jan 25 04:15:46 uranus kernel: #5 0xffffffff80a63fee at trap+0x29e Jan 25 04:15:46 uranus kernel: #6 0xffffffff80a3f825 at calltrap+0x8 Jan 25 04:15:46 uranus kernel: #7 0xffffffff808feb43 at tcp_input+0x1553 Jan 25 04:15:46 uranus kernel: #8 0xffffffff80876a55 at ip_input+0x145 Jan 25 04:15:46 uranus kernel: #9 0xffffffff8084f496 at netisr_dispatch_src+0xd6 Jan 25 04:15:46 uranus kernel: #10 0xffffffff80833d83 at ether_demux+0x163 Jan 25 04:15:46 uranus kernel: #11 0xffffffff80834ee6 at ether_nh_input+0x346 Jan 25 04:15:46 uranus kernel: #12 0xffffffff8084f496 at netisr_dispatch_src+0xd6 Jan 25 04:15:46 uranus kernel: #13 0xffffffff80834184 at ether_input+0x54 Jan 25 04:15:46 uranus kernel: #14 0xffffffff8084b646 at iflib_rxeof+0xa16 Jan 25 04:15:46 uranus kernel: #15 0xffffffff80846476 at _task_fn_rx+0x76 Jan 25 04:15:46 uranus kernel: #16 0xffffffff80779154 at gtaskqueue_run_locked+0x144 Jan 25 04:15:46 uranus kernel: #17 0xffffffff80778db8 at gtaskqueue_thread_loop+0x98 Jan 25 04:15:46 uranus kernel: Uptime: 4h16m16s Jan 25 04:15:46 uranus kernel: ---<<BOOT>>---どうも、これに似ている模様・・・:
Bug 234296 - FreeBSD 12.0-STABLE r342216 Fatal trap 12
IPv4,IPv6 を直接扱う部分のようです。どうやら解決をみたらしいのですが、まだリリースバージョンへの反映はなされていません。FreeBSD12 への更新は様子見したほうがよさそう。
〔2019/02/06(Wed)追記〕
昨日、リリースバージョン向けの対策版(FreeBSD 12.0-p3) が公開されたので、早速、本日未明から午前中にかけてFreeBSD 12 を稼働させている5台のサーバに対し、この不具合対策を行いました。
数日様子を見て、安定しているようであれば他のサーバも FreeBSD12 に更新予定。
〔2019/02/28(Thu)追記〕
どうも根本解決には至らない模様。頻度は減ったものの、5~6日経つと、勝手にリブートを繰り返します。
なので、FreeBSD12 を運用環境に持ってくるのはお勧めできません。当面 FreeBSD 11系でやり過ごすことにします。
〔2019/08/02(Fri)追記〕
Patch 7(FreeBSD12.0R-p7) あたりで安定した模様。引き続き、しばらく様子を見ます。
2018/06/04(月)IPv6の基礎(6) - 機器設定時に必要と思われる知識
2018/06/06 18:02
この後、IPv6を理解するために、2進数や16進数の知識が必要になってきます。
といっても、この知識がある方にとってこの項目は冗長なので、ここは読み飛ばしても差し支えありません。
今までさり気なく、IPv6アドレスを例示してきましたが、アルファベットが混じっていることにお気づきかと思います。
これは、「16進数」という情報処理系分野でごく普通に使われている数理方式で、普段我々が使う10進数の0~9の10個の数字に加えて、a ~ f のアルファベット6文字を加えて16進数としているのです。
つまり、16進数において、a ~ f は数字なのです。尚、a ~ f のアルファベットは、大文字でも構わないのですが、現在では、一般的に小文字の使用が強く推奨されています。
16進数が多用される理由は、コンピュータ(情報処理機器)との相性が良いからです。
10進数と2進数・16進数との相互変換を使う場面は、IPv6設定においては多くありません。(たまに必要になる場合があるが。。)
コンピュータは、2進数で内部処理の一切を行いますが、0と1の2つの数字しか使わない(だから2進数)ため、大きな数字を表現しようとすると、必然的に桁数が多くなります。
IPv6 アドレスを2進数で表現すると、128桁(128bit)にもなります。2進数4桁をひとまとめにすると、16進数1桁に上手く収まるので、4分の1になる上に、相互変換もやりやすくなります。
尚、一般的に「1バイト」といえば、16進数2桁,8ビットですが、そうでない場合もあるらしく、通信関係では代わりに「オクテット」がよく用いられます。
同じく、16進数2桁,8ビットが「1オクテット」です。
2018/04/10(火)IPv6の基礎(3) - 機器設定時に必要と思われる知識
2018/04/10 14:04
IPv6 アドレスは記述自体が長くなるため、一定の省略記述ルールが決められています。
しかしながら、必ずしも省略記述をする必要はありません。
むしろ、慣れないうちは敢えて省略記述をしない方がよいのです。
ですが、実際には先駆者によって多用されているので、ここでは省略記述ルールを紹介します。
「省略記述」は全て、数字の'0' (ゼロ) を省略するルールが定義されています。
先ず、「各フィールドの上位桁の'0'は省略可能」です。ただし、'0000' だけは全てを省略せずに'0'を記述します。
次に、「'0000' のフィールドが連続する場合は、該当部分を '::'(ダブルコロン)で省略可能」です。
但し、これが使えるのは1回だけです。
また、'::'(ダブルコロン)は、最も長く省略できる部分に適用すべき、と規定されました。
なので、厳密には上記例の3番目も×です。
2番目の 2001:db8:0:3::1 のみが正解となります。
更に、IPv6 表記でしか設定できない環境下で、IPv4を表記する場合の記述法も定義されています。
現在は、「IPv4 射影アドレス」の記法が
ただし、「IPv4 組み込みアドレス」もたまにみかけるので、知っておくとよいです。