孫の手スイッチ!?
2012-12-10
以前、秋葉原でLED電球を物色していたら、「孫の手スイッチ」なるものを発見。手にとってシゲシゲと見てみると、いわゆる「手元スイッチ」のことでした。
自作装置が幾つか接続されているACコード・・・これがどうにも心配で、今までは使わないときは神経質にコードを引っこ抜いていたんですが、手元で切れればこりゃ楽だわいと思って買おうか迷った挙げ句、その日は何となく買わずに、お目当てのLED電球だけ買って帰ってきました。今日は、丁度昼食を秋葉原で摂る段取りになり、序でにちょいと寄って買っていこうと思い立ちました。
しかし、よく考えてみると、テーブルタップも自作してたりするんで、要は「スイッチだけ」を買っていって自分で作れば安上がりだろう・・・と思い直し、手元スイッチだけでは売ってないんかなぁと暫し探して発見。

これ、365円なんですが、コンセント付きの立派な「完成品」が860円。ただ、その完成品のコードが2mもあって、ちょっと邪魔だなぁ・・・とこれを買ってきたんですが、よ~く考えてみるとこの5cmくらいのスイッチ、高くないですかねぇ
まぁ、何れにせよセコい話だね
自作装置が幾つか接続されているACコード・・・これがどうにも心配で、今までは使わないときは神経質にコードを引っこ抜いていたんですが、手元で切れればこりゃ楽だわいと思って買おうか迷った挙げ句、その日は何となく買わずに、お目当てのLED電球だけ買って帰ってきました。今日は、丁度昼食を秋葉原で摂る段取りになり、序でにちょいと寄って買っていこうと思い立ちました。
しかし、よく考えてみると、テーブルタップも自作してたりするんで、要は「スイッチだけ」を買っていって自分で作れば安上がりだろう・・・と思い直し、手元スイッチだけでは売ってないんかなぁと暫し探して発見。

これ、365円なんですが、コンセント付きの立派な「完成品」が860円。ただ、その完成品のコードが2mもあって、ちょっと邪魔だなぁ・・・とこれを買ってきたんですが、よ~く考えてみるとこの5cmくらいのスイッチ、高くないですかねぇ

まぁ、何れにせよセコい話だね

ビット処理はunionで案外イケそう・・・
2012-12-10
この記事、縦にやたらと長いです
プログラム開発のC言語化について、既存のMPASMのソースプログラムは、単純にXC8の持つ「Macro Assembler」に移植すれば済むわけですが、そんなに超高速なプログラムを作っても仕方がないことや、XC8の無償版でも案外綺麗にコンパイルしてくれそうなこと(=objがそんなに大きくならないこと)などから、ポート処理には欠かせないビット演算がそれなりの範疇に収まるようなら、殆どC言語ベースの方が後々楽だろう・・・という風に、「アセンブラ遣い」を返上した序でにもっと手を抜いてしまおうと思うに至りました。
そこで、C言語の共用体宣言を以下のように組み、どんなニーモニック(これを逆アセンブルすれば、アセンブラのソースになります)になるかを確かめてみました。
この共用体では、8ビットの符号無し変数を「1ビット単位」「4ビット単位」「8ビット丸ごと」でアクセスできるようになりますが、これに追随して、
・1ビット単位:bsf,bcf に置き換わる
・4ビット単位:swapfに置き換わる
という部分が綺麗に行くなら、多少の無駄を覚悟して「ほぼオールC言語」に持っていけるかな
というわけです。
コンパイラは勿論XC8。ソースファイル名は「lcd.c」としていますが、気にしないでください
コンパイル結果をまとめてみましょう。
なお、前提として「REG_HL」という変数を以下のように「7f 番地」に定義しています。
◆ 役割の決まったレジスタは特別扱い
PORTAやSTATUSといったPICの構成要素として役割が決まっているレジスタは、即値のセットにおいてもそのまま最適に設定されますから、ここはよくできている部分ですね。
ちなみに、アドレスを指定した変数にすれば上記PORTAの場合と同じかなぁ・・・と思ったら、「無駄な2ステップを暴いた記事」に示した通り(この記事の変数bbの展開形をご覧あれ)、余計な2ステップがもれなく付いてきます
う~ん、残念・・・。
◆ 1ビットのON/OFFはイイ感じ
これは、PORTAだろうが自分で指定した固定アドレスの変数であろうが、上記のunionできちんと最適な機械語・・・つまり1ステップのアセンブラ命令にコンパイルされます。例えば、以下のような感じです。
全く無駄がない
というわけで、1ビットのON/OFFは、C言語表現のままで良さそうです。
◆ 4ビット一括設定もまずまず・・・
4ビットの設定は、LCDを4ビットモードで動かすことが多いことから多用されますので、きちんと片付けておきたいところです。どのポートにアサインされるかは、ハード設計仕様に依存しますから固定的では不味いのですが、何れにせよ「どこかのポート」になりますよね。
そこで、一捻りして「PORTx にBIT_t を被せる」という形で、4ビット一括で扱えるようにしました。
これで、「LCD_DT_PORT.BH」と「LCD_DT_PORT.BL」で、各々PORTAの上位4ビット/下位4ビットが扱えます。
セオリー通り、PORTAから読み取ったデータの上位に「0x04」を設定して書き戻してますね。これも合格です。ちなみに、自分で指定した固定アドレスの変数も同じ展開形でした。
◆ 4ビットのハイ・ロー
これもLCDの処理では定番に当たるかも知れませんが、8ビットの上位4ビット⇒下位4ビットの順で出力する場合があります。PICのアセンブラ命令の「swapf」は、この処理に最適なんですが、果たしてC言語で表現した場合、この命令を使って効率的な機械語が吐き出されるか・・・。
ちょいと冗長・・・でも、論理演算を使って上手く処理していると思います。やはり変数「(??_lcd_cmd+0)+0」に纏わる部分がもたついてますね。
ただ、この上位⇒下位の出力処理があちこちにあるわけではないため、そんなに目くじらを立てなくても良いかも知れません。
◆ オマケ・・・
LCD制御にはストローブを与える必要がありますが、これもちょっとマクロで作ってみました。
これでC言語1ラインでストローブ処理「toggle」が使えるようになりました。この部分の展開形を参考に。どういうわけかバンク指定が入ってしまいますが、まぁ良しとしました。
◆ 結果的には
LCDにコマンドを送る処理をアセンブラで記述したサブルーチンが24ステップ。一方、上記を駆使して作ったC言語の関数が吐き出した機械語が36ステップ・・・約1.5倍になりました。これが多いのか少ないのかの議論とは別に、C言語のソースライン数は何と8行
これは、圧倒的に見通しが良い処理になりましたから、ひとまずこの調子でC言語ベースのLCDドライバを完成させ、既に動いているアセンブラ版と比較してみようと思います。
どんどん方針が変わるって
いいのいいの、仕事じゃないんだから

