hdiutil でできる。

hdiutil segment -o dest -segmentSize 500m  src.dmg

これで複数に分割される。分割されても、全部パートが揃っていれば、最初の一個を開けばそのままマウントできる。

2G以上あるファイルを FAT32 なフラッシュメモリに入れたいときとかで便利。

あるいは sparsebundle にしても入れれると思うけど、 sparsebundle は1つのディレクトリにだいぶたくさんエントリを作るので、しょぼいファイルシステムだとかなり重くなる。

  1. トップ
  2. tech
  3. 巨大な .dmg ファイルを複数に分割する

を作った。Togetter とかで「ああ、こういう話題に言及する人とは関わりあいたくないな」っていうことが時々あると思いますが、そういうときに使える便利なツールです。

余談

僕はホワイトリスト的な、つまり Twitter の場合プライベートアカウントだったりあるいは、そもそもフェイスブックだったり、というやりかたが好きではない。当然ホワイトリスト的なソーシャルネットワークのほうが安全ではあるが、新しい思いのよらなさ、というのがないのは詰らない。

しかし一方で、完全にオープンというのも全くよくない。表現をないがしろにするモヒカン的なゴミクズというのはそこらじゅうにいるし、一瞬でも隙を見せれば攻撃してくる人というのもいる。いろいろ面倒なことになるリスクだったり、思いもよらず傷つくリスクのほうが、思いもよらず良いことがある、というメリットを明かにうわまわる。

何らかの画期的な解決策、というのをいつも考えてはいるが、未だに完全にこれはというものは思いつかない。

そこで、ある程度現状で思いつく中で、なおかつ簡単に実行可能な方法として、関わりあいたくない人を先読みでブラックリストへ登録していく、というのがある。既存のサービスだと「ブロック」という言葉遣いなので、少し抵抗があるが、本来もっと活用すべき機能であると思っている。

  1. トップ
  2. tech
  3. Togetter でまとめられた Twitter ユーザーを一括でブロックするウェブサービス

ZeroPlus LAP-C 16064 をというロジックアナライザを買ってみた。Windows にしか対応してないけど、一応 Mac でも動かせそうな感じなのでやってみた。ただ、ロジックアナライザの値段はソフトウェアの値段感があって、できれば Windows で使いたくなる。

  • sigrok を使う
  • VM 上で Windows を起動する

という方法を試した。結論からすると sigrok を使うほうが楽だけど、機能的にはちゃんと Windows 使ったほうがよさそう。

sigrok を使う

OSS で対応しているソフトがあるので使ってみる

$ brew tap rene-dev/sigrok
$ brew install --HEAD libserialport
$ brew install --HEAD --with-libserialport libsigrok
$ brew install --HEAD libsigrokdecode
$ brew install --HEAD --with-libserialport sigrok-cli
$ brew install --HEAD pulseview

で頑張ると入る。libsigrokdecode がうまく入らなかったので いろいろ頑張った

pulseview

pulseview コマンドで Qt で作られた GUI が起動する。あんまり機能はないので難しくはない感じ…

  • [File] -> [Connect to Device...] で LAP-C を選択する。
  • ツールバーの設定アイコンで Volatage Threshold を適切に設定する
  • サンプリング数とサンプリングレートを設定する
  • Run を押すと出てくる

Decoder の追加はそのまんまなので難しくない Threshold 設定するのが忘れがちでハマりそう。

左のラベルをクリックするとトリガーの条件をかけられる。なぜか状態トリガーしかない。ハード的にはエッジトリガもあるはずなんだけどよくわからない。

captureratio ってのがなんなのかわかりにくいが、トリガーがかかるまでのサンプリングレートを決定する割合みたい。たぶん設定したサンプリングレートに captureratio をかけた値でトリガーがかかるまでサンプルされ、その後設定したサンプリングレートでサンプリングされる、のかな。

よくわからないけど、基本、トリガかけたい信号の周波数の2倍になるように captureratio を設定して、あとは細かいタイミングを見るために高速にサンプリングする、という使いかたなのかな。

