PIC24USBでUSBシリアルに挑戦 (5)結末

XBeeの通信モニタ用に作っていたPIC24USBによるシリアルモニタだが、挫折してしまった。
Microchipから提供されているUSB-CDCクラスのフレームワークは、割り込みで動作させていても結局ポーリングをし続ける必要があり、そこに大きな構造上の制約を受けてしまう。

そこに時間を割いても面白くないので、ホストとのI/FはFT245にやらせることにして、以下のようなボードと、その上で動く簡単なシリアルラインモニタソフトを作成した。9600bps程度で動かしているので、速度的にはまったく問題ないはずである。

 
ボード上にはAE-FT245とPIC24FJ64GB006が載っている。
左上のコネクタはISP用である。

FT245でホストとI/Fしながら、いくつかの端子を下の10ピンコネクタに出し、PIC24の特徴であるピンアサイン機能を使って、2チャンネルのUARTレシーバを10pinコネクタの5pinと6pinに出すようにした。
ホスト側に接続するとこんな感じになる。

 

上半分が子機、下半分が親機である。これでシリアルの状態が見えるようになったので、先に進めることにしたい。

gFTPのインストール

Zigbeeいじりたくてしょうがないのですが、なかなか時間がとれません。
そんな中、ちょっと訳あって、リモートサーバにFTPアクセスする必要がでてきました。WindowsでFFFTPを使ってアクセスするよう指示されているのですが、そこは他の作業をできるだけUbuntuでやっているのもあって、なんとかUbuntuでやってしまいたいところです。(猛者ならコマンドラインでやっつけるところでしょうが、さすがにそこまでの元気は無い・・・)

ということで調べてみると、Ubuntu環境ではgFTPというのが定番のようですので、早速Synapticでインストールです。おもむろに、Synpticのクイック検索で「gftp」と入れると、4つヒットします。大元のパッケージは後ろに何も付かない gftp だと思うので、ポチッとマークしたら、残りの3つも選択されました。

インストールはあっという間に完了。予想通り、ほぼFFFTPと同様に使うことが可能でした。
気をつけて使えばサーバ上のファイルに対するファイルマネージャ(エクスプローラ)ライクに使えそうです。

TrueCryptでディスクを暗号化 (3)初期設定後編

ボリュームの生成が終了したら、暗号化したドライブのマウントを行う。

上半分がマウント先(マウント後にここで設定したドライブレターを通してアクセスする)で、そこにどの暗号化ドライブをマウントするかを下半分の「ファイルの選択」「デバイスの選択」で設定する。
設定したら「マウント」を押すと、暗号化ドライブにアクセスができるようになる。

ソフト処理でAESをかけている割には、極端に遅くなる感じもせず、いい感じである。
課題は、パスワードやキーファイル(使う場合)をどうやって管理するか、というところだろうか。

<追伸>
実は TrueCrypt は日本語化がされている。
ダウンロードのページを下のほうにスクロールしていくと、「More Downloads」というのがあって、その中に language packs というのがある。そこをクリックすると、ソースコードのダウンロードリンクや language packs へのリンクがでてくるので、さらにそこをクリックする。

そうすると、言語ごとの language pack のダウンロードリンクがでてくる。これをクリックすると .zip ファイルがダウンロードできるので、それをダウンロードして展開すると、ローカライズのためのファイルのほかに、日本語マニュアルが出てくる

これらのファイルを TrueCrypt.exe のあるフォルダに置いて、TrueCryptを再起動する。メニューの「Setting」→「Language」で日本語を選ぶと日本語表示になる。

TrueCryptでディスクを暗号化 (2)初期設定前編

インストールが終わったので、初期設定を行う。​

