自作電子小物/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社から出ている各種サンプルソースコードをご覧下さい。