はじめに
前回はchrome拡張でRS232C通信をやりましたが、今回はintelHEX形式を解析してデータ部を配列にぶっこんでみます。
最近のマイコンは自身のROM領域を書き換える仕組みなどをサポートしているため、前回のRS232C通信とを合わせればマイコンのファームウェアアップデータがchrome拡張で実現できます。
そんなことをchrome拡張でやる人はいないような気もしますが、今回使用するchrome.fileSystemはいろいろと応用が利くので使用方法を覚えておくといいかもです。
いんてるへきさ?
Intel HEXはバイナリ情報をASCIIテキスト形式で運ぶためのファイル形式である。マイクロコントローラやEPROMなどのプログラム可能なデバイスのプログラム書き込みのために広く用いられている。典型的な利用用途としてはコンパイラやアセンブラがプログラムのC言語やアセンブリ言語などのソースコードを機械語に変換し、HEXファイルとして出力する。HEXファイルはROMにマシン語のコードを「焼く」ために書き込み機によって読み込まれたり、対象のシステムで読み込んだり実行したりするために転送されたりする。
http://ja.wikipedia.org/wiki/Intel_HEXより
中身は単なるテキストです。
どんなの作るの?
chrome拡張から*.hexを選択すると、配列にデータ部がぶちこまれる。というものです。
今回はCS+で生成したRL78の*.hexで確認しています。 RL78はセルフフラッシュプログラミングライブラリがrenesasから提供されているのでこれを使用すればファームウェアの更新が可能となります。 今回のサンプルはアドレスの解析など行わず、ただデータを見つけたら配列にプッシュしていくだけなので空き領域はフィルしておく必要があります。すごくサボってますけど、ROM領域の全データを送りつけるだけならこれで事足ります。
chrome拡張を作る
chrome拡張にはローカルファイルにアクセスする機能が用意されています。 この機能を使うことでファイルを触れます。
用意するファイル
- manifest.json
- window.html
- icon.png
- background.js
- jquery.js
- HexAnalyzer.js(HexAnalyzer.coffee)
- app.js(app.coffee)
manifest.json
この拡張がどういうものかを定義します。 ここで"fileSystem"を許可しておかないと通信はできません。
{ "name": "HexAnalizer", "description": "HexAnalizer", "version": "0.1", "manifest_version": 2, "app": { "background": { "scripts": ["background.js"] } }, "icons": { "128": "icon.png" }, "permissions": [ "fileSystem" ] }
window.html
ファイル選択ボタンとPATH表示を用意します。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta> </head> <body> <input type="text" id="file-path"><a id="select-file">hexファイル選択</a> <!-- Load JS here for greater good =============================--> <script src="js/jquery-1.10.1.js"></script> <script src="js/hexAnalyzer.js"></script> <script src="js/app.js"></script> </body> </html>
icon.png
好きなものを用意してください。
background.js
windowサイズ等を指定します。 いじる必要はあまりないかと思います。 ほぼサンプルのまま。
chrome.app.runtime.onLaunched.addListener(function(){ chrome.app.window.create('window.html', { 'bounds': { 'width': 500, 'height': 400 } }); });
HexAnalyzer.coffee
ローカルからhexファイルを選択し、データ部を配列に入れます
class @HexAnalyzer _fileEntry = null _bin = [] _loadCompleteCallback = null constructor : (parameter) -> _$fileSelectButton = parameter.selectFileId _$filePathDisplay = parameter.filePathDisplayId _loadCompleteCallback = parameter.loadCompleteCallback # ファイル選択、パス表示部 _$fileSelectButton.on 'click', -> chrome.fileSystem.chooseEntry { type : 'openFile' }, (entry)-> _fileEntry = entry entry.file (file)-> reader = new FileReader() reader.readAsText(file); chrome.fileSystem.getDisplayPath entry, (displayPath)-> if _$filePathDisplay isnt null then _$filePathDisplay.val(displayPath) _load() getBin : -> _bin # ファイルをテキストとして読み込み、行単位に分割 _load = -> hxf = [] if _fileEntry isnt null _fileEntry.file (file)-> reader = new FileReader() reader.onloadend = (e)-> hxf = e.target.result.split('\n') _analyze(hxf) reader.readAsText(file) # もらった行を解析 _analyze = (hxf)-> for value in hxf if value.substring(0, 1) isnt ':' console.log "error - not *.hex file" length = parseInt(value.substring(1, 3), 16) address = parseInt(value.substring(3, 7), 16) type = parseInt(value.substring(7, 9), 16) switch type when 0 _pushBinArray(value.substring(9, 9 + length * 2), length) when 1 console.log "end of file" _loadCompleteCallback() return when 2 # analyze segment else # データを配列につっこむ _pushBinArray = (data, length)-> counter = 0 while counter < length _bin.push(parseInt(data.substring(counter * 2, counter * 2 + 2), 16)) counter++
app.coffee
# ロードが完了したらメッセージとデータをログに吐く loadCompleteCallback = ()-> console.log "load complete" console.log hexAnalyzer.getBin() hexAnalyzerConfig = selectFileId : $('#select-file') filePathDisplayId : $('#file-path') loadCompleteCallback : loadCompleteCallback hexAnalyzer = new HexAnalyzer(hexAnalyzerConfig)
動作
読めた。RL78のROMが32KByteなので配列の要素数が32768になってる。
サンプル
bokuweb/chrome_app_hexanalyze_sample · GitHub
最後に
What Are Chrome Apps? - Google Chrome
ここを覗いてみると、『User Low-Level System Services』に『USB』、『Serial』、『Network Communications』、『Bluetooth』がある。こういったものをcoffeeで扱えるのはすごくありがたい。(自分でも何やってるかよくわからない感があるけど) 『Bluetooth』には『BLE』も用意されてっるぽい。いいぞ。もっとやれ。