秋月のLPC11U35マイコンボードを動かしてみた

久しぶりに秋月へ行ったら、「USBメモリにファイルを書き込むのとほぼ同様の手軽さでプログラムを書き込むことができます」という触れ込みのマイコンボードが安く売っていたので、買ってみました。

で、動かしてみるべく、Linuxマシン(環境はいつものLinux Mintです)へ接続すると、確かにマスストレージデバイスとして認識します。で、秋月のWebサイトにある動作確認用ファームウェアを書き込んで、リセットしてみても、再びマスストレージデバイスとして認識されて、LEDが点滅する気配がありません。

mbedとしても動作する、というのでサンプルプログラムを作って同様に書き込んでみてもサッパリです。linuxではドラッグアンドドロップでの書き込みはうまく行かないのかと思って、コマンドラインで cp コマンドでコピーしてみてもダメです。

で、ぐぐってみたら、どうやら linux ではそもそもファイル書き込みではうまくいかないようで、こちらの情報によると先頭の4ブロック(2キロバイト?)を削ってddで書き込むとうまく行くようです。

ただ、デバイスファイルなんていろんな要因で変わってしまうので、毎回やるのは面倒ですし、事故のもとなので、pythonのスクリプト化しました。

lsblkコマンドで見た時に、転送方法が usb で、モデルが’LPC1XXX IFLASH  ‘となっているデバイスファイルを探して、そのデバイスファイルをアンマウントして、ddコマンドで書き込むだけです。スクリプトファイル⇒mbedにlinuxから書き込むためのスクリプト

ルート権限が必要なのは変わらないので、sudo 付きで python スクリプトを実行します。

みたいな感じで使います。(途中の umount とか dd コマンドの行はこのスクリプトの処理内容を表示しているだけで、書き込みに必要な操作は最初の1行目だけです)

 

【すごい】ESP8266がArduino IDEでサポートされる

いつものように、Hack a Dayの記事から。

タイトル(「ARDUINO IDE SUPPORT FOR THE ESP8266」)だけ見ると、ESP8266をEthernet Shieldとして使えるようになったのかな、と思ってしまうところですが、そんな当たり前の話じゃありません

『ArduinoでESP8266がサポートされた』のではなく、『Arduino IDEでESP8266がサポートされた』のです。言い換えると、ESP8266単体で動かすIoTアプリケーションの開発がArduino IDEでできるようになったということなのです。(github上のサンプルプログラムにはIoTのプロトコルであるMQTTのサンプルも載っています)

ESP8266の内部のXtensaプロセッサをArduino IDEがサポートするようになり、ESP8266モジュールだけでArduinoのpinMode(),digitalRead(),digitalWrite(),analogRead()が使える上に、WiFi機能をEthernet Shieldと同様に使えるようです。一方で、PWMはESP8266自体がハードウェアリソースを1chしか持っていないので制約があり、SPIとI2Cはまだ動作しないようです。

すでに github から Linux(64bit)、Windows、OS X用のArduinoコンパチのIDEがダウンロードできるようになっていて、サポートしている機能の範囲も同じところに書かれています。(Linux版をダウンロードしてみたら70MB以上ありました・・・)

ESP8266の書き換えは、Hack a Dayのこちらの記事にあるような簡単な回路でできるようです。

IDEの安定性次第のところはあるかもしれませんが、安定して使えるようになればこれは間違いなく大ブレイクすると思います。これで無線や電子工作に詳しくない人でもArduinoでマイコン制御機器を作ってみるのと大して変わらない感覚で、ESP8266を使ったIoT機器を作ってみるということが可能になるのですから。

おそらく、Espressif社はWiFiを使ったIoT機器用のチップとしては数量でNo.1になっていくのではないでしょうか。(ちょうど、BluetoothでCSR社が占めているような立ち位置になるんじゃないかと予想します)

いまさらH8-300開発環境を構築してみたけど・・・

いまさらですが、余っているH8/3664ボードを何かに使おうと思って、開発環境を調査してみました。

1.環境

VMware上の Lubuntu14.04.2をターゲットにします。
OSをインストールしたら、build-essentialパッケージをインストールした後、VMware-Toolsをインストールします。

2.Cコンパイラ