sigrok-cli
sigrok-cli  --show --driver zeroplus-logic-cube
zeroplus-logic-cube - ZEROPLUS LAP-C(16064) with 16 probes: A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7
Supported configuration options:
    samplerate - supported samplerates:
      100 Hz
      500 Hz
      1 kHz
      5 kHz
      25 kHz
      50 kHz
      100 kHz
      200 kHz
      400 kHz
      800 kHz
      1 MHz
      10 MHz
      25 MHz
      50 MHz
      80 MHz
      100 MHz
    captureratio
    voltage_threshold
    Maximum number of samples: 65536

ここに出てくるサンプリングレート以外を設定するとセグフォして死ぬので注意

 sigrok-cli --driver zeroplus-logic-cube --probes A0=SCL,A1=SDA --output-format bits --samples 1k --config samplerate=25K 

で適当に表示されるはずなんだけど、なぜか手元のだと 4bit ごとにビットが立つみたいな挙動になってしまう…

あと sigrok-cli だとvoltage_threshold は設定できない (パースできない)。エラーもでないので罠。たぶん sigrok-cli あんまり使ってる人いない。

VirtualBox 上の Windows を使う

Mac、VirtualBox 上の Win XP で動かす

接続からドライバインストールまで

VirtualBox は USB extension を入れる必要がある。

ゲスト Windows が起動したら、VirtualBox のメニューの Devices -> USB Devices -> LAP-C〜 を選ぶ (つまり Windows 側へ接続する)

Windows 側では特に何も起きていないように見えるが、デバイスマネージャを見ると不明なデバイスが1つ見える。

そのデバイスのプロパティを開き、ドライバの再インストールボタンを押す。

  • (Windows Update に)「いいえ、今回は接続しません」を選択
  • 「一覧または特定の場所からインストールする」を選択
  • 「次の場所で最適のドライバを検索する」を選択
    • リムーバブルメディアは検索しない
    • 「 次の場所を含める」に C:\Program Files\PC-Based Instrument\ZEROPLUS\DRIVER を入れる
  • 次へをやると1段階進む
  • 今度は再び自動的にドライバのインストールウィザードが開くので、同じように進める
  • ドライバの選択では一番新しそうなのを選ぶ

これで起動はするようになる。

使いかた (I2C)

A0 を SCL, A1 を SDA にする場合 (当然これらと GND を結線しておく)

  • [Bus/Signal] → [Channels Setup]
  • [Delete All] して全部消す
  • [Add Bus/Signal] を SCL, SDA 及びバスのデータ表示用に3回押す
  • SCL 用には A0 を選択
  • SDA 用には A1 を選択
  • I2C 用には A0, A1 をどっちも選択
  • [OK] で閉じる

[Tool] -> [Bus Property...] をクリックするとアナイラザを選択できるはずだが、エラって死ぬ……… ので終了。うまくいく方法はわからず。

ZeroPlus に問いあわせてみたら、これは V3.12.02 のバグらしい。Channels Setup から BUS を作ってはダメみたい。

V3.12.02 でうまくいく方法は以下

  • [Bus/Signal] → [Channels Setup]
  • [Restore Default] して元に戻す
  • [OK] で閉じる
  • メイン画面の左側のプローブ一覧から A1, A0 を Shift か Ctrl を押しながら複数選択して、右クリックから [Group into Bus] をする。
  • [Tool] -> [Bus Property...] で開く (開ける)
  • 適当に設定する

あらかじめ対応する DLL を入れる必要がある。http://www.zeroplus.com.tw/logic-analyzer_en/products.php?pdn=10&pdnex=list で、とりあえず Generic Free Protocols を入れたらいい

  • シリアルが必要なアナライザの場合入れるコードは http://www.zeroplus.com.tw/ に登録して出てきたコード
  • 入れる場所は設定画面

で、適当にセットしたらいける。



  1. トップ
  2. tech
  3. Mac OS Xで ZeroPlus LAP-C


