楽天市場
[無料でホームページを作成] [通報・削除依頼]

PICの制約を取り除く

前のページでTiny AVR/PIC Bootloader+ではPICとAVRでプログラム転送の方法が異なることを説明しました。

そしてPICはAVRに比べてソースプログラム作成上の制約が多いことを明らかにしました。

このページでは拡張ミッドレンジのPIC16Fを対象に、AVR並みに制約を取り除く方法について考察します。

①ブートローダーへジャンプする方法の考察

Tiny AVR/PIC Bootloader+でブートローダーへジャンプするコードは
movlw XX
movwf PCLATH
goto Bootloader

でしたが、拡張ミッドレンジのPIC16FではMOVLP命令が追加されたので
movlp XX
goto Bootloader

上記のように2ワードに短縮可能です。

では更にAVRのように1ワードに短縮する方法はあるでしょうか。

ありました。PICのフラッシュ領域もAVR同様最上位アドレスから最下位アドレスに循環していることが確認できました。
すなわちBRA命令をAVRのように負の方向に使えばバンクをまたいで0x0000からブートローダーへの移動が可能となります。

コードは
DW 0x339F ; bra $-0x60 (PIC16F1827の場合)

コンパイラがエラーコードを吐くためbra命令でなくDWにしています。

このとき気をつけないといけないのは、ブートローダー中で使用しているサブルーチンです。
拡張ミッドレンジのPIC16Fでは相対ジャンプBRA命令は追加されたのですがWレジスタの値によらない相対サブルーチンコールrcallは追加されていません。

BRA命令はPCLATHの値を考慮せずにバンクを移動できる命令なので、ブートローダー中のGOTO命令を全てBRA命令に書き換えてしまえば良いのですが、CALL命令はそうもいきません。

そしてCALL命令を実行すれば必ずPCLATHの値を参照しますので、ブートローダー本体の先頭でPCLATの値をブートローダー用に設定する必要があります。

②ブートローダーの出口の処理
ブートローダーへのジャンプコードが1ワードで済むと出口の処理がやり易くなります。
従来のような強制コピーでなく、AVRのように条件分けでコードを記述することが可能です。

この時気をつけなければいけないのは先ほどと同じPCLATHの設定です。出口でPCLATHをクリアするか、ブートローダー中で(出口に至る直前に)PCLATHをクリアする必要があります。

以下にブートローダー中でPCLATHをクリアした場合を記述します。

出口のコードは以下のようになります。

(1)ソースコードの最初の命令がBRAの場合 (1ワード使用)

braをgotoに変換して記述

(2)その他の場合 (2ワード使用)

ソース0x0000の命令をコピー
DW 0x03263     ;bra 0x0001 (0x3200+Bootloader_size+0x03)

最初のワードでPCLATの値が書き換えられても
次のBRA命令でPCLATHの値を書き換えずに0x0001にジャンプできる。

最初の命令がGOTOなら、goto,braの記述になるが有効なのは最初のgotoのみ

これによりPICソースコードの制約が"ユーザープログラムから0x0000へのジャンプ・サブルーチンコール"を除いて解消されます。