いまさらアセンブラもないので、Cコンパイラを探します。
synapticでh8を検索すると、binutils-h8300-hmsとgcc-h8300-hmsが見つかります。これらをインストールします。これらをインストール後、バージョンを確認すると以下のようになっていました。

3.書き込みツール

昔、三岩さんが作られたものと思われるツールが sourceforge にあがっていましたのでコンパイルしてみます。説明では先頭の4行を環境に合わせて修正してからコンパイル、と書いてありましたが、はじめからLinuxのみが#defineされていました。

Warningがたくさん出ましたが、実行ファイルは生成されました。

4.コンパイルテスト

Strawberry LinuxのWebサイトからLED点滅サンプルを持ってきてコンパイルしてみました。

・・・が、-lc がないと言って怒られます。探してみると、どこにもH8用のlibc.aがありません。これは libc.a がないことを意味していますので、newlibをインストールすることにしました。

5.newlibのインストール

組み込み用のlibcであるnewlibをコンパイルします。
その前に、まずgitからインストールです。

さらに、newlibのソースを取ってきます。

このままコンパイルすると、「makeinfoがない」といって怒られますので、synapticでtexinfoパッケージをインストールして、別のターミナルを新規に開いてから configureスクリプトを走らせて、make、make install します。

libc.a、libg.a、libm.a が /usr/local/h8300-hitachi-coff/lib の下にインストールされました。

6.改めてコンパイルテスト

よくみると、さらにはMakefileでライブラリパスが設定されていなかったので、これを修正してみたのですが、今度は互換性のないlibc.aをスキップしました、となってしまいました。

確か、gccのクロスコンパイラをビルドするときにはライブラリ(libcなど)なしで一度コンパイラをビルドしてライブラリをビルド、その後再度コンパイラをビルドし直す手順になっていたかと思うのですが、そのへんがちゃんと行われていないのかもしれません。(ググってもnewlibのバイナリがなく、ソースからビルドするしかなさそうだ、という時点で嫌な予感はしたんですけどね)

7.まとめ

・・・うーむ。ぐぐってみると、同じ問題がはるか昔に出ていたようです。
https://bugs.launchpad.net/ubuntu/+source/gcc-h8300-hms/+bug/342667
ここを見る限り、リポジトリにあってSynapticでインストールできても結局メンテナンスされてなくて使い物にならないようで、そのままずーっと放置されているようですね。

コンパイラごとソースからビルドすれば動く組み合わせもあるかもしれませんが、そこまでして動かす元気はありません。今でも秋月ではH8/300のボードを売ってますが、みなさんどうやって使ってるのでしょう?(メンテナンス目的?教材用?)
いまでもcygwin + gcc2.95.3ベースの環境をCD-Rで売ってるようですが、いまさらのような気がします。

H8は比較的電子工作用途に受け入れられた数少ない日本製マイコンですが、この状況ではとても使う気にはなれません。かといって、いまさらR8Cとか78Kとかってのもないでしょうから、素直に諦めるほうが良さそうです。

さて、余ってしまったボード、どうしよう・・・。

MPLAB-X + PIC12F675は使えない・・・・

ちょっと治具を簡単に手持ちのPIC12F675で作ろうとしたのですが、ハマってしまいました。
今回の環境はMPLAB-X + XC8を使ってみようと思ったのですが、これがハマりの元凶です。

まずはLチカで環境に問題がないことを確認しようとしていたのですが、そこで引っかかりました。

Lチカプログラムはこんな感じで、何の変哲もありません。

101

しかし、コンパイルして動かそうとすると動きません。
いろいろ設定を疑ってみたものの、うんともすんとも言いません・・・・。

プログラムメモリの内容をディスアセンブル表示させると、先頭は

Screenshot-1

というような感じでした。001番地にCALL 0x3FFがありますが、これは確か3FF番地にはRETLW命令が置いてあって、Wレジスタにクロック周波数の補正値を入れて戻ってきて、その後、OSCCALレジスタにWの値を書き込む(上記で言うと、レジスタバンクを1に切り替えてからT1CONのアドレスに書き込む)ことで、周波数を補正していたはずです。

しかし、不安になって、WindowsでPickit2でROMの中身を吸い出して見たところ・・・・・3FF番地の値が0000(NOP)になってました。これでは001番地のCALL命令で無限ループになるので動くわけがありません。