ピンヘッダのレイアウトツールに 幅狭の DIP IC のラベルを作る機能を足した。印刷して貼るだけで配線ミスが減らせるので便利

特に DIP IC の場合、文字を入れるスペースが殆どないので、自分に必要な要素だけ厳選して作る必要があって、簡単に別バージョンを作れたほうがいいと思う。ブラウザ上でやって実寸 PDF すぐ印刷できるのはかなり便利だと思う。

  1. トップ
  2. tech
  3. IC のピン配置ラベルを作る

Path::Class と Path::Tiny はほぼ同じことができるモジュールで、どっちを使っても特に変わりはないんですが「やっぱこっち〜」って感じで変えるとハマるような差異があり、今回ハマりましたのでご紹介します。

Path::Class->tempdir, Path::Tiny->tempdir

いずれのモジュールにも、tempdir というメソッドがあり、これはいずれも全く同じ引数をとり、File::Temp を使ってテンポラリディレクトリを掘ってパスオブジェクトを返すだけのメソッドです。

しかし内部で使っている File::Temp のメソッドが少々違うため、CLEANUP まわりの挙動が以下のように異ります。

  • Path::Class は File::Temp::tempdir() を使っている
    • CLEANUP => 0 がデフォルト (デフォルトで削除されない)
    • CLEANUP => 1 を指定した場合 Perl プロセス終了時にファイルが削除される
  • Path::Tiny は File::Temp->newdir() を使っている
    • CLEANUP => 1 がデフォルト (デフォルトで削除される)
    • 返ってきたオブジェクトが DESTROY されるときにファイルが削除される

File::Temp の挙動

  • File::Temp::tempdir() は文字列を返す
  • File::Temp->newdir() はオブジェクトを返す
    • 内部的には File::Temp::tempdir() を呼んでる
    • DESTROY が設定されている

ハマる例

普通ハマらないんですが、アホなことしてるとハマります。

  • Path::Class->tempdir を使っていて、Path::Tiny に変えた場合、その後の処理でファイルが存在していない場合がある
  • Path::Tiny->tempdir を使っていて、Path::Class に変えた場合、ファイルが削除されない場合がある
  1. トップ
  2. tech
  3. File::Temp, Path::Class, Path::Tiny

印刷してピンヘッダにハメれば、どれがどのピンだかわかりやすくなるというツールを作った。PDF (A4) を出力するので、あとは印刷してカッターで切りとれば 100mil のピンヘッダにぴったりあう。

一行目の # からはじまる行がタイトルになり、あとは適当にそれっぽくピン番号と名前のペアを書いていく。名前の語尾に # をつけると反転する。

ほんとはフォントも変えれるようにしたかったんだけど、ブラウザ上で任意のフォントを確実に指定する方法がなくてあきらめた。

作るまで

いろいろな方法があるが、結局 PDF を JS で生成している。jsPDF というライブラリをつかっているので比較的楽に書けた。

他に検討した方法は以下の通り

HTML/CSS

できるならこれが一番良い方法だと思ったが、いまいちクロスブラウザでうまくいくか微妙なのでやめた。table を印刷しようとするとプリントするときだけ width/height が効かなくなったり、つらい。

Canvas

実寸で印刷しようと思うと結局めんどうなのでやめた。

SVG

ハマりそうなのでやめた。

  1. トップ
  2. tech
  3. ピンヘッダのレイアウトを実寸で印刷するツール

FT4232H

http://strawberry-linux.com/catalog/items?code=50029

FT2232H か FT4232H を使って JTAG インターフェイスにするのが高コストパフォーマンスっぽいので、FT4232H を買ってみた。FTDI の一部のシリアルポート変換チップは、MPSSE という方法で JTAG や I2C, SPI を喋ることができる。

なので、UART 接続しつつ JTAG しつつ、みたいなのが1個あればできて便利そう!って感じです。ただ、他プロトコル喋らせるのは、やはりちょっとハマりどころがあった……

