自作電子小物/TIPS/ブートローダ使用例/PIC18F26J50
            自作電子小物/TIPS/ブートローダ使用例/PIC18F26J50
Microchip社のUSB付マイクロコントローラであるPIC18F26J50で、USBブートローダ機能(HID経由)を使う手順等を再整理してみました。
PICkit等のプログラマ(プログラム書込み器)が現場になくとも、本体だけでプログラムの書込みがUSB経由で行う事が出来ますので、気軽にバージョンアップできる様になります。極端な使い方としては、ブートローダが書込まれたデバイスが入手できれば、プログラマを用意する必要が無くなります。
注意点として、下記の制限があります。
・ROMの4KBがブートローダ本体に取られます
・下図の「標準基本回路」が最低限必要になります
・コンフィギュレーションが固定します
Usage example of USB BootLoader - PIC18F26J50
2011年1月9日
<デバイスにUSBブートローダ機能を付加する>
Microchip社から必要なファイルがほとんど提供されているので、手順は次の2つだけです。
(1)ブートローダ本体ソースコードの修正
PIC18F26J50の場合、Microchip社から専用のオブジェクトファイル (HEX型式) までは提供されていない為、一番近いソースコードを選んで修正します。ソースコードを扱いますのでMPLAB等のコンパイル・ビルド環境が整っている事を前提で説明します。PIC18F26J50はPIC18F46J50が同一系列ですので、これ(\Microchip Solutions\USB Device - Bootloaders\HID - Bootloader\HID Bootloader - Firmware for PIC18F46J50 Family Devices)をベースにします。修正する部分は46J50の名前を検索して、名前を26J50に変更するだけなので意外と簡単に出来ます。ビルドして.HEXファイルを作って下さい。PIC18F46J50の.HEXファイルがそのまま使用出来る可能性が高いですが、確認できていません。
私が修正したPIC18F26J50専用のソースコード(*1)は実行確認済で、より部品の少ない「最小回路」でも動くようになっています。PIC18F14K50では内部オシレータをUSBクロックに供給する事が出来ないので外部発振子が必須でしたが、J50では許されているためチップ本体のみでUSBにアクセスできてしまいます。
(*1): MPLABプロジェクトファイル
 最小回路用 HID Bootloader - Firmware for PIC18FxxJ50 SW=RB2.zip (144kB)
 最小回路2用 HID Bootloader - Firmware for PIC18FxxJ50 SW=RA0.zip (144kB)