Pickit2にはクロック周波数補正値を回復する機能があるので、それで3FF番地の値を回復させて、改めてMPLAB-Xで書き込んでみるとLチカが動作しました。・・・が、再度コンパイルして書き込んでみると、やっぱり動きません。
Pickit2で見ると、また3FF番地の値が消失しています。この状態をPickit2で吸い出してHEXファイルに保存し、補正値を回復させ、改めて吸い出したHEXファイルを書き込むと、Pickit2は補正値を保存するので、ちゃんと動作しました。

とにかく「MPLAB-XとPIC12F675の組み合わせは使い物にならない」ということがわかりました・・・。

commi(GUIシリアルターミナル)をインストールしてみた

最近、仕事でリバースエンジニアリングっぽいことをやっています。相手がUARTなのでFT232Rベースのシリアルコンバータを接続してごにょごにょやっているのですが、Linuxでマイコン開発をしていると結構困るのがシリアルターミナルプログラムです。Windows環境だとTeraTermという鉄板ターミナルプログラムがあるのですが、Linuxではこれまでいいターミナルプログラムが見つけられず、screen コマンドの引数で /dev/ttyUSB0 などを指定して使っていました。しかしながら、なにぶん通信条件の設定等が面倒です。・・・で、調べていたら見つかったのが commi というQtベースのGUIのシリアルターミナルプログラムです。

オリジナルのプロジェクトページは http://commi.berlios.de/ のようです。で、ページを覗いてみると、CuteComというプロジェクトから fork したようなのですが、画面イメージを見ると、 commi の方が自分の好みに合いそうです。

早速ソースを http://sourceforge.jp/projects/freshmeat_commi/ から取ってきて、LinuxMint11(64bit)環境で展開、

であっさりインストールできました。起動は /dev/ttyUSB0 のアクセス権の関係から、

で自分は起動してます。

設定のしかたがTeratermに比較的近いので気に入っています。

PIC32MXで7segLEDを駆動してみた

続いて、PIC32MXで7segLEDを点灯してみました。

使用したのは4桁のカソードコモンの7セグメントLEDです。

回路は各桁のSEGMENTのA~G、DPをポートBのbit4~10、bit11に100Ωの抵抗を介して接続、各桁をデジタルトランジスタDTC123ESAを介してポートBのbit2,bit3、ポートAのbit2,bit3で駆動しています。

ダイナミック点灯の処理は割込みを1ms周期でかけて、1msごとに点灯する桁を変更しています。

表示している内容は0.1秒単位のストップウォッチ風の何かです。(単にカウントアップしているだけ)

さすがに28pinのDIPマイコンだとこれだけでポートを12本も使ってしまいます。PIC32MX120F032B(PIC32MX120F016BやPIC32MX220F032Bも同じ)は電源・GND関係だけで6本、さらにデバッガで3本の端子を使ってしまいますので、ちょっと苦しいかもしれません。

なお、デフォルトではJTAGやセカンダリオシレータがイネーブルになっているようで、使えない端子があります。それを解決するために、15行目に

という記述を入れて、JTAGやセカンダリオシレータを禁止しています。

なお、例によって役に立たないソースを置いておきます。→7seg駆動のソース

あ~、コメントは直し忘れていますので、無視してください。^^;

PIC32でLチカ(別の方法)

待ちループ、割り込みで点滅するLチカを紹介しましたが、MIPS CPUの場合には別の方法の時間待ちも可能です。
MIPS CPUの場合にはCPUの中のCP0(CoProcessor 0)というのがあって、その中にCOUNTレジスタというレジスタがあります。このレジスタはCPUコアの周波数の1/2の周波数でカウントアップしていきますので、CPUコアの周波数がわかっていれば、時間待ちに使うことが可能です。

本来、CP0のレジスタ読み出しには専用命令(mfc)が必要なのですが、コンパイラにはじめからマクロ定義が用意されているのでこんな感じで使えます。この例は100ms待ってLEDを反転させます。このレジスタには書き込みもできますが、基本的に読み出し専用で使います。読み出し専用で使えば複数のタスクでも共有できるからです。ただし、40MHz動作の場合には200秒程度でカウンタが1周しますし、上記の使い方だとその半分で正常に動作しなくなりますので要注意です。