JTAG 専用の USB インターフェイスの中には普通にこれを使っているのも多いみたい。専用のものだとここに書いてあるようなハマり所はあまりなさそう。

この製品のピン配置

OpenOCD

JTAG をハンドリングして使えるようにしてくれる OSS として Open OCD (オンチップデバッガー) というのがある。これは gdb のプロトコルを喋るサーバーになったりしてくれる。

FT4232H を生で使った場合、2つの方法がある。

libftd2xx を使う場合

FTDI が提供しているドライバを使う場合。ドライバ自体のソースは非公開のビルド済みのものを使う。

http://www.ftdichip.com/Drivers/D2XX.htm で libftd2xx をいれる

sudo cp /Volumes/release/D2XX/bin/10.5-10.7/libftd2xx.1.2.2.dylib /usr/local/lib/
sudo ln -sf /usr/local/lib/libftd2xx.1.2.2.dylib /usr/local/lib/libftd2xx.dylib
sudo cp /Volumes/release/D2XX/Samples/ftd2xx.h /usr/local/include/
sudo cp /Volumes/release/D2XX/Samples/WinTypes.h /usr/local/include/  # Win とかついてるが必要

で、入れたら、homebrew で以下の通りインストールする

sudo brew install openocd ----enable-ft2232_ftd2xx 

このようなファイルを generic-ft4232h.cfg でつくる。

# Adapter Configuration:
# http://openocd.sourceforge.net/doc/html/Debug-Adapter-Configuration.html

interface ft2232
ft2232_device_desc "Quad RS232-HS"
ft2232_layout usbjtag
ft2232_vid_pid 0x0403 0x6011 # vendor id, product id from usb

vid_pid は system_profiler SPUSBDataType を実行して出てくるやつを入れたらよい。

ft2232_layout は、この FT4232H を使う場合 usbjtag を指定すればよい。usbjtag を指定した場合

  • ADBUS0 -> TCK
  • ADBUS1 -> TDI
  • ADBUS2 -> TDO
  • ADBUS3 -> TMS
  • ADBUS4 -> nTRST
  • ADBUS5 -> WAIT or STOPCLK
  • ADBUS6 -> nRST
  • ADBUS7 -> RTCK

になる。

libftdi を使う場合

入れるのはより簡単

sudo brew install openocd --enable-ft2232_libftdi 

とするだけで依存まで入る。ちなみに OpenOCD が最新の libftdi には対応していないので、自分でビルドしようとするとだいぶハマる。homebrew 使いましょう。

設定ファイルは以下のようになる。コメント頑張って書いた。AN_135_MPSSE_Basics.pdf で出てくるドキュメントと FT4232H のデータシートを読むとだいたい必要な情報は理解できる……

# Adapter Configuration:
# http://openocd.sourceforge.net/doc/html/Debug-Adapter-Configuration.html

# Use MPSSE adapter
interface ftdi
# USB driver name (must be matched with your device)
ftdi_device_desc "Quad RS232-HS"
# USB vendor ID, product ID pairs
ftdi_vid_pid 0x0403 0x6011

# Channel for using JTAG
ftdi_channel 0

# Initial state and direction setting (ref. AN_135_MPSSE_Basics.pdf)
# ftdi_layout_init [data] [direction]

#  name   signal  state      direction  JTAG name
# *DBUS0  TCK/SK  (low =0)   (out=1)    TDI
# *DBUS1  TDI/DO  (low =0)   (out=1)    TDO
# *DBUS2  TDO/DI  (low =0)   (in =0)    TCK
# *DBUS3  TMS/CS  (high=1)   (out=1)    TMS
# *DBUS4  GPIOL0  (low =0)   (in =0)    (nTRST)
# *DBUS5  GPIOL1  (low =0)   (in =0)    WAIT | STOPCLK
# *DBUS6  GPIOL2  (low =0)   (in =0)    (nRST)
# *DBUS7  GPIOL3  (low =0)   (in =0)    RTCK
ftdi_layout_init 0x08 0x0b

