undefined

bokuweb.me

chrome拡張でchrome.fileSystemを使って"いんてるへきさ"のデータ部を配列にぶっこんでみる

はじめに

前回は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を選択すると、配列にデータ部がぶちこまれる。というものです。

f:id:bokuweb:20150216224124j:plain

今回は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)

動作

f:id:bokuweb:20150216224143j:plain

読めた。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』も用意されてっるぽい。いいぞ。もっとやれ。