ソースリストはこんな感じです→CountレジスタでLチカ

このレジスタは特定の区間のCPUの処理時間などの計測にも使えるので結構便利です。デバッガでCPUを停止させるとこのレジスタも停止するので、ブレークポイントを2箇所設定してそれぞれでこのレジスタを見れば処理時間がわかります。

PIC32MXの動作周波数を確認してみる

Lチカは動いたものの、結局何MHzで動作しているのかよくわからなかったPIC32MXですが、実際の動作周波数を調べてみます。

方法はいろいろありますが、知りたいのはプログラムの実行速度なのでデバッガの表示と実際の速度から推定する手段をとってみます。

まず、ループで時間待ちするプログラムのコードに着目します。

ソースからは1回の点灯期間/消灯期間の間にfoo()という関数が10万回ループすることがわかります。ループ以外の時間はほとんど無視できると思われるのでループに着目します。

デバッガでプログラムをいったんスタートしてブレークし、Disassembly Listingを表示しながらアニメーション実行をさせると、

の赤い四角で囲った部分が「for(i=0;i<index;i++);」のループ内であることがわかります。実際には、最後のbne命令はDelayed Branch命令なので、その次のnopも実行しているはずです。また、ループ内にはlw命令が入っていて、メモリからのリードサイクルが発生することになりますが、頻度は低いのでここではそれが速度の制約にはおそらくならないでしょう。
となると、1ループで5命令を5clkかけて実行することになります。つまり、foo()関数では時間待ちとして約50万clkサイクルを要することになるわけです。

一方で、runモードで実際の実行時間を計ってみると、

H区間/L区間ともに約75msであることがわかりました。ここから計算すると、50万clkサイクルが75msなので、75000000ns/500000=150ns=6.67MHzということになってしまいました。

どうやらconfigビットの設定がおかしいようですので、調べていくと、#pragma config の設定はMPLAB IDEの「Help」→「Topics」→「Language Tools」→「PIC32MX Config Setting」の中にあることがわかりました。

そこで、これを参照してConfigの設定を

と修正したところ、H区間/L区間ともに約15msになりました。計算すると、1サイクルが30ns=33.3MHzということになりました。
ちなみにFPLLODIV = DIV_1 のままでは暴走してしまいました。まあ、66.6MHzとなるとしかたないでしょう。

こんどはConfigの設定を

と修正すると、内部オシレータ(8MHz)が直接SYSCLKとして使用されるはずですが、H区間/L区間はともに約75ms=6.67MHzに戻りました。

ここまでの結果から考察すると、1ループが5clkで回っているのではなく6clkになっていると考えると辻褄が合うようです。
(75000000ns/600000=125ns=8MHz、15000000ns/600000= 25ns=40MHz)

そこで、「Project」→「Build Option」→「main.c」でCategoriesをOptimizationを選択して、最適化を「0」から「s」に変更してみます。

すると、青の部分をみるとわかるように関数foo()の呼び出し自体が削除されてしまいました。orz・・・
この状態でリアルタイム実行させてみると、370~380nsでトグルしています。これは125nsの3クロック分、ということなのでしょう。 Configの設定を「FNOSC = FRCPLL」に変更すると70~80nsのトグルになりましたので、こちらも25nsの3クロック分、赤で囲んだ部分のループ(Delayed Branchで実行されるnopを含めて3clk)ということであっていそうです。

修正したLチカプログラムをアップロードしておきます。

  • ループでLチカ
    100万回ループで150msの待ち時間を作って、0.3秒周期でLEDが点滅します。
    ただし、最適化をかけてしまうと待ち時間そのものがなくなってしまいます。
    <追伸>SYS_FREQの定数定義が間違っていました(直し忘れ)。修正していませんのでご注意を。
  • 割り込みでLチカ
    タイマー割り込みで100ms周期(1秒間に10回) でLEDが点滅します

いずれもCPUは40MHz動作(SYSCLKは40MHz、PBCLKは20MHz)です。

DIPの32bitマイコンをためしてみる