# Use GPIOL0 as nTRST
ftdi_layout_signal nTRST -data 0x10
# Use GPIOL2 as nRST
ftdi_layout_signal nRST -oe 0x40

libftdi を使う場合エラーメッセージがろくに表示されないので罠い。例えば、ftdi_device_desc が間違っていると error code -100 みたいなエラーしかでないのでさっぱりわからない。

この設定ファイルの場合、ftd2xx の usbjtag と同じピン配置になる (はず…)。すなわち以下

  • ADBUS0 -> TCK
  • ADBUS1 -> TDI
  • ADBUS2 -> TDO
  • ADBUS3 -> TMS
  • ADBUS4 -> nTRST
  • ADBUS5 -> WAIT or STOPCLK
  • ADBUS6 -> nRST
  • ADBUS7 -> RTCK

Raspberry Pi との接続

Raspberry Pi 側の配置 (リビジョンによって違うが、最近のバージョン = rev2 で)

  • 7pin TDI
  • 13pin TMS
  • 15pin TRST
  • 18pin TDO
  • 22pin TCK
  • 25pin GND


Raspi <-> JTAG

  • 7pin (TDI) 4pin (TDI)
  • 13pin (TMS) 6pin (TMS)
  • 15pin (TRST) 7pin (TRST, GPIOL0)
  • 18pin (TDO) 5pin (TDO)
  • 22pin (TCK) 3pin (TCK)
  • 25pin GND

とする。あとは同じ名前のピン同士を接続する。

Bare metal Raspbery Pi 側で JTAG を有効にする

JTAG は GPIO ピンの ALT 機能なので (JTAG を使ってる場合これらのピンはGPIOとしては使えない)、JTAG を使うようにブートする必要がある。以下のイメージを kernel.img にして SD カードにコピー

https://github.com/dwelch67/raspberrypi/blob/master/armjtag/armjtag.bin

これは単に JTAG を利用するように設定したあと、LED をチカチカさせて接続を待つプログラムになっている。

接続する

raspi.cfg を以下の内容でつくる。

# Broadcom 2835 on Raspberry Pi

telnet_port 4444
gdb_port 3333

#jtag_khz 1000
adapter_khz 1000

#jtag_nsrst_delay 400
#jtag_ntrst_delay 400

if { [info exists CHIPNAME] } {
   set  _CHIPNAME $CHIPNAME
} else {
   set  _CHIPNAME raspi
}

reset_config none

if { [info exists CPU_TAPID ] } {
   set _CPU_TAPID $CPU_TAPID
} else {
   set _CPU_TAPID 0x07b7617F
}
jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID

set _TARGETNAME $_CHIPNAME.arm
target create $_TARGETNAME arm11 -chain-position $_TARGETNAME

でもって、

openocd -d -f generic-ft4232h.cfg -f raspi.cfg 

とする。-d はデバッグオプションなので、ちゃんと動けばつけなくていい。

シリアルポートドライバのアンロード

ちゃんとデバイス名とか設定してるのに! 動かない! ってときは

kextstat  | grep FTDI

してみると、シリアルポートドライバが (入れたなら) 入ってるので、それが動いている。そのポートに対して JTAG をしかけようとしても衝突するのでうまくいかない。

とりあえずアンロードして動くことを試す

sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
# ドライバを無効にしている状態で抜き挿しするとロードされてしまう? アップルがデフォルトで入れてるドライバも無効にする kextstat | grep FTDI ででてくる
sudo kextunload -b com.apple.driver.AppleUSBFTDI

ftd2xx の場合 FT_OpenEx あたりで、うまくいくはずなのに失敗している場合これが疑われる。libftdi の場合エラーがよくわからないので気付きにくい。


これで動くなら動くでいいんだけど、このままだと他のチャンネルをシリアルポートとして使えない。なので、一部のポートだけシリアルポート機能をやめたい。検索したところドライバの設定ファイルを変えればいいっぽい。以下の場所にある。

