Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20apr2012 kernelvm7-main

3,533 views

Published on

Published in: Technology
  • Be the first to comment

20apr2012 kernelvm7-main

  1. 1. Extreme Java @Fantom_JAC
  2. 2. 自己紹介• Java原人• Java原理主義者• Javaのためならなんでも – ハードウェア設計(回路、PCB等) – ハードウェア実装(ホットプレートリフローを 提唱) – サーバーサイド技術(REST/SOAP等) – 組み込みJVM• 無線、特にZigBeeが好き – 日本ZigBeeユーザーグループ代表
  3. 3. (Java原人からみた) Javaとは• 小型の組み込み機器等に使われるプラット フォーム• センサーやクレジットカード、ICパスポート に組み込まれることが多い• 最近はパソコンでも動くようになったらしい• JVMと呼ばれる海のなかで動く – OSの上で動くことは稀 – OSがある時はLinuxが多い• ARMと仲がいい• お前にサンは救えない
  4. 4. やった(やりたかった)こと これを繋ぎたい
  5. 5. 用意された環境• Javaで直接レジスタが叩ける• EHCIに準拠したレジスタ群
  6. 6. 当初のイメージ Java側 アプリ ドングル側 USB便利なAPI用ドライバ 便利なAPI TCP/IP MAC PHY
  7. 7. 突付けられた現実 Java側 アプリ TCP/IP MAC USB ドングル側 仕様の分からない仕様の分からないドライバ 不親切なAPI 中途半端なMAC PHY
  8. 8. 必要なもの• EHCIドライバ(HCD) – 実質OTGドライバも必要だった• USBスタック/フレームワーク• Ralinkドライバ• 802.11MACスタック• TCP/IPスタック
  9. 9. EHCIとは• USB2.0用のコントローラー仕様• Intelが作った(んでしたっけ)• HCIの一種• ちゃんとレジスタの仕様が公開されてるo(^▽^)o• 3年前のことなので大分忘れてます
  10. 10. 用意されたUSB環境• cHCが存在しない – EHCIで1.1も繋がる謎仕様• 1ポート• OTGを経由している – OTGにはレジスタ仕様の標準がない
  11. 11. コントローラ構成Global Controller OTG Controller Device Host Controller Controller
  12. 12. Global Controller• GC割り込みがかかるので、フラグを見て HC、OTG、DCどの割り込みがかかったのか 振り分ける• 特にThreadは用意しない
  13. 13. OTG Controller• Threadを一本用意してステートマシンを記述 – Stateが変わる(Parameter入力される)まで wait• GCからOTG割込がかかったら – フラグをチェック – 独自仕様なので、独断と偏見でOTG仕様の Parameterに解釈 – パラメータ入力して先述のThreadにnotify• OTG仕様に沿ってState変更 – やるべきことをやる – State変更してまたwaitに戻る
  14. 14. OTG Controller• b_idle時はid入力以外無視 – Device Controllerは実装してません• 小技として・・・ – State変更時はyieldせずに即座に次のアクショ ンをとっている – Stateが変更されないとき(orサボって実装して ないとき)はwaitする – waitは1000msで一応外すようにしている
  15. 15. Host Controller• OTGと同じくThread一本でステートマシン• GCからの割込でUSBSTSをチェック• 起動時はIdle状態• OTGからのReset要求でポートリセット – ポートリセット出来ないのでHC再起動• PORTSCでポート検知、OTGにb_conn入力• Asynchronous ListとPeriodic Frame Listを準 備• AsyncListに初期QHを突っ込む
  16. 16. Asynchronous List• QHとQTDを管理• やってることは普通のEHCI – Javaらしく • QueueHead#setNextQH(QueueHead qh) • QueueElement#fillPayload(byte[], int, int) – newできないので自分でメモリ管理 • ImmortalHeapで予めたくさんとっておく • #allocAlignedArrayとかできるので便利 • 分割して、それぞれ先頭のアドレスをPool • Javaらしく – QueueHead#newQueueHead
  17. 17. Periodic Frame List• Isochronousは絶対にやりません• FSTNもやりません• QHのスケジュールがめんどくさい – 2の冪でないといけない • bIntervalが10だったら8とかになる – HSの場合更に1/8ms単位でスケジューリングす る – 帯域オーバーしていないか常にチェックする – SplitTransactionの場合はC-Maskも空きがある か調べる
  18. 18. Periodic Frame List 1/8 2/8 4/8 8/8
  19. 19. Periodic Frame List 1/8 2/8 4/8 8/8
  20. 20. Periodic Frame List 125us x 8 = 1ms 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0
  21. 21. USBスタック• JSR-80に(たぶん)準拠 – TCKは通してません(キリッ• IBMの作ったRIを使用• RIで足りないハード依存部を実装 – Device Enumeration等• EHCIと合わせて概ね快調に動作
  22. 22. squilla-jsr80• JSR-80をOSGiに対応させた• JSR-80ではドライバやデバイスの管理は規定 されていない – OSGiのDeviceManagentに対応 – UsbDeviceDriverを継承するだけで簡単ドライ バ開発• HubドライバやMSD(BulkOnly)ドライバを同 梱• ひっそりオープンソースで公開
  23. 23. Ralink• その界隈ではあまりにも有名• RT2860/3070を使用 – 一番安かった – 隣のビックカメラにたくさん売ってた• FreeBSD用非公式ドライバを大部分移植 – 公式でLinuxドライバがあるが・・・• 1Mbpsのみ対応 – 気合と根性と納期が足りなかった• WEPのみ対応 – 気合とは・・・根性とは・・・• STAのみ対応
  24. 24. Ralinkの公式ドライバ
  25. 25. Ralink IO• Ralink共通(?)のAPIセット• たぶんUSB以外のインターフェースでも共通 – APIのインターフェース実装さえ変えれば他の インターフェースにも対応?• public interface RTIO – public class USBIO implements RTIO• USBの実装はControl転送を使用 – Vendor Request• read32とかwrite8とか – たぶんMCUのレジスタとお話してる
  26. 26. Ralinkの謎• 起動時にファームウェアをまるごと転送 – 普通フラッシュに書かれてるのでは・・・ – 転送がよくコケる• 膨大な量の定数 – 改造すれば普通に電波法やぶれそう – メモリいじってパッチを当てている疑惑• 怪しいノード管理 – wcid = associationId & 0xFF• ControlFrameだけ実装されているぽい – リアルタイム性の問題?
  27. 27. Ralink系チップ想像図Interface 8051 MCU MCU Radio EEPROM
  28. 28. squilla-net• Javaでプロトコルスタックを書くためのライ ブラリを作った• 各種フレームの生成 – 802.11、TCP/IP、ARP、802.3・・・• 802.11関連多し – ManagementFrame – MLME – Javaに欠けているWLAN用API • Androidにはあるのに・・・(ボソ • (↑大分参考にした)• ひっそりオープンソースで公開
  29. 29. MLME• 最低限のリクエストのみ実装 – SCAN – JOIN – AUTHENTICATE – ASSOCIATE• JOINがよくわからない – 特にRalinkの場合、自動でやっている気がする – JOINって名前が紛らわしい
  30. 30. 802.11+Ralink• じぶんでもびっくりするくらい動いた – SSIDがちゃんとスキャンできた日は興奮が収ま りませんでした
  31. 31. TCP/IPスタックTCPConnectionManager UDPConnectionManager IPv4Service ARPService送受信FIFO+Thread EthernetService EthernetConnection ・・・ EthernetConnection
  32. 32. IPv4• 適当• たぶんもっとまじめに実装しなきゃいけない• フラグメント未対応• 受診時チェックサム計算省略 – 少しでもパフォーマンスが上がると思った の・・・• 特にThreadなし
  33. 33. ARP• RequestおよびReply監視用Thread一本• IPv4側からRequest発行可能 – waitし、Reply到着後Threadからnotifyされるま で待機• 一方的なReplyが来ても、テーブルになければ 一応登録• Requestされたときは、そのまま同一Thread 上で返信 – もう一本Thread置くか迷った
  34. 34. UDP• 簡単• Thread未使用 UDPConnection ・・・ UDPConnection UDPConnectionManager
  35. 35. TCP• 1人に聞いた!もう二度と実装したくないプロ トコルスタック堂々の第一位• なんでこんなプロトコルが30年以上まともに 動いているのかまったく不明• 不可解な輻輳制御• 理不尽な仕様書• ひどい相性問題 TCPConnection ・・・ TCPConnection TCPConnectionManager
  36. 36. TCP• Slow-startもCongestion avoidanceもなし• Fast Recoveryなんてムリムリ• Fast Retransmitだけやった• 輻輳制御なんてむりだお・・・• TCPConnection毎にThread一本 – 頑張って再送まで含めて一本におさめた• Connectionは頻繁に開閉するので専用の ThreadPoolを作成
  37. 37. TCPConnection概要InputStream OutputStreamBufferedPipe BufferedPipe(Ring Buffer) (Ring Buffer) TCPInput TCPOutput ThreadPoolより割当 られた専用Thread TCPConnection
  38. 38. 基本動作• 基本はステートマシン• tickと呼ばれるMethodを無限ループで呼び続 ける – 3Dゲーム開発でよくやる手法• tickされた時に・・・ – 受信FIFOに溜まっていれば取り出して TCPInputに投げ、処理 – なければTCPInputにて、ACK可能であるか判断 し、可能であれば送信 – 最後に再送タイムアウトが発生したかチェック し、必要であれば再送 • タイムスタンプと現在時刻で判断
  39. 39. なぜSingle-Threadか• 当初はマルチスレッドにする予定だった – タイムアウトタイマー用Thread – 送信受信それぞれにThread一本づつ• GCが使えないので管理が大変 – GCより高いプライオリティで動いている• プログラムのミスを起こしやすい – 同期を取るのが大変• リソースを消費する• tickが空回りしないように何もないときは 50ms程度sleepする
  40. 40. BufferedPipe• スライディングウィンドウ実現のために作っ たクラス• 内部はリングバッファ• 非同期に可変長のバイト列を入れる• 非同期に可変長のバイト列を取り出す• つまり、両端がInputStream/OutputStream InputStream OutputStream
  41. 41. BufferedPipe• 探したけど意外とこういうクラスはなかった• 元々TCP向けなので、入出力個別にシャット ダウン可能 – 例えば入力を切ると出力側でEOF• 意外とTCP以外の場面でも活躍する• read()するとちゃんとブロックする• 便利なのでひっそりとオープンソースで公開 – squilla-commons
  42. 42. 残酷な現実• やっぱりどうしてTCPはまともに動かない – UDPはTCPに比べたらまとも• 相性がひどい – 同じWindowsでもパソコン変えただけで通信で きたりできなかったり – Mac相手だとやたら不安定だったり• 簡単なSocket通信だと良いけど – HELLOとか• HTTPとか載せた瞬間に激不安定
  43. 43. スクラッチから実装することの意義• 勉強になる – 百聞は一コーディングにしかず• デバッグが容易 – 腐っても自分の書いたコード• ライセンス問題ゼロ• 話のネタになる
  44. 44. わかったこと• Linuxはすごい(いろんな意味で) – EHCIのコードの雑さ – ネット周りのスパゲティさ – よくこれで動いてるな• FreeBSDは読みやすい – 特にネットスタック• IEEEの仕様書は非常に親切で読みやすい• IETFの仕様書は非常に不親切で読みにくい
  45. 45. そもそもの経緯• ギョウムで必要でした• 半年強で実装しました• 結局使われませんでした
  46. 46. 今後• 眠ってても仕方ないのでオープンソース化? – 欲しい人いるの?• JavaMEがCortex-M向けに出るらしいので – 利用価値が出てくるかも• 使い道募集中
  47. 47. Special Thanks• @naobsd氏• @tawakemono氏• 802.11関連で助けて下さいました
  48. 48. 宣伝• squilla – http://code.google.com/p/squilla/• Jazzkaffe – http://code.google.com/p/jazzkaffe/• Japan ZigBee User Group – http://jzug.org/

×