2019年3月31日日曜日

IchigoBoy 2、IchigoBoy Pocket2

IchigoBoyを更新します。

皆さんからご意見頂きまして改定することにしました。

IchigoBoy2

抵抗器の配置で違う種類が混ざっていたので並べなおしました。
抵抗の足の間隔を少し広げて付けやすくしました。
モニターコネクタが当たっていたので切欠きました。
LCDの位置を左右中央に移動しました。
電池コネクタを少し移動しています。
OUT1~6に配線できるパッドを追加しました。キースイッチと切り替えでうまく使えば利用できます。
コマンドが裏側に書いてありますが、電池ボックスで隠れにくいように少し移動しました。
バックライトにジャンパー線を付けていましたが、パターンを追加してジャンパーの半田付けを不要にしました。暗く設定するときはパターンを削ればOKです。
     等々。

IchigoBoy Pocket2

ROMを追加しました。(OFFできるので、外付けROMも使えます。)
Bボタンが押しにくかったので位置を調整しました。
電源スイッチに足つきの壊れにくいものも使えるようにしました。従来タイプも使えます。
基板の中央になりましたが、OUT1~6の端子を出しました。キースイッチと共用ですが使えます。


補足

PocketはROMを追加しました。スイッチの間に置きましたのでちょっと目立ちます。
OUT1~6を配線を半田付けして引き出せるように追加ポートを用意しました。
INはLCDに使っているので、やめておきました。LCDのあるコントローラなどに利用できるとおもいます。
OUT1~6はBoy的にはINに設定して使いますのでそのままであればボタンの状態が追加ポートでわかります。ここで、OUTに変えるとスイッチの状態ではなくOUTした状態に変わります。注意点は、INで使うときはスイッチの状態(通常0で押すと3.3V)になることと、抵抗が入っているので取りだせる電流に制限があることです。

回路は基本的には変わっていませんので掲載は省略します。

回路図追記(Pocket ROM付き版、OUTPORTはIchigoBoy2と同じです。)
ダウンロードはこちら


告知

メイカーフェア京都2019にエントリーしましたので、これにもっていく予定です。



メイカーフェア京都2019に出展しました。お買い上げいただいた皆様ありがとうございました。





Ichigojam用モニターTVの中の基板

IchigoJamで使っているダッシュボードモニタの故障品が届きました。
修理しようとして溜まっています。
とりあえず写真だけ撮ってあったたけで修理は進んでいないのですがこれはこれで面白いので公開しておきます。







電解コンデンサを交換したら動きましたが、、
ケースに入りません。(^^;;;

中身は色々ありますね。
故障個所ですが、ざっと見たところでは電解コンデンサの容量抜けですねえ。電解コンデンサのてっぺんは平らなのが初期状態ですがよく見ると膨らんできています。典型的な不良モードです。コンデンサとしては機能しなくなってると考えられます。

となれば修理作業は単純で、コンデンサを交換すればOKです。

ただ、故障したのは面実装用の小さな部品を使っていて熱がコモッタというのが根本にある可能性があります。それだと同じ部品を持ってきて交換してもまた壊れます。
外形が大きなコンデンサに変えればよいですが、それだとケースに収まらなくなります。

1台はフェライトコアが割れていました。割れたかけらが残っていれば瞬間接着剤で貼り付ければ治りますが、なくしてしまいました。

面実装コンデンサの交換はそれなりに難しいというのもあって放置ですが、近いうちに直したい。です。

LPC1114 にプログラムを書く

IchigoJamに使われているLPC1114は、NXPから無償のコンパイラが入手できます。
書き込みTOOLもFlashMagicがNXP社のサイトからダウンロードできます。
ところが、コンパイラがつくるファイルはELFフォーマットでそのままではFlashMagicでは書き込みできません。Linuxだと変換TOOLがあるのですが、Windowsにはないようです。
LPCExpressoを買えば、ELFファイルを書き込めるので問題はないのですが、FlashMagicでも書けるようにしてみたい。

ELFをBINやHEXファイルにするTOOLを作ろうというのが今回のテーマです。

NXP社のコンパイラ

まずは、LXP11xx用のTOOLとExampleをダウンロードしてきます。
無償でも256Kbまでコンパイルできるようで、問題なく使えます。LPC1114には32Kbしかメモリがないので余裕です。

さて、とりあえず以前にも使ったことのあるBlinkyをReleaseでコンパイルしました。
コンパイルに先立って参照するライブラリをコンパイルしておかないとエラーになります。

プロジェクトのReleaseフォルダのなかに「LPCX1114_cmsis2_blinky.axf」というのができていました。拡張子が予想とちがいますが、これがELFファイルのようです。

次に中を見たいのでバイナリエディタを探してもいいのですが、後で変換する予定なので中をみるツールを作ることにします。

ファイルをバイナリでひらくプログラム

Visual Studio2013

C#のデスクトップアプリを作ることにします。
Form1にボタンとテキストボックスを貼って、テキストボックスのマルチライン=TrueにしてFrom1に次のコードを書きます。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ArmElfHandle
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        
        byte[] elf;

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();

            if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {

                FileStream fs = new FileStream(ofd.FileName, FileMode.Open);

                elf = new byte[fs.Length];

                fs.Read(elf, 0, elf.Length);

                fs.Dispose();

                StringBuilder sb = new StringBuilder();

                for(int i=0; i<elf.Length; i++)
                {
                    sb.Append(elf[i].ToString("x2"));
                    if((i%16)==7)
                    {
                        sb.Append(" -");
                    }

                    if((i % 256) == 255)
                    {
                        sb.Append("\r\n\r\n");
                    }
                    else if((i % 16)== 15)
                    {
                        sb.Append("\r\n");
                    }
                    else
                    {
                        sb.Append(" ");
                    }
                }

                textBox1.Text = sb.ToString();
                
            }

        }
    }
}