/System/Library/Extensions/FTDIUSBSerialDriver.kext/Contents/Info.plist

これに対して以下のように A ポートだけ無効にする。

--- Info.plist.orig	2014-03-02 14:58:05.000000000 +0900
+++ Info.plist	2014-03-02 14:58:35.000000000 +0900
@@ -2033,25 +2033,6 @@
 			<key>idVendor</key>
 			<integer>1027</integer>
 		</dict>
-		<key>FT4232H_A</key>
-		<dict>
-			<key>CFBundleIdentifier</key>
-			<string>com.FTDI.driver.FTDIUSBSerialDriver</string>
-			<key>IOClass</key>
-			<string>FTDIUSBSerialDriver</string>
-			<key>IOProviderClass</key>
-			<string>IOUSBInterface</string>
-			<key>bConfigurationValue</key>
-			<integer>1</integer>
-			<key>bInterfaceNumber</key>
-			<integer>0</integer>
-			<key>bcdDevice</key>
-			<integer>2048</integer>
-			<key>idProduct</key>
-			<integer>24593</integer>
-			<key>idVendor</key>
-			<integer>1027</integer>
-		</dict>
 		<key>FT4232H_B</key>
 		<dict>
 			<key>CFBundleIdentifier</key>

一応バックアップをとってから編集して、

sudo kextunload /System/Library/Extensions/FTDIUSBSerialDriver.kext
sudo kextload /System/Library/Extensions/FTDIUSBSerialDriver.kext

すると ls -l /dev/tty.usbserial-* の結果に A が出てこなくなり、JTAG もうまく動くようになる。

JTAG 経由で書きこんで実行してみる

$openocd -f generic-ft4232h.cfg -f raspi.cfg 
Open On-Chip Debugger 0.7.0 (2014-03-02-16:47)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter speed: 1000 kHz
none separate
raspi.arm
Info : clock speed 1000 kHz
Info : JTAG tap: raspi.arm tap/device found: 0x07b7617f (mfg: 0x0bf, part: 0x7b76, ver: 0x0)
Info : found ARM1176
Info : raspi.arm: hardware has 6 breakpoints, 2 watchpoints

上記通りの設定をすると、コマンドでポート 4444 を listen するようになっている。この状態でイメージをアップロードしてみる。

$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> halt
target state: halted
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x600001d3 pc: 0x000210d0
> load_image main.elf
330812 bytes written at address 0x00008000
downloaded 330812 bytes in 3.823093s (84.502 KiB/s)
> resume 0
>

でうまくいけばとりあえず JTAG 経由で何かしらする準備ができた感じ。

gdb

上記通りの設定をしていると、gdb プロトコル用のポートとして 3333 も listen している。これを使って gdb でデバッグをする。

まず先に telnet するなりなんなりして halt してないとだめっぽい?

$  arm-none-eabi-gdb main.elf
GNU gdb (32-bit ARM EABI Toolchain JBS-FLOAT_IO-SGXXLITE_ML-2013.05-23-v2013.05-20-g7e710b6) 7.4.50.20120716-cvs
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-apple-darwin13.0.2 --target=arm-none-eabi".
For bug reporting instructions, please see:
<https://github.com/jsnyder/arm-eabi-toolchain>...
Reading symbols from /Users/cho45/project/raspberrypi-mruby-bare-metal/main.elf...done.
(gdb)  target remote localhost:4445
Remote debugging using localhost:4445
0x00000000 in ?? ()
(gdb) load
Loading section .text, size 0x52c00 lma 0x8000
Load failed

しかし load がうまくいかず……

Error: 33 words out of 4060 not transferred

みたいなエラーがでる。データラインにノイズが乗ってる?

ちょっとすぐ解決できなそうなので今日はここまで……

  1. トップ
  2. tech
  3. FT4332H (FT2232) で Raspberry Pi (bare metal) を JTAG (Mac OS X)