起動すると、こんな画面になる。最初は、「Create Volume」で暗号化ディスクを生成する。

 

 
ファイルを仮想ディスクにするか、パーティション/ドライブ丸ごとかを選択する画面が出る。
今回はディスク丸ごと暗号化なので、
真ん中の「Encrypt a non-system partition/drive」を選択する。
一番下はシステムドライブを暗号化する場合に使うらしい。

 
普通の暗号化ボリュームにするか、さらにその中に暗号化ボリューム(2階層になる)を
作るかを選択する。強制的にパスワードを喋らなければならない状況になった場合に備えて、
ということらしいが、後ろめたいことをするわけではないので普通のものにする。

 
暗号化するボリュームの場所を設定する。「Select Device」でドライブレターが
選択できるので、それで暗号化するディスクを選択する。

ボリューム作成時にフォーマットをするかを選択。上が標準で、ボリューム作成時にフォーマット。
下は、初めて読み出した際に暗号化するらしいが、すごく遅いらしい。

暗号化のモードを選択。普通はAESでいいと思う。
「ベンチマーク」を押すと、下のように暗号化のパフォーマンス測定をしてくれる。

ベンチマークの結果

 
ボリュームのサイズを聞いてくるが、HDD丸ごと1台なので選択肢なし

 
パスワードを入力する。画面ではキーファイルを指定していますが、実際には指定していません。
(キャプチャし忘れました)
キーファイルを使うと、うっかりキーファイルを消去してしまった場合にどうにもならなくなります。
キーファイルの代わりに、特定のUSBデバイスが使えれば便利なんでしょうが・・

TrueCryptでディスクを暗号化 (1)インストール編