実行するとファイルを開くダイアログが現れるので、先ほどのELFファイルを指定します。
結果はこんな感じです。”45 4c 46”(ASCIIでELF)が最初にあってよさげです。
これで、ELFファイルのバイナリダンプができました。このTOOL上では見にくければ適当なテキストエディタなどにコピペすれば見やすくなります。

ELFファイルのダンプリスト

さて、ELFファイルですが、最初の256バイトはこうなっていました。

7f 45 4c 46 01 01 01 00 - 00 00 00 00 00 00 00 00
02 00 28 00 01 00 00 00 - 03 01 00 00 34 00 00 00
6c 5b 02 00 00 02 00 05 - 34 00 20 00 02 00 28 00
13 00 10 00 01 00 00 00 - 00 00 01 00 00 00 00 00
00 00 00 00 ac 06 00 00 - ac 06 00 00 05 00 00 00
00 00 01 00 01 00 00 00 - 00 00 02 00 00 00 00 10
ac 06 00 00 04 00 00 00 - 0c 00 00 00 06 00 00 00
00 00 01 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00

これを後述のLINKを参考に手作業で調べてみます。

ELFヘッダの手解析

7f 45 4c 46  最初の4バイトは固定です。3バイトは”ELF”ですね。
01      EI_CLASS:32ビットアーキテクチャ
01      EI_DATA:リトルエンディアン
       (複数バイトの値は下位バイトから書くということ)
01      EI Version は 1
00 - 00 00 00 00 00 00 00 00 ゼロで埋めてあるらしい。将来拡張用かな

02 00     種類。実行ファイル。(予想通りですね)
28 00     マシンの種類。ARMの仕様書に40と書いてあり一致しています。
01 00 00 00 - Version 1
03 01 00 00  e_entry; システムが最初に送る制御コードの仮想アドレス
34 00 00 00  e_phoff; プログラムヘッダテーブルのオフセット
6c 5b 02 00  e_shoff; セクションヘッダテーブルのオフセット
00 02 00 05 - e_flags; マシン固有のフラグ
34 00     e_ehsize; ELFヘッダのバイト数
20 00     e_phentsize;プログラムヘッダテーブルの登録ごとのバイト数
02 00     e_phnum; プログラムヘッダテーブルの登録数
28 00 -     e_shentsize; セクションヘッダのバイト数
13 00     e_shnum; セクションヘッダテーブルの登録数
10 00     e_shstrndx; セクション名テーブルのあるセクションテーブル番号

これで52バイトですので、テーブル中のELFヘッダのバイト数34と一致しました。
プログラムヘッダテーブルのオフセットが34なのですぐ次がプログラムテーブルだとわかります。テーブルには2つの登録がありテーブルの大きさが20なので各々32バイトです。
とりあえずセクションテーブルは使いません。フラグが何かCPUの設定を持っていそうです。

プログラムヘッダテーブル

ELFヘッダからヘッダテーブルの位置と大きさがわかりました。
次の2ブロックからなるテーブルがあるとわかりました。

エントリー1:
                  01 00 00 00 - 00 00 01 00 00 00 00 00
00 00 00 00 ac 06 00 00 - ac 06 00 00 05 00 00 00
00 00 01 00 

エントリー2
                  01 00 00 00 - 00 00 02 00 00 00 00 10
ac 06 00 00 04 00 00 00 - 0c 00 00 00 06 00 00 00
00 00 01 00

手作業で解読してみます。
エントリー1:
01 00 00 00 - p_type セグメントタイプ
00 00 01 00   P_offset セグメント内のアドレスオフセット
00 00 00 00   p_vaddr 仮想アドレスオフセット
00 00 00 00   p_paddr 相対アドレスマシン用の物理アドレス
ac 06 00 00 - p_filesz ファイル内でのプログラムのバイト数
ac 06 00 00    p_memsz メモリイメージ内でのプログラムのバイト数
05 00 00 00   p_flags メモリセグメント用のフラグ
00 00 01 00   p_align ファイル内のセグメントの配置指定のための数

エントリー2
01 00 00 00 -  p_type セグメントタイプ
00 00 02 00  P_offset セグメント内のアドレスオフセット
00 00 00 10   p_vaddr 仮想アドレスオフセット
ac 06 00 00   p_paddr 相対アドレスマシン用の物理アドレス
04 00 00 00 -  p_filesz ファイル内でのプログラムのバイト数
0c 00 00 00    p_memsz メモリイメージ内でのプログラムのバイト数
06 00 00 00  p_flags メモリセグメント用のフラグ
00 00 01 00  p_align ファイル内のセグメントの配置指定のための数

ELFファイルのアドレスオフセットの位置からfilesz分だけ読み出して使えばよさそうです。
エントリー2のファイル内のデータが4でメモリ上では12で足りませんが、不足分はゼロで埋めます。
これで、ELFからプログラムコードが取得できそうです。

FlashMagicについて

バイナリファイルを書きだしてFlashMagicで書き込むというのが当初のプランでしたが、FlashMagicが汎用ツールのためCPUのIDチェックなど手厚く処理します。このため、時々書き込めなかったりします。
ISPでの書き込み手順は公開されているので、こうなったら自分で作ることもできます。
ISP書き込みはすでに作ったことがあるので問題ないでしょう。



ELFファイルフォーマット: