Linux上でH8/36064の開発をする †準備 †これひとつでビルドできます.(というかできるようにしました) ただし,ビルド時間を少しでも短縮するために,h8300s,h8300sx向けのgcc,newlibは向こうにしてあります.詳しくは,patchesフォルダ内のgcc-4.4.6.patchをご覧ください. シリアル経由の書き込みには,Open SH/H8 writerが便利です. Open SH/H8 writerは,ソースコードを適当な作業フォルダにダウンロードして,
のように,出てきたバイナリを/usr/local/binの中に突っ込んでおくと,どのディレクトリからも呼び出せるので便利です.(汚したくないという方は適当に/opt/toolsとかそのあたりにディレクトリを掘ってパスを通してください.) Ubuntuの場合 †ターミナルを開いて,
で,必要なパッケージ類をインストールします.
makeします.
ビルドには2時間ほどかかります.installまで終わったら準備完了です. ビルドしたツールチェインは,/opt/cross/h8300-elf-x-tools/ 以下のディレクトリに配置されます. H8/36064向け開発の手引き †H8/36064は,H8/300HTinyシリーズのマイコンです. 適切なコンフィギュレーションでもってビルドしないとバグります. h8300-toolchain-builderでは,h8300,h8300h向けのgcc(コンパイラ群)とnewlib(標準Cライブラリ)をビルドしています. また,h8300,h8300hそれぞれに対して,デフォルトモード,int32モード(intを16bitではなく32bitとして処理するモード),normalモード(後述),normalモードでのint32モードの4種類のコンフィギュレーションが用意されています. H8/36064では,h8300hのnormalモードを使用します. このコンフィギュレーションは,
をフラグとしてgccに与えることで指定できます. その他細かい部分の設定は必要ですが,最も重要なのはこの項目です. 特に-mnを忘れると,マイコンとして動作はするものの一部機能だけがバグるといった厄介な現象が発生するため,忘れないようにしましょう. その他の項目については,サンプルのMakefileを用意したので,こちらをご覧ください. リンカスクリプト †OUTPUT_FORMAT("elf32-h8300")
OUTPUT_ARCH(h8300hn)
ENTRY("_start")
MEMORY
{
vectors : o = 0x0000, l = 0x0042
rom : o = 0x0042, l = 0x7fbe
ram : o = 0xf780, l = 0x0400
stack : o = 0xff80, l = 0x0000
}
SECTIONS
{
.vectors : {
/* 0x0000 */
SHORT(ABSOLUTE(_start)) /* 0(0x0000): _startの絶対アドレスをShortにして渡す*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 1(0x0002): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 2(0x0004): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 3(0x0006): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 4(0x0008): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 5(0x000A): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /* 6(0x000C): システム予約*/
SHORT(ABSOLUTE(_INT_NMI)) /* 7(0x000E): NMI*/
/* 0x0010 */
SHORT(ABSOLUTE(_INT_TRAP0)) /* 8(0x0010): CPU トラップ命令 #0*/
SHORT(ABSOLUTE(_INT_TRAP1)) /* 9(0x0012): CPU トラップ命令 #1*/
SHORT(ABSOLUTE(_INT_TRAP2)) /*10(0x0014): CPU トラップ命令 #2*/
SHORT(ABSOLUTE(_INT_TRAP3)) /*11(0x0016): CPU トラップ命令 #3*/
SHORT(ABSOLUTE(_INT_ABRK)) /*12(0x0018): アドレスブレーク ブレーク条件成立 */
SHORT(ABSOLUTE(_INT_SLEEP)) /*13(0x001A): CPU スリープ命令の実行による直接遷移*/
SHORT(ABSOLUTE(_INT_IRQ0)) /*14(0x001C): 外部割り込み端子 IRQ0 低電圧検出割り込み*/
SHORT(ABSOLUTE(_INT_IRQ1)) /*15(0x001E): 外部割り込み端子 IRQ1*/
/* 0x0020 */
SHORT(ABSOLUTE(_INT_IRQ2)) /*16(0x0020): 外部割り込み端子 IRQ2*/
SHORT(ABSOLUTE(_INT_IRQ3)) /*17(0x0022): 外部割り込み端子 IRQ3*/
SHORT(ABSOLUTE(_INT_WKP)) /*18(0x0024): 外部割り込み端子 WKP*/
SHORT(ABSOLUTE(_INT_Dummy)) /*19(0x0026): システム予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /*20(0x0028): 予約*/
SHORT(ABSOLUTE(_INT_Dummy)) /*21(0x002A):*/
SHORT(ABSOLUTE(_INT_TimerV)) /*22(0x002C): タイマV*/
SHORT(ABSOLUTE(_INT_SCI3)) /*23(0x002E): SCI3*/
/* 0x0030 */
SHORT(ABSOLUTE(_INT_IIC2)) /*24(0x0030): IIC2*/
SHORT(ABSOLUTE(_INT_ADI)) /*25(0x0032): A/D変換終了*/
SHORT(ABSOLUTE(_INT_TimerZ0)) /*26(0x0034): タイマZ*/
SHORT(ABSOLUTE(_INT_TimerZ1)) /*27(0x0036): Z*/
SHORT(ABSOLUTE(_INT_Dummy)) /*28(0x0038):*/
SHORT(ABSOLUTE(_INT_TimerB1)) /*29(0x003A): タイマB*/
SHORT(ABSOLUTE(_INT_Dummy)) /*30(0x003C):*/
SHORT(ABSOLUTE(_INT_Dummy)) /*31(0x003E):*/
/* 0x0040 */
SHORT(ABSOLUTE(_INT_SCI3_2)) /*32(0x0040): SCI3_2*/
} > vectors
.text 0x0042 : {
___text = . ;
*(.text)
_etext = . ;
} > rom
.rodata : {
___rodata = . ;
*(.strings)
*(.rodata)
*(.rodata.*)
_erodata = . ;
} > rom
.data : AT ( _erodata ){
___data = . ;
*(.data)
*(.tiny)
_edata = .;
} > ram
.bss : AT ( LOADADDR(.data) + SIZEOF(.data) ) {
_bss_start = . ;
*(.bss)
*(COMMON)
_end = . ;
} >ram
.stack : {
_stack = . ;
*(.stack)
} > stack
.stab 0 (NOLOAD) : {
[ .stab ]
}
.stabstr 0 (NOLOAD) : {
[ .stabstr ]
}
}
スタートアップファイル †
Renesasの開発環境からのコードの移植 †Renesasが用意しているHEWなどの開発環境からコードを移植する際は,組み込み関数に注意する必要があります. 組み込み関数とは,マイコンの低レベルなレイヤー(よりダイレクトにいじるレイヤー)に対して提供される関数群のことを指します. 例えば,H8の開発でよく用いるset_imask_ccr(int)関数がこれに該当します. Renesasのツールチェインでは,これらの関数はすでに定義されているのですが,gccを自分でビルドした場合は定義されていないため,そのまま使用することはできません. したがって,自分で定義する必要があります. Renesasのツールチェインでは,組み込み関数はmachine.hに定義されています. このmachine.hをそのまま再利用できる形で進めて行きましょう. HEWデフォルトで生成するコードから呼ばれるのは,set_imask_ccr(int)関数と,_builtin_sleep()関数のみですので,この2つについて処理を記述することとします. machine.hに以下の関数の定義をコメントアウトし,次の記述を追加すればよいでしょう.
あまりdefineマクロは使いたくないのですが・・・ |