プログラム開発のC言語化について、既存のMPASMのソースプログラムは、単純にXC8の持つ「Macro Assembler」に移植すれば済むわけですが、そんなに超高速なプログラムを作っても仕方がないことや、XC8の無償版でも案外綺麗にコンパイルしてくれそうなこと(=objがそんなに大きくならないこと)などから、ポート処理には欠かせないビット演算がそれなりの範疇に収まるようなら、殆どC言語ベースの方が後々楽だろう・・・という風に、「アセンブラ遣い」を返上した序でにもっと手を抜いてしまおうと思うに至りました。
そこで、C言語の共用体宣言を以下のように組み、どんなニーモニック(これを逆アセンブルすれば、アセンブラのソースになります)になるかを確かめてみました。
typedef union { struct { unsigned B0 :1; // 1ビット毎 unsigned B1 :1; unsigned B2 :1; unsigned B3 :1; unsigned B4 :1; unsigned B5 :1; unsigned B6 :1; unsigned B7 :1; }; struct { unsigned BL :4; // 4ビット毎 unsigned BH :4; }; unsigned char BT; // 8ビット丸ごと } BIT_t; |
この共用体では、8ビットの符号無し変数を「1ビット単位」「4ビット単位」「8ビット丸ごと」でアクセスできるようになりますが、これに追随して、
・1ビット単位:bsf,bcf に置き換わる
・4ビット単位:swapfに置き換わる
という部分が綺麗に行くなら、多少の無駄を覚悟して「ほぼオールC言語」に持っていけるかな

コンパイラは勿論XC8。ソースファイル名は「lcd.c」としていますが、気にしないでください

なお、前提として「REG_HL」という変数を以下のように「7f 番地」に定義しています。
★extern volatile BIT_t REG_HL @ 0x7f; |
◆ 役割の決まったレジスタは特別扱い
PORTAやSTATUSといったPICの構成要素として役割が決まっているレジスタは、即値のセットにおいてもそのまま最適に設定されますから、ここはよくできている部分ですね。
;lcd.c: 65: PORTA = 0x0a; movlw (0Ah) movwf (12) ;volatile |
ちなみに、アドレスを指定した変数にすれば上記PORTAの場合と同じかなぁ・・・と思ったら、「無駄な2ステップを暴いた記事」に示した通り(この記事の変数bbの展開形をご覧あれ)、余計な2ステップがもれなく付いてきます

;lcd.c: 67: REG_HL.BT = 0x0a; movlw (0Ah) movwf (??_lcd_cmd+0)+0 ←これと movf (??_lcd_cmd+0)+0,w ←これ movwf (127) ;volatile |
う~ん、残念・・・。
◆ 1ビットのON/OFFはイイ感じ
これは、PORTAだろうが自分で指定した固定アドレスの変数であろうが、上記のunionできちんと最適な機械語・・・つまり1ステップのアセンブラ命令にコンパイルされます。例えば、以下のような感じです。
;lcd.c: 69: REG_HL.B1 = 1; bsf (127),1 ;volatile |
全く無駄がない

◆ 4ビット一括設定もまずまず・・・
4ビットの設定は、LCDを4ビットモードで動かすことが多いことから多用されますので、きちんと片付けておきたいところです。どのポートにアサインされるかは、ハード設計仕様に依存しますから固定的では不味いのですが、何れにせよ「どこかのポート」になりますよね。
そこで、一捻りして「PORTx にBIT_t を被せる」という形で、4ビット一括で扱えるようにしました。
★extern volatile BIT_t LCD_DT_PORT @ (&PORTA); |
これで、「LCD_DT_PORT.BH」と「LCD_DT_PORT.BL」で、各々PORTAの上位4ビット/下位4ビットが扱えます。
;lcd.c: 71: LCD_DT_PORT.BH = 0x04; movf (12),w ;volatile andlw not (((1<<4)-1)<<4) iorlw (04h & ((1<<4)-1))<<4 movwf (12) ;volatile |
セオリー通り、PORTAから読み取ったデータの上位に「0x04」を設定して書き戻してますね。これも合格です。ちなみに、自分で指定した固定アドレスの変数も同じ展開形でした。
◆ 4ビットのハイ・ロー
これもLCDの処理では定番に当たるかも知れませんが、8ビットの上位4ビット⇒下位4ビットの順で出力する場合があります。PICのアセンブラ命令の「swapf」は、この処理に最適なんですが、果たしてC言語で表現した場合、この命令を使って効率的な機械語が吐き出されるか・・・。
;lcd.c: 74: LCD_DT_PORT.BL = REG_HL.BH; swapf (127),w ;volatile andlw (1<<4)-1 movwf (??_lcd_cmd+0)+0 movf (12),w ;volatile xorwf (??_lcd_cmd+0)+0,w andlw not ((1<<4)-1) xorwf (??_lcd_cmd+0)+0,w movwf (12) ;volatile |
ちょいと冗長・・・でも、論理演算を使って上手く処理していると思います。やはり変数「(??_lcd_cmd+0)+0」に纏わる部分がもたついてますね。
ただ、この上位⇒下位の出力処理があちこちにあるわけではないため、そんなに目くじらを立てなくても良いかも知れません。
◆ オマケ・・・
LCD制御にはストローブを与える必要がありますが、これもちょっとマクロで作ってみました。
extern volatile BIT_t LCD_E_PORT @ (&PORTB); #define LCD_E LCD_E_PORT.B2 #define nop asm("nop") #define toggle { LCD_E = 1; nop; LCD_E = 0; } |
これでC言語1ラインでストローブ処理「toggle」が使えるようになりました。この部分の展開形を参考に。どういうわけかバンク指定が入ってしまいますが、まぁ良しとしました。
;lcd.c: 67: { LCD_E_PORT.B2 = 1; asm("nop"); LCD_E_PORT.B2 = 0; }; bsf (13),2 ;volatile nop ;# movlb 0 ; select bank0 bcf (13),2 ;volatile |
◆ 結果的には

LCDにコマンドを送る処理をアセンブラで記述したサブルーチンが24ステップ。一方、上記を駆使して作ったC言語の関数が吐き出した機械語が36ステップ・・・約1.5倍になりました。これが多いのか少ないのかの議論とは別に、C言語のソースライン数は何と8行

どんどん方針が変わるって


XC8とMPASMの混在は無理そう・・・
2012-12-08
先の記事の続き・・・今日は何とか「XC8とMPASMの混在」に時間を割いてみましたが、結局上手くいかないようだということが判りました。
そもそも、PIC16系より小さなものは詰め込めるプログラム量も限られており、ライブラリ化なんて考える必要はないとも言えるわけですが、高級言語(C言語も一応、アセンブラに比しては高級言語としておきます)向けに本格的になっているのはPIC18系より上だ・・・ということで、コンパイラが抱えているリンカやライブラリアンの作りも、XC16⇒XC32の順に充実していっています。もっと大規模なプログラム作成には、自前のライブラリは結構重宝ですからね。
その代わり、XC8には「ちゃんとしたMacro Assembler」が入っており、インラインアセンブラに向けての扱い易さなどに工夫があって、結局これを使い倒せば「C言語ライクな楽なプログラミングが可能だよ」ということのようだと、「MAPALB X IDE」のHELPを眺めていて判ってきました。
試行錯誤も自分の判る範囲で工夫して随分やってみましたが上手くいかず・・・流石にちょっと飽きたわ
まぁ、少々残念ですがライブラリにしたかったアセンブラソースを、XC8の「ちゃんとしたMacro Assembler」へ移植しようと思います。差分が沢山あったら、別途まとめようと思います。
そもそも、PIC16系より小さなものは詰め込めるプログラム量も限られており、ライブラリ化なんて考える必要はないとも言えるわけですが、高級言語(C言語も一応、アセンブラに比しては高級言語としておきます)向けに本格的になっているのはPIC18系より上だ・・・ということで、コンパイラが抱えているリンカやライブラリアンの作りも、XC16⇒XC32の順に充実していっています。もっと大規模なプログラム作成には、自前のライブラリは結構重宝ですからね。
その代わり、XC8には「ちゃんとしたMacro Assembler」が入っており、インラインアセンブラに向けての扱い易さなどに工夫があって、結局これを使い倒せば「C言語ライクな楽なプログラミングが可能だよ」ということのようだと、「MAPALB X IDE」のHELPを眺めていて判ってきました。
試行錯誤も自分の判る範囲で工夫して随分やってみましたが上手くいかず・・・流石にちょっと飽きたわ

まぁ、少々残念ですがライブラリにしたかったアセンブラソースを、XC8の「ちゃんとしたMacro Assembler」へ移植しようと思います。差分が沢山あったら、別途まとめようと思います。
XC8とMPASMの混在が微妙・・・
2012-12-08
そろそろ環境を整えてC言語への乗り換えをと考えたものの、やはり高速部分やよく使いそうなルーチン群(例えば、LCD表示や割り込みを使った正確なタイマなど)は、アセンブラによる高速化・コンパクト化も魅力があるため、こうした「混在環境」の構築が可能か確認してみました。
アセンブラルーチン群は、「ライブラリ」という固まりにしてしまい、その時に作るものに合わせて必要なものをチョイスするのがカッコイイわけです(っていうか、常套手段です)が、使用するチップに依存する部分をきちんと排除しないと汎用性がなくなり上手くありませんから、既存の(っていうか、既に作ってしまってある)アセンブラソースをそのまま流用することはできませんが、あまり様変わりさせるのもちょっと面倒・・・。
逆に、テンプレートのようなイメージでプログラムファイルを用意しておき、毎度カスタマイズするというのがPICの場合の常套手段とも言えますから、このライブラリ化については「メリット・デメリット」をよく考える必要があるのですが、何れにせよ「XC8とMPASMの混在」がどんな風に実現できるのか(リンカが上手く動いてくれるのか)を確認することにしました。
◆ ソースの種類ではスイッチできない
C言語ソースはXC8でコンパイル、アセンブラソースはMPASMでアセンブル(※)・・・こうすれば、今まで作ったLCD表示やタイマ制御部分が少しのカスタマイズで「ライブラリ化」できる・・・そう踏んでチャレンジしたのですが、このIDEの場合、あるプロジェクト内のコンパイラ(アセンブラ)の選択が1つしかできません。

プロジェクトのプロパティで選択できるのは、右の方にある「Compiler Toolchain」から1つを選ぶ形になるため、少なくともC言語を使うプロジェクトでは「C言語のコンパイラ」を選択するしかありませんので、アセンブラソースをMPASMで・・・と頑張ってもそれは無理なようです。即ち、MPASMの既存のソースを「そのままの形では活かせない」ということになります。
◆ XC8内蔵の「Macro Assembler」
XC8では、アセンブラとの親和性が高いことを謳い文句の一つにしていますが、これは「MPLAB XC8 Assembly Language」として、XC8の中に「Macro Assembler」が内包される形で準備されているからです。
ところが、このアセンブラの文法やリンクする際の各種の宣言がMPASMとは「似て非なるもの」であり、MPASM用に作ったアセンブラソースをそのままXC8でアセンブルしてもエラーが出てしまいます。特に頻出する数値表現なども少し違っているため、始めはかなり沢山エラーが出ることを覚悟する必要があります。
勿論、これを1つひとつ修正していけばよいのですが、結構手間が掛かるのと幾つかバグ(LIST~NOLISTのネストがおかしい・・・など)を見つけてしまったため、ちょっとゲンナリしています
◆ ライブラリが課題
昨晩は、上記で手こずった挙げ句、結局ライブラリの上手な作りに持っていくところまでには到達しませんでした。これを片付けてしまわないと実際のプログラム作成に入り難いため、今日はこの辺りを片付けようと思いますが、どうもリンクエラーが取れないんで弱っています・・・。
※ プログラムソースを翻訳して機械語に直すことは「コンパイル」と言いますが、アセンブラソースを
翻訳することは特に「アセンブル」と言います。
ツール | Ver | |
環境 | MPLAB X IDE | 1.51 |
C言語 | XC8 | 1.11 |
アセンブラ | MPASM | 5.47 |
アセンブラルーチン群は、「ライブラリ」という固まりにしてしまい、その時に作るものに合わせて必要なものをチョイスするのがカッコイイわけです(っていうか、常套手段です)が、使用するチップに依存する部分をきちんと排除しないと汎用性がなくなり上手くありませんから、既存の(っていうか、既に作ってしまってある)アセンブラソースをそのまま流用することはできませんが、あまり様変わりさせるのもちょっと面倒・・・。
逆に、テンプレートのようなイメージでプログラムファイルを用意しておき、毎度カスタマイズするというのがPICの場合の常套手段とも言えますから、このライブラリ化については「メリット・デメリット」をよく考える必要があるのですが、何れにせよ「XC8とMPASMの混在」がどんな風に実現できるのか(リンカが上手く動いてくれるのか)を確認することにしました。
◆ ソースの種類ではスイッチできない
C言語ソースはXC8でコンパイル、アセンブラソースはMPASMでアセンブル(※)・・・こうすれば、今まで作ったLCD表示やタイマ制御部分が少しのカスタマイズで「ライブラリ化」できる・・・そう踏んでチャレンジしたのですが、このIDEの場合、あるプロジェクト内のコンパイラ(アセンブラ)の選択が1つしかできません。

プロジェクトのプロパティで選択できるのは、右の方にある「Compiler Toolchain」から1つを選ぶ形になるため、少なくともC言語を使うプロジェクトでは「C言語のコンパイラ」を選択するしかありませんので、アセンブラソースをMPASMで・・・と頑張ってもそれは無理なようです。即ち、MPASMの既存のソースを「そのままの形では活かせない」ということになります。
◆ XC8内蔵の「Macro Assembler」
XC8では、アセンブラとの親和性が高いことを謳い文句の一つにしていますが、これは「MPLAB XC8 Assembly Language」として、XC8の中に「Macro Assembler」が内包される形で準備されているからです。
ところが、このアセンブラの文法やリンクする際の各種の宣言がMPASMとは「似て非なるもの」であり、MPASM用に作ったアセンブラソースをそのままXC8でアセンブルしてもエラーが出てしまいます。特に頻出する数値表現なども少し違っているため、始めはかなり沢山エラーが出ることを覚悟する必要があります。
勿論、これを1つひとつ修正していけばよいのですが、結構手間が掛かるのと幾つかバグ(LIST~NOLISTのネストがおかしい・・・など)を見つけてしまったため、ちょっとゲンナリしています

◆ ライブラリが課題
昨晩は、上記で手こずった挙げ句、結局ライブラリの上手な作りに持っていくところまでには到達しませんでした。これを片付けてしまわないと実際のプログラム作成に入り難いため、今日はこの辺りを片付けようと思いますが、どうもリンクエラーが取れないんで弱っています・・・。
※ プログラムソースを翻訳して機械語に直すことは「コンパイル」と言いますが、アセンブラソースを
翻訳することは特に「アセンブル」と言います。
小春日和
2012-12-06
自宅前の通りは椋鳥の住み処として名を馳せるケヤキ通り。例年なら彼らが「帰省した後」には束の間の化粧を見せてくれるそのケヤキ達が、今年は随分と乱雑に紅葉を迎えてバラバラに散っていってしまい、あまり綺麗とは言えなかった。「シュンカシュウトウ」ならぬ「シュンカカトウ」のような季節の移り変わりに、ケヤキもついて行かれなかったのかも知れない。
11月の下旬から一気に気温が下がり、毎朝辛い思いで家を出ることが多くなったが、今日は正真正銘の「小春日和」だった。朝から向島の方に仕事で出向き、早昼を済ませようと浅草まで出てちょっと贅沢な昼食を摂り、午後から浅草橋での打ち合わせまでに少し時間の余裕ができたため、正味30分ほどの「徒歩」を決め込んだ。
3年ほど前には、浅草界隈をよく歩いたものだ。仕事の合間を見つけては、浅草が根城の小粋な同僚とあれこれ飲み食いしていたから、方向音痴が自慢の自分でも信じられないほど、この界隈には聡くなっていた。
「電気ブラン」の前を通り、駒形方面へ。「どぜう」と「むぎとろ」の看板に、拙速に決めてしまった昼食を少々恨みつつ、ポカポカ陽気に少し汗ばみながら、わざと歩みをゆったりとさせた。
浅草からの道すがらの佇まいは、聳え立つ高層マンションの長い陰の中に、「よく持ち堪えたなぁ」と感心するような木造家屋の見本のような家や、以前自分が住んでいたような「THE モルタル」といった作りの家々が問屋さんと軒を並べている。昭和と平成をごちゃ混ぜにして無造作に投げ出したような、それでいて何かほっとする町並みでもある。
路地を曲がると、ちょっと噎せ返るような異臭が鼻を突いた。足元を見ると・・・ギンナンが落ちて潰れている。随分季節外れのような気もするが、これも我が家の前のケヤキの如く季節感を失ったのであろうか。そして視線を頭上に移して驚いた。

たまには、歩いてみるのも悪くないもんだ。
11月の下旬から一気に気温が下がり、毎朝辛い思いで家を出ることが多くなったが、今日は正真正銘の「小春日和」だった。朝から向島の方に仕事で出向き、早昼を済ませようと浅草まで出てちょっと贅沢な昼食を摂り、午後から浅草橋での打ち合わせまでに少し時間の余裕ができたため、正味30分ほどの「徒歩」を決め込んだ。
3年ほど前には、浅草界隈をよく歩いたものだ。仕事の合間を見つけては、浅草が根城の小粋な同僚とあれこれ飲み食いしていたから、方向音痴が自慢の自分でも信じられないほど、この界隈には聡くなっていた。
「電気ブラン」の前を通り、駒形方面へ。「どぜう」と「むぎとろ」の看板に、拙速に決めてしまった昼食を少々恨みつつ、ポカポカ陽気に少し汗ばみながら、わざと歩みをゆったりとさせた。
浅草からの道すがらの佇まいは、聳え立つ高層マンションの長い陰の中に、「よく持ち堪えたなぁ」と感心するような木造家屋の見本のような家や、以前自分が住んでいたような「THE モルタル」といった作りの家々が問屋さんと軒を並べている。昭和と平成をごちゃ混ぜにして無造作に投げ出したような、それでいて何かほっとする町並みでもある。
路地を曲がると、ちょっと噎せ返るような異臭が鼻を突いた。足元を見ると・・・ギンナンが落ちて潰れている。随分季節外れのような気もするが、これも我が家の前のケヤキの如く季節感を失ったのであろうか。そして視線を頭上に移して驚いた。

たまには、歩いてみるのも悪くないもんだ。
オシロを校正したい(><)
2012-12-03
ヤフオクの初めての「大きな買い物」はオシロ・・・「KENWOOD CS-1065」。既に5年も経ったんだなぁ
その間、ほんのちょっとした思いつき測定にしか使っていないんで、そろそろ「火も入らない病」になっていないか気になり、ちょいと通電しようと引っ張り出してきました。

それなりに年季が入ったちょっと小汚い面構えは、手に入れたときからあんまり変わっていません。問題は「動くのか」・・・というわけで、即通電。キャリブレの波形が確認でき一安心。
さて、信号源は・・・と探してみると「クラニシ君」が手を上げています
まずはメインのCH1で波形を見てみました。

綺麗なサイン波でしょ
53MHz辺りを測定中です。写真のピントが少し甘いんですが、見た感じではフォーカスも良く出ていてまだまだ使えそうです。60MHzの二現象(外部入力CHを合わせると三現象)なんですが、測定限界(同期が十分に取れる最高周波数)はこれくらいのようです。一方の2CH・・・こっちがどうもまともに同期が取れず、ちょっとぼんやりとした波形になってしまいます
このでかいオシロは取り回しが面倒なんで、もう一度ヤフオクで売り飛ばしてデジタルの「薄い奴」を買おうかと画策していたんですが、どうせ売るならその前に一度校正に出してみて、その上で判断しようと思いつつ今日に至ったわけです。CH1はそれなりに動いていそうですし、2CHも「全く見えない」というわけではないんで、きちんと校正して貰えばまだまだ使えそう・・・。
数日前に某計測ショップの校正サービスに見積もり依頼を出したんですが梨の礫・・・。まぁ他にもやってくれそうなところはあるんで、ネットの情報を頼りに頼んでみようかなぁ・・・と思案中です。


それなりに年季が入ったちょっと小汚い面構えは、手に入れたときからあんまり変わっていません。問題は「動くのか」・・・というわけで、即通電。キャリブレの波形が確認でき一安心。
さて、信号源は・・・と探してみると「クラニシ君」が手を上げています


綺麗なサイン波でしょ


このでかいオシロは取り回しが面倒なんで、もう一度ヤフオクで売り飛ばしてデジタルの「薄い奴」を買おうかと画策していたんですが、どうせ売るならその前に一度校正に出してみて、その上で判断しようと思いつつ今日に至ったわけです。CH1はそれなりに動いていそうですし、2CHも「全く見えない」というわけではないんで、きちんと校正して貰えばまだまだ使えそう・・・。
数日前に某計測ショップの校正サービスに見積もり依頼を出したんですが梨の礫・・・。まぁ他にもやってくれそうなところはあるんで、ネットの情報を頼りに頼んでみようかなぁ・・・と思案中です。
PIC用Cコンパイラ無償版の「char型の扱い」
2012-12-02
「アセンブラ信者の宗旨替え」から一晩経って早速「C言語信者」になるべく、アセンブルリストを見ながら展開形(C言語の1行がどの程度のニーモニックに置き換えられるのか)のチェックをしました。各種のPIC用C言語コンパイラ製品版は非常に高価で、一応Microchip社推しの「XC8」はStandardが495$
Proが1195$
・・・幾ら円高でも趣味の範疇では少々ビビってしまいます
そこで、無償版のオプティマイズの実力を知っておいて、できるだけコンパクト(≒高速)なプログラムを作るための予備知識を蓄えておこうという魂胆です。
XC8の製品版の「売り文句」としての「Optimization Levels」は、無償版の2倍がStandard、4倍がProというイメージで、確かにその魅力はあるんでしょうが、コンパイラとしての得手・不得手を捕まえてしまいその欠点を補うようなコーディングをすれば、ある程度自前で「無碍な肥大化」を防ぐことができます。また、インラインアセンブラの活用場面の検討にも有利になりますから、この調査はやっておいて損はないでしょう。
そこで、とりあえずXC8の最新バージョン(Ver 1.11)を使って調査してみました。
◆ 調査の前に・・・
・ Enhanced Mid-Rangeを使う
上位言語の特性として「関数」という考え方が強くなります。関数は「戻り値が得られる」「パラメータを渡せる」という部分がその特徴であり、戻り値とパラメータの引き渡しの部分で、旧来のMid-Rangeモデルには幾つか欲しいニーモニックがあったわけですが、これを「Enhanced Mid-Range」ではかなり意識して改善させています。既にPIC16F18xx/19xxは安価で入手も容易、かつ既にPIC16F1823,1827が「我が定番」になりそうですから、まずは「PIC16F1827」を前提に調査しました。
・ あくまで8ビットRISCチップであるということ
C言語の「int」は、これまでのプロセッサの歩みとC言語登場の歴史から16ビット/32ビットが主流なわけですが、幾ら「Enhanced・・・」とは言え8ビットRISCチップに代わりはありませんから、処理が得意なのは明らかに「char」になります。従って、8ビット以上の処理は「それなりの数のニーモニック」にコンパイルされますので、この点も「無駄な処理」になる可能性があります。
そもそも、8ビットもあれば「256通りの意思疎通」ができるわけで、特殊な処理でもない限りはこの範疇で収まるように考えるべきでしょう。
◆ ポートアクセスについて
まずは、何と言ってもポートアクセスについての記述・・・これが解り易いことに加えて、収容バンクの切替などがどんな風なのか・・・という部分です。
記述自体は、上記の通り「レジスタ名」がそのまま使えるようにヘッダファイルが用意されていますから、アセンブラ同様解り易いですね。上記の展開形はというと・・・
アセンブルリストから、ニーモニックに関係のない行・コメントを削除していますが、かなり綺麗にコンパイルされています。
・ バンク切替命令は、必要なときに適宜挿入
・ 8ビットの0設定にclrfを使用
・ ビット制御にはbcf/bsf命令
アセンブラで作っても、上記の通りになりそうですから合格でしょう。バンク切り替えができるだけ生じない順序のコーディングを意識するだけで十分なようです。
◆ 変数代入の罠
8ビット操作が得意なわけですから、8ビットの変数への数値代入も上記のようになるだろうと高を括っていましたが、やはり一筋縄ではいきませんでした
まず、C言語ソースは以下の通り。外部変数「a,c」と内部変数「bb,dd」に数字を代入です。
これがどんな風にコンパイルされるかというと・・・
0,1はそれなりに考えられた最適化が掛かっていますが、即値は2ステップ分のロスがあります。これは実にポピュラーな処理ですから頻発必至・・・ちょっと萎えてしまいました。そこで、あれこれ情報を当たってみたら「HI-TECH C Ver 9.70」では、少し違ったニーモニックが・・・。
即値の代入は、「HI-TECH C Ver 9.70」ではwレジを介した2ステップ・・・普通に考えられるステップ数で片付きます。が、0,1を代入する処理がねぇ・・・。ちなみに、HI-TECH Cの上記以降のバージョンはXC8と同じように「4ステップ」になっています。
また、変数から変数への代入は「HI-TECH C Ver 9.70」はwレジを介した2ステップ、XC8はワーク変数を介した4ステップですから、「0,1の処理に勝るXC8」と甲乙付け難く、ちょっと迷ってしまいます。
何れにせよ、XC8の「char型への2以上の数値代入」「char型同士の代入」は4ステップを消費・・・これはあんまり歓迎できませんね。
◆ 関数の戻り値は「char型のBoolean」が良さそう
関数処理結果の「真偽の受け渡し」を戻り値で行う場合、intなどの型では大きすぎてコンパイル結果のニーモニックが冗長になるため、char型のBooleanを作ると良さそうです。if文の分岐もwレジスタだけで分岐できますので好都合
何だかんだ詳しく調べたり環境の入れ替えを頻々と行っていたりしたら、結局char関連の理解だけで今日は終わってしまいました・・・。が、多分それ以上のビット数の処理は「推して知るべし」でしょうから、この記事の留意点だけで行けそうな気もしています。
※ 12/12/03 Booleanについては流石に考慮してあり、「stdBool.h」をincludeすると「bool」という関数属性が使えます。



XC8の製品版の「売り文句」としての「Optimization Levels」は、無償版の2倍がStandard、4倍がProというイメージで、確かにその魅力はあるんでしょうが、コンパイラとしての得手・不得手を捕まえてしまいその欠点を補うようなコーディングをすれば、ある程度自前で「無碍な肥大化」を防ぐことができます。また、インラインアセンブラの活用場面の検討にも有利になりますから、この調査はやっておいて損はないでしょう。
そこで、とりあえずXC8の最新バージョン(Ver 1.11)を使って調査してみました。
◆ 調査の前に・・・
・ Enhanced Mid-Rangeを使う
上位言語の特性として「関数」という考え方が強くなります。関数は「戻り値が得られる」「パラメータを渡せる」という部分がその特徴であり、戻り値とパラメータの引き渡しの部分で、旧来のMid-Rangeモデルには幾つか欲しいニーモニックがあったわけですが、これを「Enhanced Mid-Range」ではかなり意識して改善させています。既にPIC16F18xx/19xxは安価で入手も容易、かつ既にPIC16F1823,1827が「我が定番」になりそうですから、まずは「PIC16F1827」を前提に調査しました。
・ あくまで8ビットRISCチップであるということ
C言語の「int」は、これまでのプロセッサの歩みとC言語登場の歴史から16ビット/32ビットが主流なわけですが、幾ら「Enhanced・・・」とは言え8ビットRISCチップに代わりはありませんから、処理が得意なのは明らかに「char」になります。従って、8ビット以上の処理は「それなりの数のニーモニック」にコンパイルされますので、この点も「無駄な処理」になる可能性があります。
そもそも、8ビットもあれば「256通りの意思疎通」ができるわけで、特殊な処理でもない限りはこの範疇で収まるように考えるべきでしょう。
◆ ポートアクセスについて
まずは、何と言ってもポートアクセスについての記述・・・これが解り易いことに加えて、収容バンクの切替などがどんな風なのか・・・という部分です。
PORTA = 0; // BANK0 PORTB = 12; TRISA0 = 0; // BANK1 TRISB1 = 1; |
記述自体は、上記の通り「レジスタ名」がそのまま使えるようにヘッダファイルが用意されていますから、アセンブラ同様解り易いですね。上記の展開形はというと・・・
;test.c: 18: PORTA = 0; movlb 0 ; select bank0 ;; バンク切り替え clrf (12) ;; 0を設定⇒clrfを使用 ;test.c: 19: PORTB = 12; ;; バンクが変わらないため」バンク切り替え命令はない movlw (0Ch) ;; 12を代入(アセンブラでも同様な記述) movwf (13) ;test.c: 21: TRISA0 = 0; movlb 1 ; select bank1 ;; バンクが変わればバンク切り替え bcf (1120/8)^080h,(1120)&7 ;; ビットに0を設定⇒bcf使用 ;test.c: 22: TRISB1 = 1; ;; バンクが変わらないため処理はない bsf (1129/8)^080h,(1129)&7 ;; ビットに1を設定⇒bsf使用 |
アセンブルリストから、ニーモニックに関係のない行・コメントを削除していますが、かなり綺麗にコンパイルされています。
・ バンク切替命令は、必要なときに適宜挿入
・ 8ビットの0設定にclrfを使用
・ ビット制御にはbcf/bsf命令
アセンブラで作っても、上記の通りになりそうですから合格でしょう。バンク切り替えができるだけ生じない順序のコーディングを意識するだけで十分なようです。
◆ 変数代入の罠
8ビット操作が得意なわけですから、8ビットの変数への数値代入も上記のようになるだろうと高を括っていましたが、やはり一筋縄ではいきませんでした

まず、C言語ソースは以下の通り。外部変数「a,c」と内部変数「bb,dd」に数字を代入です。
#include <pic16f1827.h> char a,c; main() { static char bb; static char dd; a = 0; c = 1; bb = 5; dd = 0; } |
これがどんな風にコンパイルされるかというと・・・
;test.c: 10: a = 0; clrf (_a) ;; 0はclrf ;test.c: 11: c = 1; clrf (_c) ;; 1はclrfして1インクリメント incf (_c),f ;test.c: 12: bb = 5; movlw (05h) movwf (??_main+0)+0 ;; 即値設定はここを介して行う movf (??_main+0)+0,w movwf (main@bb) ;test.c: 13: dd = 0; ;; 外部変数とローカル変数は同じ仕様 clrf (main@dd) |
0,1はそれなりに考えられた最適化が掛かっていますが、即値は2ステップ分のロスがあります。これは実にポピュラーな処理ですから頻発必至・・・ちょっと萎えてしまいました。そこで、あれこれ情報を当たってみたら「HI-TECH C Ver 9.70」では、少し違ったニーモニックが・・・。
;test.c: 10: a = 0; clrc movlw 0 btfsc status,0 movlw 1 movwf (_a) ;test.c: 11: c = 1; clrf (_c) bsf status,0 rlf (_c),f ;test.c: 12: bb = 5; movlw (05h) ;; 即値は2ステップで片付く movwf (main@bb) ;test.c: 13: dd = 0; clrc movlw 0 btfsc status,0 movlw 1 movwf (main@dd) |
即値の代入は、「HI-TECH C Ver 9.70」ではwレジを介した2ステップ・・・普通に考えられるステップ数で片付きます。が、0,1を代入する処理がねぇ・・・。ちなみに、HI-TECH Cの上記以降のバージョンはXC8と同じように「4ステップ」になっています。
また、変数から変数への代入は「HI-TECH C Ver 9.70」はwレジを介した2ステップ、XC8はワーク変数を介した4ステップですから、「0,1の処理に勝るXC8」と甲乙付け難く、ちょっと迷ってしまいます。
何れにせよ、XC8の「char型への2以上の数値代入」「char型同士の代入」は4ステップを消費・・・これはあんまり歓迎できませんね。
◆ 関数の戻り値は「char型のBoolean」が良さそう
関数処理結果の「真偽の受け渡し」を戻り値で行う場合、intなどの型では大きすぎてコンパイル結果のニーモニックが冗長になるため、char型のBooleanを作ると良さそうです。if文の分岐もwレジスタだけで分岐できますので好都合

何だかんだ詳しく調べたり環境の入れ替えを頻々と行っていたりしたら、結局char関連の理解だけで今日は終わってしまいました・・・。が、多分それ以上のビット数の処理は「推して知るべし」でしょうから、この記事の留意点だけで行けそうな気もしています。
※ 12/12/03 Booleanについては流石に考慮してあり、「stdBool.h」をincludeすると「bool」という関数属性が使えます。
寄る年波には勝てぬ・・・でもC言語は便利(^^;
2012-12-01
そろそろ本格的に冬を迎えました。近くのエアコンの「暖房ノイズ攻撃」で、10KHzほどの間隔でキャリアが並んでいます。15mではS=7くらい・・・こっそり系の運用なんで、場所を特定して処置して貰うわけにも行かず・・・なんですが、TS-590切ってのノッチが頑張ってくれますから、昨冬のIC-703の時より安心。でも、邪魔は邪魔。その上、完全な冬型のCONDXとなれば、アクティビティは下がってしまいます
一方、今年は何と言っても「工作環境の改善」が大きく、この冬場は専ら「ガラクタ作り」に没頭したいと思っていますが、最近どうもちょっとした工作にPICを使いたくなる場面が多く、先週辺りからぼちぼちAD9834を使ったSGモドキを作ろうかしらん・・・と思えど、どうもプログラミングが面倒になってしまい、なかなか重い腰が上がりませんでした。
今日は一昨日の飲み過ぎ&寝不足から爆睡した上に、なんと午後からも微睡んでしまいました。その上、子供のPCが調子悪で「我が家の保守サービス長」たる自分の出番・・・。結局、午後が丸々潰れて夕飯を終えて漸く落ち着き、さぁて・・・とPICのプログラム作りを始めたのですが、やはり何ともどんよりとした気持ちになってしまい捗らず
そこで、新しいチップの情報でも拾おうと何気にMicrichip社のHPなど眺めていると、MPLAB-IDE付属のC言語環境が刷新している様子。「ふーん、XC8ねぇ・・・今年の3月に登場したのか・・・ふむふむ」と読み進めていくと、ちょっと味見してみようかなぁという悪魔の囁きが
アセンブラとC言語・・・無論、生産性から言えば後者の圧倒的勝利なんですが、オプティマイズ(最適化:コンパイルされた機械語をコンパクトにまとめていく機能)が上手くないと、小さなメモリには乗らない、処理速度が遅いなどの弊害が出るため嫌った部分があって、アセンブラの緻密さや高速性に傾倒しがちな自分としては「御法度」と決めていたんです。しかし、これでプログラム作成が億劫になっては本末転倒
さらに、少し前から「必要に迫られる部分だけインラインで『#asm ~ #endasm』を使ってきゃいいか」・・・と思い始めていた部分もあって、禁断のC言語環境を構築してしまいました

少し覚書しておきます。
◆ ANSI準拠で前方参照は無論Warning対象
◆ C言語程度の変数名は、アセンブラでは先頭にアンスコが要る
◆ アセンブルリストは「.lst」ではき出される
◆ 24ビット変数として「short」が使える
◆ Warning 1273は、無償版では必ず出てしまう
アセンブルリストを少し覗いてみました。longの計算ロジックなどではちゃんと必要なライブラリが結合される反面、流石に結構大きくなりますから注意が必要なのは無論のことですが、計算の必要な部分を上手く関数に括り出す工夫などで逃げたり、最悪はプログラムメモリ容量の大きいチップをチョイスしたりすれば済むわけですし、PICKit3では18F/24Fも焼けるわけですから、こっちに逃げていくのもありかも・・・と、今いまは言い訳を探しています
細かなpragmaやマクロなどについては追々覚えていくとして、ひとまずこれで今回のSGモドキは「後学のため」という名目で、C言語ベースで作ってしまおうかと思います。

一方、今年は何と言っても「工作環境の改善」が大きく、この冬場は専ら「ガラクタ作り」に没頭したいと思っていますが、最近どうもちょっとした工作にPICを使いたくなる場面が多く、先週辺りからぼちぼちAD9834を使ったSGモドキを作ろうかしらん・・・と思えど、どうもプログラミングが面倒になってしまい、なかなか重い腰が上がりませんでした。
今日は一昨日の飲み過ぎ&寝不足から爆睡した上に、なんと午後からも微睡んでしまいました。その上、子供のPCが調子悪で「我が家の保守サービス長」たる自分の出番・・・。結局、午後が丸々潰れて夕飯を終えて漸く落ち着き、さぁて・・・とPICのプログラム作りを始めたのですが、やはり何ともどんよりとした気持ちになってしまい捗らず

そこで、新しいチップの情報でも拾おうと何気にMicrichip社のHPなど眺めていると、MPLAB-IDE付属のC言語環境が刷新している様子。「ふーん、XC8ねぇ・・・今年の3月に登場したのか・・・ふむふむ」と読み進めていくと、ちょっと味見してみようかなぁという悪魔の囁きが

アセンブラとC言語・・・無論、生産性から言えば後者の圧倒的勝利なんですが、オプティマイズ(最適化:コンパイルされた機械語をコンパクトにまとめていく機能)が上手くないと、小さなメモリには乗らない、処理速度が遅いなどの弊害が出るため嫌った部分があって、アセンブラの緻密さや高速性に傾倒しがちな自分としては「御法度」と決めていたんです。しかし、これでプログラム作成が億劫になっては本末転倒



少し覚書しておきます。
◆ ANSI準拠で前方参照は無論Warning対象
◆ C言語程度の変数名は、アセンブラでは先頭にアンスコが要る
◆ アセンブルリストは「.lst」ではき出される
◆ 24ビット変数として「short」が使える
◆ Warning 1273は、無償版では必ず出てしまう
アセンブルリストを少し覗いてみました。longの計算ロジックなどではちゃんと必要なライブラリが結合される反面、流石に結構大きくなりますから注意が必要なのは無論のことですが、計算の必要な部分を上手く関数に括り出す工夫などで逃げたり、最悪はプログラムメモリ容量の大きいチップをチョイスしたりすれば済むわけですし、PICKit3では18F/24Fも焼けるわけですから、こっちに逃げていくのもありかも・・・と、今いまは言い訳を探しています

細かなpragmaやマクロなどについては追々覚えていくとして、ひとまずこれで今回のSGモドキは「後学のため」という名目で、C言語ベースで作ってしまおうかと思います。