(2)ブートローダ本体の書込み
用意した.HEXファイルを、PICkit等のプログラム書込み器を使ってデバイスに書込みします。AKI-PIC2であれば、ゼロプレッシャーソケットに差し込んで書込み出来ますが、PICkitでは書込み用の回路(結線だけ)をブレッドボードに作って行う等の作業が要ります。これで、ブートローダ機能が付いているはずです。プログラム書込み器は以後必要ありません。
<ブートローダでアプリケーションを書込む>
(!)デバイス側の準備
書込みスイッチ(ポートRB2)を押しながらUSBケーブルをPCに接続して下さい。これで、ブートローダ機能が有効になり待機状態になっているはずです。外見上の変化ありません。
(2)PC側の操作
Microchip社からWindows用のアプリケーションプログラム(\Microchip Solutions\USB Device - Bootloaders\HID - Bootloader\HIDBootLoader.exe)が提供されていますので、これを実行します。デバイスが認識されていれているメッセージが出ているはずです。見つからないメッセージの場合は、ハードウエアが問題ないか確認して下さい。良ければ、アプリケーションプログラムのオブジェクトファイルを指定し、書込みを指示すれば完了です。リセットボタンかUSBケーブルを差し直すとアプリケーションプログラムが動くはずです。詳しくはPIC18F14K50版を参照して下さい。
<ユーザアプリケーションプログラムをブートローダ対応にする>
ユーザプログラムは、ブートローダを意識した書き方をしなければなりません。Microchip社が提供しているUSB系のサンンプルプログラムをベースに作って行けば、自然に対応したソースコードになりますので、通常はこの方法が楽です。USBを直接使わないケース等では、多少面倒ですが2点を修正する事で対応可能です。
・割込/リセットベクタ値を変更
・リンクパラメタ(リンカースクリプト)をブートローダ用に変更
メインプログラムのソースコードに以下を追加。単にコピペするのではなく、ある程度中身を読み取っておかないと、思わぬトラブルに振り回されるかもしれません。
#define PROGRAMMABLE_WITH_USB_HID_BOOTLOADER
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS0x1000
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS0x1008
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS0x1018
#elif defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
#define REMAPPED_RESET_VECTOR_ADDRESS0x800
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS0x808
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS0x818
#else
#define REMAPPED_RESET_VECTOR_ADDRESS0x00
#define REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS0x08
#define REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS0x18
#endif
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
extern void _startup (void);        // See c018i.c in your C18 compiler dir
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
void _reset (void) {
    _asm goto _startup _endasm
}
#endif
#pragma code REMAPPED_HIGH_INTERRUPT_VECTOR = REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS
void Remapped_High_ISR (void) {
     _asm goto YourHighPriorityISRCode _endasm
}
#pragma code REMAPPED_LOW_INTERRUPT_VECTOR = REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS
void Remapped_Low_ISR (void) {
     _asm goto YourLowPriorityISRCode _endasm
}
#pragma code
#if defined(PROGRAMMABLE_WITH_USB_HID_BOOTLOADER)||defined(PROGRAMMABLE_WITH_USB_MCHPUSB_BOOTLOADER)
#pragma code HIGH_INTERRUPT_VECTOR = 0x08
void High_ISR (void) {
     _asm goto REMAPPED_HIGH_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code LOW_INTERRUPT_VECTOR = 0x18
void Low_ISR (void) {
     _asm goto REMAPPED_LOW_INTERRUPT_VECTOR_ADDRESS _endasm
}
#pragma code
#endif
#pragma interrupt YourHighPriorityISRCode
void YourHighPriorityISRCode() {
// User code
}
#pragma interruptlow YourLowPriorityISRCode
void YourLowPriorityISRCode() {
// User code
}
リンクパラメタはMicrochip社が提供しているブートローダ対応版を使用。
// File: 18f26j50_g.lkr
// Generic linker script for the PIC18F26J50 processor
#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN
LIBPATH .
#IFDEF _CRUNTIME
  #IFDEF _EXTENDEDMODE
    FILES c018i_e.o
    FILES clib_e.lib
    FILES p18f26j50_e.lib
  #ELSE
    FILES c018i.o
    FILES clib.lib
    FILES p18f26j50.lib
  #FI
#FI
#IFDEF _DEBUGCODESTART
  CODEPAGE   NAME=bootloader START=0x0            END=0xFFF          PROTECTED   
  CODEPAGE   NAME=page       START=0x1000         END=_CODEEND
  CODEPAGE   NAME=debug      START=_DEBUGCODESTART   END=_CEND        PROTECTED
#ELSE
  CODEPAGE   NAME=bootloader START=0x0            END=0xFFF          PROTECTED   
  CODEPAGE   NAME=page       START=0x1000               END=0xFFF7
#FI
CODEPAGE   NAME=config     START=0xFFF8            END=0xFFFF         PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED
#IFDEF _EXTENDEDMODE
  DATABANK   NAME=gpre       START=0x0               END=0x5F
#ELSE
  ACCESSBANK NAME=accessram  START=0x0               END=0x5F
#FI
DATABANK   NAME=gpr0       START=0x60              END=0xFF
DATABANK   NAME=gpr1       START=0x100             END=0x1FF
DATABANK   NAME=gpr2       START=0x200             END=0x2FF
DATABANK   NAME=gpr3       START=0x300             END=0x3FF
DATABANK   NAME=gpr4       START=0x400             END=0x4FF
DATABANK   NAME=gpr5       START=0x500             END=0x5FF
DATABANK   NAME=gpr6       START=0x600             END=0x6FF
DATABANK   NAME=gpr7       START=0x700             END=0x7FF
DATABANK   NAME=gpr8       START=0x800             END=0x8FF
DATABANK   NAME=gpr9       START=0x900             END=0x9FF
DATABANK   NAME=gpr10      START=0xA00             END=0xAFF
DATABANK   NAME=gpr11      START=0xB00             END=0xBFF
DATABANK   NAME=gpr12      START=0xC00             END=0xCFF
#IFDEF _DEBUGDATASTART
  DATABANK   NAME=gpr13      START=0xD00             END=_DATAEND
  DATABANK   NAME=dbgspr     START=_DEBUGDATASTART   END=_DEND           PROTECTED
#ELSE //no debug
  DATABANK   NAME=gpr13      START=0xD00             END=0xDFF
#FI
DATABANK   NAME=gpr14      START=0xE00             END=0xEBF
DATABANK   NAME=sfr14      START=0xEC0             END=0xEFF          PROTECTED
DATABANK   NAME=sfr15      START=0xF00             END=0xF5F          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60             END=0xFFF          PROTECTED
SECTION    NAME=USB_VARS   RAM=gpr11
#IFDEF _CRUNTIME
  SECTION    NAME=CONFIG     ROM=config
  #IFDEF _DEBUGDATASTART
    STACK SIZE=0x100 RAM=gpr12
  #ELSE
    STACK SIZE=0x100 RAM=gpr13
  #FI
#FI
より具体的な修正方法は、Microchip社から出ている各種サンプルソースコードをご覧下さい。