先日、秋月電子のWebサイトを見ていたらPIC32MXのDIP版が載っていました。・・・で、とりあえず買ってきてみました。物はPIC32MX120F032BでMIPS4Kコアの32bitマイコンです。MIPSといえば昔はワークステーションに載っていたようなCPUですが、それがプリンタやプレイステーションなどの機器を経て、とうとうPICマイコンの世界まで降りてきてしまいました。

で、最初はお約束のLチカです。

DIPなのでブレッドボードに載せます。

左に見えているAE-UM232Rは単にUSBから3.3V-50mAの電源を取っているだけです。

左端の抵抗はMCLRのプルアップ抵抗です。PIC32(PICkit3に依存かもしれませんが)はMCLRのプルアップ抵抗がないとリセットが解除されないようです。8bitのPICではなくても動作するものがほとんどだったので要注意です。

MPLABを立ち上げて、ポートAのbit0(2pin)に接続した白色LEDを点滅させます。

LEDチカチカのプログラムですが、さすがに32bitマイコンとなると初期設定が多く、初期設定の部分をゼロから書くのは大変です。(このへんはPIC24も同じですが、PIC24は頑張ればLチカくらいはゼロから書けます)
なので、サンプルプログラムを探して参考にして動かすことにしました。

Lチカまでは結構大変なので、役に立つか分かりませんが圧縮したものを置いておきます。

ループで点滅するものと、割込みで点滅するものの2種類です。
ここで不思議なのは、CONFIGレジスタの設定はサンプルプログラムから持ってきた(その前に自分で書いたものもあったのですが、結局同じだった)のですが、結果としてSYSCLKが80MHzになるように思われることです。割込み動作のものの結果をみてもSYSCLK=80MHz、PBCLK=40MHz動作に思えます。しかしながら、データシート類では最大動作周波数は40MHzとされています。
このあたりはもう少し調査してみる必要がありそうです。

また、8bitのPICであればAPIとか面倒なことを考えずにデータシート類を見て直接ポートを叩けば良かったのですが、32bitとなるとMIPSのアドレス空間(ksegとかusegとか)を考えないといけなかったりするので直接叩くのは少し面倒くさそうです。サンプルプログラムからAPI(でいいのかな?)を調べていったりする必要がありそうです。

minicomの使い方

ひょんなことからとあるマイコンの評価ボードを入手しました。

その評価ボードにはシリアルポートがついているのですが、そこにLinuxでつなぎたい、ということでminicomの使い方を調べてみました。

インストールは簡単で、

でおしまいです。

起動は、

でセットアップ画面に入れるのですが、日本語表示だと桁数の関係で画面がかなり悲しいことになります。それでも、3番目の「シリアルポート」を選択して、「A」のシリアルデバイスを「/dev/ttyUSB0」などに設定します。「E」の速度やパリティなどの通信パラメータは初期値で115200 8N1になっています。また、ハードウェアフロー制御がデフォルトでONになっているので、デバイスだけ設定すればOKでした。

そのままEnterやESCで適当に(^^;抜けると、モデムの初期化を試みるようです。minicomは大昔のパソコン通信の時代のものなので、モデム制御が入ってしまう(そしてモデムの応答をまつ)のが鬱陶しいところです。

で、何とかならないかとと思って、manページを読んでみました。

コマンドラインオプション

  • 「-s」でセットアップ画面。システムの初期設定値は /etc/minicom/minirc.dfl に記述されている。-s オプションをつけるとイニシャライズせずに直接設定メニューを表示するようです。
  • 「-o」でモデムの初期化をせずに起動します。今回はシリアルコンソールとして使うので、このオプションをつける方がいいですね。ちなみに「C-a z q」でモデムの初期化無しに終了します。
  • 「-b」で通信速度を指定します。
  • 「-D」でデバイスを指定します。今回の場合は「-D /dev/ttyUSB0」という感じですね。
  • 「-7」「-8」でビット長を指定します。

システムの初期設定値は /dev/minicom/minirc.dfl に記述されている、ということですが、初期設定ではファイルは存在しません。「$ sudo minicom -s」でメニューを起動して、デバイスや通信速度等を設定し、dfl に保存する操作をすると /dev/minicom/minirc.dfl が生成されましたので、そういう使い方が良さそうです。

使い方で必ず必要なこととしては、終了の「C-a z q」だけで良さそうな気がします。