RS232C x4 Capeの作成
BeagleBone Black上のCPUには6個のUARTが載っていて、そのうちの1つはシリアルコンソール用、それ以外の5本が拡張IOで使用可能になっている。
(厳密には、3番ポートがTxのみなので4.5本だが、、、)
これを使って、MOXAの4ポートシリアルコンバータの代わりにならないかということで作り始めた。+αとして単体でEPICS動作が可能なので、IOCの分散にもつながる。
Hardware
BeagleBone Black側はUART1,2,4,5を使うことにし、CTS/RTSはつながない。
EEPROMはつけておくことにする。
HDMI OFF
今回のHWでは、UART5とHDMI出力が被ってしまう。今回は画面が必要ないので、HDMI出力を停止させることにした。
HDMI出力の確認は、
root@beaglebone:/media/card# cat /sys/devices/bone_capemgr.8/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
で行う。
5にHDMIのモジュールが読み込まれているのがわかる。"P-O-L"の"L"が"Load"ということらしく、これが消えればいいらしい。
設定は、ブートローダーで行うので、boot領域をmountして、uEnv.txtを書き換える。
root@beaglebone:~/cape/UARTx4# df Filesystem 1K-blocks Used Available Use% Mounted on rootfs 3369444 1641652 1553304 52% / /dev/root 3369444 1641652 1553304 52% / devtmpfs 255228 0 255228 0% /dev tmpfs 255356 0 255356 0% /dev/shm tmpfs 255356 232 255124 1% /run tmpfs 255356 0 255356 0% /sys/fs/cgroup tmpfs 255356 232 255124 1% /etc/machine-id tmpfs 255356 0 255356 0% /tmp /dev/mmcblk0p1 72102 59252 12850 83% /media/card root@beaglebone:~/cape/UARTx4# cd /media/card/ root@beaglebone:/media/card# ls App Drivers LICENSE.txt README.md autorun.inf uEnv.txt Docs ID.txt MLO START.htm u-boot.img root@beaglebone:/media/card# vi uEnv.txt optargs=quiet ↓ optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN
設定を書き換えたらreboot。
reboot後は、画面に何もでなくなるので注意すること。
sshで他のマシンからログインして、状態を確認。
root@beaglebone:/media/card# cat /sys/devices/bone_capemgr.8/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
この状態になっていればOK。
Cape回路図
今回の回路は、各uartにRS232CのレベルコンバータとEEPROMを載せるだけの簡単なものにする。
firmware
firmwareのひな形は/lib/firmwareにあったので、それを編集して作成。
/* * Copyright (C) 2013 Tetsuya Michikawa <hig-mchi@post.kek.jp> * * BeagleBone Black UART 1,2,4,5 used RS232c cape */ /dts-v1/; /plugin/; / { compatible = "ti,beaglebone", "ti,beaglebone-black"; /* identification */ part-number = "cape-bone-uartx4"; version = "00A0"; /* state the resources this cape uses */ exclusive-use = /* the pin header uses */ "P9.24", /* uart1_txd */ "P9.26", /* uart1_rxd */ "P9.21", /* uart2_txd */ "P9.22", /* uart2_rxd */ "P9.13", /* uart4_txd */ "P9.11", /* uart4_rxd */ "P8.37", /* uart5_txd */ "P8.38", /* uart5_rxd */ /* the hardware ip uses */ "uart1", "uart2", "uart4", "uart5"; fragment@0 { target = <&am33xx_pinmux>; __overlay__ { bb_uart1_pins: pinmux_bb_uart1_pins { pinctrl-single,pins = < 0x180 0x20 /* P9.26 uart1_rxd.uart1_rxd INPUT */ 0x184 0x20 /* P9.24 uart1_txd.uart1_txd OUTPUT */ >; }; bb_uart2_pins: pinmux_bb_uart2_pins { pinctrl-single,pins = < 0x150 0x21 /* P9.22 spi0_sclk.uart2_rxd | MODE1 */ 0x154 0x01 /* P9.21 spi0_d0.uart2_txd | MODE1 */ >; }; bb_uart4_pins: pinmux_bb_uart4_pins { pinctrl-single,pins = < 0x070 0x26 /* P9.11 gpmc_wait0.uart4_rxd | MODE6 */ 0x074 0x06 /* P9.13 gpmc_wpn.uart4_txd | MODE6 */ >; }; bb_uart5_pins: pinmux_bb_uart5_pins { pinctrl-single,pins = < /* the uart pins */ 0x0C4 0x24 /* P8.38 lcd_data9.uart5_rxd | MODE4 */ 0x0C0 0x04 /* P8.37 lcd_data8.uart5_txd | MODE4 */ >; }; }; }; fragment@1 { target = <&uart2>; /* really uart1 */ __overlay__ { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&bb_uart1_pins>; }; }; fragment@2 { target = <&uart3>; /* really uart2 */ __overlay__ { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&bb_uart2_pins>; }; }; fragment@3 { target = <&uart5>; /* really uart4 */ __overlay__ { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&bb_uart4_pins>; }; }; fragment@4 { target = <&uart6>; /* really uart5 */ __overlay__ { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&bb_uart5_pins>; }; }; };
このファイルをコンパイルして、firmwareを作成。
これを/lib/firmwareにコピーして、ロードさせてみる。
root@beaglebone:~/cape/UARTx4# dtc -O dtb -o cape-bone-uartx4-00A0.dtbo -b 0 -@ cape-bone-uartx4-00A0.dts root@beaglebone:~/cape/UARTx4# cp cape-bone-uartx4-00A0.dtbo /lib/firmware root@beaglebone:~/cape/UARTx4# cd /lib/firmware root@beaglebone:/lib/firmware# echo cape-bone-uartx4 > /sys/devices/bone_capemgr.8/slots
ここで何もでなければOKだけど、ロードできないとエラーが出る。エラーの内容はdmesgで出力されるので、それを確認してエラーを修正後、再度実行。
root@beaglebone:/lib/firmware# cat /sys/devices/bone_capemgr.8/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-L Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 6: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-bone-uartx4
EEPROM
Capeに載せるEEPROMを作成する。
EEPROMへのアクセス
その前に、I2C2でEEPROMが認識されるかをチェックする。今回はEEPROMにATMEL AT24C256Bを使った。BBBはIO電圧が3.3Vなので、そこにつなぐICも3.3V対応のものを使う必要があるので注意。
画像の実験回路をブレッドボード等で作成して、初めはSW A0,A1,A2のプルアップ抵抗を接続せずにGNDに接続してみる。
回路を作成後、BBBのI2C2 SCL,SDAに接続し、i2cdetectでバススキャンしてみる。
root@beaglebone:~# i2cdetect -r 1 WARNING! This program can confuse your I2C bus, cause data loss and worse! I will probe file /dev/i2c-1 using read byte commands. I will probe address range 0x03-0x77. Continue? [Y/n] y 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: 50 -- -- -- UU UU UU UU -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
回路が正しければ、上記のような表示になるはず。ならなければ、どこか回路が間違っているので修正する。
次にEEPROMへの読み書きができるかを実験。
まず、EEPROMにアクセスするためのデバイスインターフェイス(?といえばいいのかな)を作成。
root@beaglebone:~# echo 24c256 0x50 > /sys/bus/i2c/devices/i2c-1/new_device root@beaglebone:~# ls /sys/bus/i2c/devices 0-0024 0-0050 1-0050 1-0054 1-0055 1-0056 1-0057 i2c-0 i2c-1 root@beaglebone:~# dmesg : [ 5404.713106] at24 1-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 5404.713545] i2c i2c-1: new_device: Instantiated device 24c256 at 0x50
1-0050がEEPROMにアクセスするためのインターフェイスになる。
root@beaglebone:~ # cd /sys/bus/i2c/devices/1-0050 root@beaglebone:/sys/bus/i2c/devices/1-0050# ls -la total 0 drwxr-xr-x 3 root root 0 Oct 22 02:19 . drwxr-xr-x 9 root root 0 Jan 1 2000 .. lrwxrwxrwx 1 root root 0 Oct 22 02:19 driver -> ../../../../../bus/i2c/drivers/at24 -rw------- 1 root root 32768 Oct 22 02:22 eeprom -r--r--r-- 1 root root 4096 Oct 22 02:22 modalias -r--r--r-- 1 root root 4096 Oct 22 02:22 name drwxr-xr-x 2 root root 0 Oct 22 02:22 power lrwxrwxrwx 1 root root 0 Oct 22 02:19 subsystem -> ../../../../../bus/i2c -rw-r--r-- 1 root root 4096 Oct 22 02:19 uevent root@beaglebone:/sys/bus/i2c/devices/1-0050#
EEPROMへのデータの書き込み、読み込みはeepromファイルにアクセスすることで行われる。
root@beaglebone:/sys/bus/i2c/devices/1-0050# echo "hoge" > eeprom root@beaglebone:/sys/bus/i2c/devices/1-0050# cat eeprom | hexdump -C 00000000 68 6F 67 65 ff ff ff ff ff ff ff ff ff ff ff ff |hoge | *
今回の実験ではi2cアドレス0x50を使用して実験しているが、実際にcapeとして使用する場合には、i2cアドレス0x54~0x57の範囲内にしないとcapeとして認識されないので注意。
EEPROMの作成
EEPROMのイメージデータは、firmwareファイルから生成することはできないので、別の定義ファイルから作成するしかないみたい。
EEPROMのフォーマットは規定されているが、それを作る方法が確立しているわけではないみたい。
色々なページでも、自作のプログラムでひな形を作ったりしている。一応、正式な方法としてはJSON形式のファイルを作成して、それをコンバートして作る方法が紹介されている。
変換プログラム自体はjavascriptで書かれているが、OSにはインストールされていないのでどこかから持ってくる必要がある。今回はここから、eeprom.jsとbone.jsをとってきた。
このスクリプトを使って変換する。ちなみに、EEPROMの定義ファイルは、cape-bone-uartx4-00A0.jsonとした。
root@beaglebone:~/cape/UARTx4/eeprom# node ./eeprom.js -w cape-bone-uartx4-00A0.json
JSON形式の設定ファイルの内容は以下の通り。
注意点として、partNumberとversionはfirmwareの設定内容(ファイル名?)と同じにしておかないといけない。これをキーにして対応するfirmwareを検索するらしい。
{ "uartx4.eeprom": { "type": "cape", "header": "aa5533ee", "formatRev": "A0", "boardName": "RS232C x4 Cape", "version": "00A0", "manufacturer": "KEK cERL CTRL", "partNumber": "cape-bone-uartx4", "numPins": 8, "serialNumber": "0000-0000-0001", "currentVDD_3V3EXP": 250, "currentVDD_5V": 250, "currentSYS_5V": 1000, "DCSupplied": 1000, "mux": { "P9_26": { "used": "used", "direction": "in", "pullup": "disabled", "slew": "fast", "rx": "enabled", "mode": 0, "function": "uart1_rxd" }, "P9_24": { "used": "used", "direction": "out", "pullup": "disabled", "slew": "fast", "rx": "disabled", "mode": 0, "function": "uart1_txd" }, "P9_22": { "used": "used", "direction": "in", "pullup": "disabled", "slew": "fast", "rx": "enabled", "mode": 1, "function": "uart2_rxd" }, "P9_21": { "used": "used", "direction": "out", "pullup": "disabled", "slew": "fast", "rx": "disabled", "mode": 1, "function": "uart2_txd" }, "P9_11": { "used": "used", "direction": "in", "pullup": "disabled", "slew": "fast", "rx": "enabled", "mode": 6, "function": "uart4_rxd" }, "P9_13": { "used": "used", "direction": "out", "pullup": "disabled", "slew": "fast", "rx": "disabled", "mode": 6, "function": "uart4_txd" }, "P8_38": { "used": "used", "direction": "in", "pullup": "disabled", "slew": "fast", "rx": "enabled", "mode": 4, "function": "uart5_rxd" }, "P8_37": { "used": "used", "direction": "out", "pullup": "disabled", "slew": "fast", "rx": "disabled", "mode": 4, "function": "uart5_txd" } } } }
変換したEEPROMイメージをダンプするとこんな感じ。
root@beaglebone:~/cape/UARTx4/eeprom# hexdump -C uartx4.eeprom 00000000 aa 55 33 ee 41 30 52 53 32 33 32 43 20 78 34 20 |.U3.A0RS232C x4 | 00000010 43 61 70 65 00 00 00 00 00 00 00 00 00 00 00 00 |Cape............| 00000020 00 00 00 00 00 00 30 30 41 30 4b 45 4b 20 63 45 |......00A0KEK cE| 00000030 52 4c 20 43 54 52 4c 00 00 00 63 61 70 65 2d 62 |RL CTRL...cape-b| 00000040 6f 6e 65 2d 75 61 72 74 78 34 00 08 30 30 30 30 |one-uartx4..0000| 00000050 2d 30 30 30 30 2d 30 30 a0 29 c0 09 00 00 00 00 |-0000-00.)......| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 28 |...............(| 00000070 c0 08 00 00 00 00 00 00 00 00 00 00 a0 2e c0 0e |................| 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000000c0 00 00 c0 0c a0 2c 00 00 00 00 00 00 00 00 00 00 |.....,..........| 000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 fa 00 fa |................| 000000f0 03 e8 03 e8 |....| 000000f4
これをEEPROMに書き込んで、Capeを起動すれば、自動的に対応するfirmwareが読み込まれる。
EEPROMがI2C2の0x54に接続されている場合には、以下のコマンドで書き込みができる。
root@beaglebone:~/cape/UARTx4/eeprom# cat uartx4.eeprom > /sys/bus/i2c/devices/1-0054/eeprom
実機テスト
実際にCapeを試作して実装してみる。
root@beaglebone:~# cat /sys/devices/bone_capemgr.8/slots 0: 54:PF--- 1: 55:PF--- 2: 56:PF--- 3: 57:P---L RS232C x4 Cape,00A0,KEK cERL CTRL,cape-bone-uartx4 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
I2Cアドレスの設定によって、表示されるスロットは変わるが、0x57の位置に今回作成したcapeがロードされたことがわかる。
dmesgで詳細を確認。
[ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Initializing cgroup subsys cpu [ 0.000000] Linux version 3.8.13 (koen@rrMBP) (gcc version 4.7.3 20130205 (prerelease) (Linaro GCC 4.7-2013.02-01) ) #1 SMP Wed Aug 14 16:25:00 CEST 2013 [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=50c5387d [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache : [ 0.244885] loop: module loaded [ 0.245009] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 0.245089] at24 1-0054: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 0.245159] at24 1-0055: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 0.245228] at24 1-0056: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 0.245298] at24 1-0057: 32768 byte 24c256 EEPROM, writable, 1 bytes/write [ 0.252493] bone-capemgr bone_capemgr.8: Baseboard: 'A335BNLT,0A5C,2713BBBK6962' [ 0.252534] bone-capemgr bone_capemgr.8: compatible-baseboard=ti,beaglebone-black [ 0.252607] bone-capemgr bone_capemgr.8: Skipping disabled cape with part# BB-BONELT-HDMI [ 0.252690] bone-capemgr bone_capemgr.8: Skipping disabled cape with part# BB-BONELT-HDMIN [ 0.282744] bone-capemgr bone_capemgr.8: slot #0: No cape found [ 0.319851] bone-capemgr bone_capemgr.8: slot #1: No cape found [ 0.356959] bone-capemgr bone_capemgr.8: slot #2: No cape found [ 0.387222] bone-capemgr bone_capemgr.8: slot #3: 'RS232C x4 Cape,00A0,KEK cERL CTRL,cape-bone-uartx4' [ 0.387406] bone-capemgr bone_capemgr.8: slot #4: specific override [ 0.387447] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 4 [ 0.387475] bone-capemgr bone_capemgr.8: slot #4: 'Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G' [ 0.387608] bone-capemgr bone_capemgr.8: slot #5: specific override [ 0.387644] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 5 [ 0.387672] bone-capemgr bone_capemgr.8: slot #5: 'Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI' [ 0.387809] bone-capemgr bone_capemgr.8: slot #6: specific override [ 0.387845] bone-capemgr bone_capemgr.8: bone: Using override eeprom data at slot 6 [ 0.387873] bone-capemgr bone_capemgr.8: slot #6: 'Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN' [ 0.388152] bone-capemgr bone_capemgr.8: Skipping loading of disabled cape with part# BB-BONELT-HDMI [ 0.388222] bone-capemgr bone_capemgr.8: Skipping loading of disabled cape with part# BB-BONELT-HDMIN [ 0.388534] bone-capemgr bone_capemgr.8: initialized OK. : [ 4.800832] bone-capemgr bone_capemgr.8: slot #3: dtbo 'cape-bone-uartx4-00A0.dtbo' loaded; converting to live tree [ 4.801128] bone-capemgr bone_capemgr.8: slot #3: #5 overlays [ 4.804422] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89) is a OMAP UART1 [ 4.806330] 48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90) is a OMAP UART2 [ 4.809856] 481a8000.serial: ttyO4 at MMIO 0x481a8000 (irq = 61) is a OMAP UART4 [ 4.811270] 481aa000.serial: ttyO5 at MMIO 0x481aa000 (irq = 62) is a OMAP UART5 [ 4.811678] bone-capemgr bone_capemgr.8: slot #3: Applied #5 overlays. [ 4.811731] bone-capemgr bone_capemgr.8: slot #4: Requesting firmware 'cape-bone-2g-emmc1.dtbo' for board-name 'Bone-LT-eMMC-2G', version '00A0' [ 4.811751] bone-capemgr bone_capemgr.8: slot #4: dtbo 'cape-bone-2g-emmc1.dtbo' loaded; converting to live tree [ 4.812171] bone-capemgr bone_capemgr.8: slot #4: #2 overlays
UART1,2,4,5がそれぞれttyO1,ttyO2,ttyO4,ttyO5になっていることが確認できた。
実際に通信して確かめてみる。
RS232Cクロスケーブルをポート1と2につなぎ、シリアル通信プログラム minicom で実験。タミーナルを2つ立ち上げて、それぞれでminicomを実行する。
root@beaglebone:~# minicom -D /dev/ttyO1 -b 115200
root@beaglebone:~# minicom -D /dev/ttyO2 -b 115200
minicomが起動したら、片方のターミナル画面から適当な文字を入力すると、もう片方のターミナルに入力した文字が表示されれば成功。表示されないようなら、配線をチェックするか、違うRS232Cポートにケーブルをつないでいないかをチェックする。
ケース作成
ケースの作成は当初既製品を自分で加工することも考えたが、4つケースを作るとなると時間と労力がかかりすぎるので、今回はメーカーで既製品を追加工してもらうことにした。
色々と検討した結果、(株)タカチ電機工業のKC5-13-10GSをベースとすることにした。最初は穴加工だけにするつもりだったが、部品固定用スタッド(スペーサ)をつけても値段的には300円ぐらいの差しかないので、合わせて加工してもらった。
組み立て後はこうなった。
参照HP
NULLCape. How to Roll your own BeagleBone Capes (Part II) | Community Papermint Designs
Where are the serial ttyO1,2,3,4? - Google グループ
Cape Expansion Headers - Circuitco Wiki Support
Disabling the BeagleBone Black HDMI Cape Logic Supply Blog
Adventures in BeagleBone Cape EEPROMs | K.Keller's Blog
Attachments (4)
- BBBSerialCape.png (52.3 KB) - added by michkawa 11 years ago.
- BBBSerialCape_board.png (35.3 KB) - added by michkawa 11 years ago.
- kc5-13-10_bbb2.png (28.3 KB) - added by michkawa 10 years ago.
- serialx4.png (1.6 MB) - added by michkawa 10 years ago.
Download all attachments as: .zip