雑多なデータはやはりWindows上にあることが多いので、Windowsから暗号化できないと面倒である。仕方がないので、Windows側にTrueCryptを導入して、暗号化パーティションを作成することにした。TrueCrypt(http://www.truecrypt.org/)は「オープンソースの暗号化された仮想ディスクを作成・利用するソフトウェア」(Wikipediaによる)である。詳しくは、Wikipediaの方を参照されたい。

単純にWindowsであればOSの暗号化機能でも良さそうな気もするが、ディスク自体は外付けであり、過去にOSの再インストール時に読めなくなったことがある(このときは他にバックアップがあって助かった)ので、やっぱり外だしのツールのほうが安心かも、ということである。

そんなこんなで、まずダウンロードする。TrueCryptのダウンロードのページにいくと、ダウンロードのリンクとPGP signatureのリンクがある。ダウンロードしたファイルの検証方法は PGP Signature のリンクを押すと表示されるが、Windows版の場合は電子署名を確認してもOKだよ、ということみたいである。よって、ダウンロードしたファイルをエクスプローラで右クリックして、プロパティを表示して確認していく。

プロパティを開いたところ。デジタル署名のタブをクリックする。

 

すでに選んであるが、TrueCrypt Fundation の署名を選択して「詳細」を押す

 

ここで「このデジタル署名は問題ありません」と出れば、OKみたいである。

引き続き、実行形式のファイルをダブルクリックして、インストールを行う。

お約束のライセンス確認である。中身を読んでチェックを入れて「Accept」を押す

 

インストールするのか、展開だけなのかを選ぶ。
展開だけを行う場合は、「システムドライブの暗号化を行う場合」と
「ポータブルモードで動作させる場合」のようである。
展開したファイルの実行形式をダブルクリックすると
ポータブルモードで動作するらしい。

 

セットアップオプションを選ぶ。標準のままにした。

 

インストールの過程が表示される。
完了すると、完了のメッセージが出る。

 

「初めて使うんだったら、チュートリアルを読むことをお勧めするよ、
チュートリアル見たい?」ということなので、「はい」を押す。

 

「はい」を押すと、TrueCryptのチュートリアルのページが開く

ということで、インストール自体はいたってシンプル。あっさり終わりました。

Ubuntuでディレクトリを暗号化

この時期になると、年賀状などを書かなくてはならないだが、年賀状は個人情報の塊でもある。

これまではNAS(玄箱PRO+Debian)に保管していたが、結局無防備な状態であった。調べてみると、Ubuntuでも暗号化ディレクトリが作れるということなので、試してみることにした。
  1. Cryptkeeperのインストール
    Cryptkeeperは、暗号化ディレクトリを生成する encfs のGUIとのこと。
    例によって、Synapticでサクッとcryptkeeperを検索して、インストールする。
  2. 適当にディレクトリを2つ作る。1つは暗号化されたディレクトリの実体(データ格納場所)、もう1つは暗号化されないデータを見せるマウントポイント。
    ここでは、/home/encryptedが暗号化されたデータの格納場所、/home/enc-mtptがマウントポイントとした。それぞれ、chown コマンドで group/owner を自分に変えてある。
  3. 以下の方法で暗号化されたディレクトリを実体にマウントする。
    $ encfs /home/encrypted /home/enc-mtpt
    新しい暗号化ボリュームを作成します。
    Please choose from one of the following options:
    enter "x" for expert configuration mode,
    enter "p" for pre-configured paranoia mode,
    anything else, or an empty line will select standard mode.
    > (ただリターンキーを押す)
    
    Standard configuration selected.
    
    設定が完了しました。以下のプロパティのファイルシステムが
    作成されます:
    ファイルシステム暗号アルゴリズム: "ssl/aes", バージョン 2:2:1
    Filename encoding: "nameio/block", version 3:0:1
    鍵サイズ: 192 ビット
    Block Size: 1024 bytes
    Each file contains 8 byte header with unique IV data.
    Filenames encoded using IV chaining mode.
    File holes passed through to ciphertext.
    
    Now you will need to enter a password for your filesystem.
    You will need to remember this password, as there is absolutely
    no recovery mechanism. However, the password can be changed
    later using encfsctl.
    
    新しい Encfs パスワード:
    Encfs パスワードの確認: 
    $ 
    

    これで /home/enc-mtpt にアクセスすると、暗号化されたデータにアクセスできた。

  4. アンマウントは
    $ fusermount -u enc-mtpt

    でアンマウントできた。

・・・が、ここで問題。EncFSで mount したディレクトリは、どうやら共有できない模様。Windowsからアクセスするディレクトリにするつもりだったので、ガックリである・・・。

PIC24USBでUSBシリアルに挑戦 (4)送信バッファ組込み

アナライザとしてPIC24USBを使う場合、大量のデータがPIC24USBからPCに上がってくることになるが、Microchip社が提供するUSB Frameworkでは送信バッファがそのままUSBコントローラに渡されるため、送信データは毎回ブロッキングされてしまう。これではちょっと都合が悪いので、ソフトウェアのバッファを噛ませることにした。
1KBのソフトバッファをかませたうえでのUSB-CDCの通信速度は約200~250Kbpsといったところのようである。PIC24USBからSOF割り込みの回数カウント値とデータ表示回数をカウントした値をsprintfで表示したものを、PC側でTeraTermProでひたすら表示しているだけである。
XBeeとAVRの間は9600bpsなので、上り下りで約20Kbpsである。凝った解釈をしなければなんとか表示できると思うのだが・・・。

VMware上にUbuntu10.04LTSとXubuntu10.10をインストール

Chromeブラウザのアルファ版を試してみたくなった。しかし、普段の環境にインストールすると後で往々にしてハマることが多いので、VMware上にインストールすることにした。

まずは、Ubuntu10.04LTSをインストール。インストールISOイメージを持ってくる(ダウンロードする)間に、仮想マシンを debian32bit で生成。仮想CDROMにインストールISOイメージをマウントして、仮想マシンを起動。インストールISOイメージを仮想ディスクとは別のHDDにいれていることと、仮想ディスクへのライトキャッシュを許可してあることからか、インストールはあっという間に終わってしまう。次に、アップデートマネージャを起動すると、数百MB分のアップデートが要るということで、かなりの時間を要してしまった。
VMware toolsのインストールも、共有ディスクを生成していないことでエラーが出るのと、vmxネットワークドライバのコンパイルでエラーになるが、操作性とグラフィックスの改善ができたのでよしとする。(しかし、実際には、VMwareについているVMware toolsよりも、ここで紹介されているopen-vm-toolsの方が良いのかもしれない。)
それはさておき、Ubuntuのインストール中に見つけた、軽量版のXubuntuが気になってしまった。(Ubuntuでも十分に軽いのだが)
同様にインストールISOイメージを持ってくる(ダウンロードする)間に、仮想マシンを debian32bit で生成。仮想CDROMにインストールISOイメージをマウントして、仮想マシンを起動。インストールISOイメージを仮想ディスクとは別のHDDにいれていることと、仮想ディスクへのライトキャッシュを許可してあることからか、インストールはあっという間に終わってしまう。こちらのインストール時は繁体字(中国語)まじりの日本語になっているが、インストール後の日本語の文字はUbuntu10.04と大差は無い。(ただし、メニュー自体は一部英語のままになっている)
次のアップデートもUbuntuと同様だったが、その次のVMware toolsのインストールで嵌ってしまった。結局、調べていくと、VMwareについているVMware toolsではなく、ここで紹介されているopen-vm-toolsを

$ sudo apt-get install open-vms-tools

でサクッとインストールするだけでよいことがわかった。
次にChromeブラウザをインストールした。デスクトップやランチャメニューに追加するには、Ubuntuの場合にはマウス操作でできたのだが、Xubuntuはそうはいかず、ランチャを一つずつ追加するしかなさそうである。
機能的にはやや劣るものの、XubuntuはUbuntuと比べても非常に軽い。そして概ね日本語化ができていて、フォントも(インストーラを除けば)Ubuntuのものと同じ綺麗なものが使われている。・・・と思ったら、XubuntuでChromeを使うとUIと異なるちょっと貧相なフォントが使われてしまうのが残念。Chromeの設定自体は同じようなので不思議なのだが・・・。


12/23追伸
Chromeのアルファ版はWindows版しかないのであった。がっくり。

PIC24USBでUSBシリアルに挑戦 (3)ソースを改造してみる

USB Frameworkは無事に動作したのだが、ループの中で常にCDCTxService()を呼び出し続けなければならない構造になっていて、改造しにくい。できればそんなものは割り込みなどで監視してほしいものである。

なので、もう少しコードを眺めてみることにした。そこでわかったこと、試してみたことは、

  • usb_config.h の中に、
    #define USB_INTERRUPTがあり、PIC24FJ256GB106ではUSBは割り込みで動作している。
  • main.c の最後に、BOOL USER_USB_CALLBACK_EVENT_HANDLER()という関数があり、そこでUSB割り込み発生後のユーザー用のハンドラを記述できる。
    EVENT_TRANSFERがパケット転送後、EVENT_TRANSFER_TERMINATEDがパケット転送中断後のイベントのようである。Start of Frame は EVENT_SOF
  • 問題の面倒くさい処理 CDCTxService()は、usb_function_cdc.c の最後にある。
    細かくは見ていないが、USBHandleBusy(CDCDataInHandle)を確認し、BUSYでなければ送信データをエンドポイントのサイズに分割しながらメモリ中にコピーして、USBTxOnePacket()を呼び出している。このUSBTxOnePacket()は、usb_device.h の中で
    #define USBTxOnePacket(ep,data,len) USBTransferOnePacket(ep,IN_TO_HOST,data,len)
    となっている。
  • putUSBUART()は、mUSBUSARTTxRam()を呼び出している。その際、cdc_trf_stateがCDC_TX_READYかどうかをチェックしていて、CDC_TX_READYでない場合には、何もせずに帰ってくる。即ち、送信しようとしたデータは捨てられることになるが、事前にUSBUSARTIsTxTrfReady()をチェックしていれば、そのようなことは起きないはず。
  • cdc_trf_stateはエンドポイントの初期化でCDC_TX_READYにセット、CDC_TX_COMPLETINGの状態でCDCTxService()が呼ばれるとCDC_TX_READYにセット、mUSBUSARTTxRam()などを呼ばれるとCDC_TX_BUSYにセットされるようである。整理すると、「CDC_TX_READY」→「(送信データセットで)CDC_TX_BUSY」→「(データの終わりのZeroLengthPacket送信で)CDC_TX_ZLP(省略あり)」→「CDC_TX_COMPLETING」→「CDC_TX_READY」となるようである。
  • mUSBUSARTTxRam()は渡されたデータのポインタ(アドレス)、長さなどをモジュール内のグローバル宣言の構造体や変数などにコピーするだけ。実際の転送処理はCDCTxService()に任される形になる。

つまり、putUSBUART()などから送信データをポインタ渡しされたら、そのポインタをコピーしておき、CDCTxService()が呼ばれる度に状態をチェックして、送信データをエンドポイントのサイズに分割しながらコピー、送信する、という動作のようである。

これらのことから、以下のようにすれば概ね上手く行くのではないかと考えた。

  • 送信データをセットする前に、USBUSARTIsTxTrfReady()をチェックして、CDCTxService()が抱えている未送信データの有無をチェックする。(CDC_TX_READYかチェックする)
  • 送信データを準備し、putUSBUART()でそのポインタを教えてやる
  • その直後に、一度だけCDCTxService()を呼び出し、送信を開始する。CDCTxService()はデータをエンドポイントのサイズに切り出して最初のパケットを送信する。
  • USER_USB_CALLBACK_EVENT_HANDLER()の中のEVENT_TRANSFERのところに、CDCTxService()を追加して、1パケット送信ごとに自動的にCDCTxService()が呼ばれるようにする。割り込み処理内なのでネストしてしまうリスクがあるが、USBUSARTIsTxTrfReady()を実行してから送信処理をしていれば大丈夫なはず・・・。

ということで、実際に試してみた。確認のため、usb_config.hの

#define CDC_DATA_OUT_EP_SIZE 64
#define CDC_DATA_IN_EP_SIZE 64
を共に4に変更してみたところ、送信(PCから見ると受信)に関しては問題ないようである。
しかし、逆方向はファイルを流し込むと送受信を同時に行った際にデータを取りこぼしてしまう。もう少し調べなければ・・・。

PIC24USBでUSBシリアルに挑戦 (1)準備編

ずっと前に買ったオプティマイズのPIC24USBを引っ張り出してきた。
このボードに搭載されているPIC24FJ256GB106にはUSBデバイスインタフェースとシリアルポートが4チャンネルあるので、これらを使ってシリアルラインモニタを作ろうと考えている。シリアルラインモニタを使って、XBeeのプロトコルをモニタする作戦である。

USBプロトコルの処理は、Microchip Technology社から提供されているMicrochip Application Librariesの中のUSB Frameworkを使うつもりである。Microchip Application Librariesは、MicrochipのホームページのSoftware Librariesの中からダウンロードできる。

ダウンロードしてインストールすると、Microchip Solutionsというフォルダができるので、その中の「USB Device – CDC – Basic Demo」フォルダの中の、「CDC – Basic Demo – Firmware」フォルダの中の、「USB Device – CDC – Basic Demo – C30.mcw」をダブルクリックすると、MPLABが立ち上がり、プロジェクトが開く。

ここで、「Configure」→「Select Device」でPIC24FJ256GB106を選択し、さらに「Project」→「Package in .zip」を選択すると、ビルドに必要なファイルだけが「USB Device – CDC – Basic Demo – C30.zip」という名称でZIPに圧縮して保存される。これを別のフォルダで展開したものを作業のベースとすることにした。

試しに、「Project」→「Build All」すると、ちゃんとHEXファイルが生成されることを確認できる。