FrontPage

2009/05/20 からのアクセス回数 11338

サンプルプログラム

組み込みソフトで最初のプログラムは、いつもLEDの点滅です。 Interface 2009/5月号では、LEDの点滅プログラムに割り込みを使っていましたが、 これは大きなルール違反です。

最初のプログラムは、できるだけシンプルにし、最低限の設定にしないとうまく動かなかった 時に、原因の切り分けが難しくなります。

今回のプログラムは、 nandさんのテストプログラム を参考に、Olimex のサイトにあった LED を点滅させるプログラムから、crt0.S, リンクコマンドファイル を修正し、必要最低限にカットしました。

Eclipseプロジェクトの作成

最初に、Eclipseに組み込み用Cのプロジェクトを作成します。 File->New->C Project...を選択するか、図の用に右クリックでC Project...を選択します。

eclipse-1.jpg

次にProjectnmae:にプロジェクト名を入力します。ここでは、sam7s-t0としました。 Project type:として、Makefile projectのEmpty Projectを選択し、-- Other Toolchain --を選択して Finishボタンを押します。

eclipse-2.jpg

プロジェクトができたら、filesrc.zipを解凍し、srcフォルダ以下のファイルをプロジェクトにドラッグします。

ファイルの説明

srcディレクトリには、以下のファイルが含まれています。

main.c

main.cは、非常にシンプルです。 PIO_PER, PIO_OERを設定し、2個のLEDを交互に点滅するために、PIO_CODR, PIO_SODRを設定し、 delayで時間間隔をとります。

#include "AT91SAM7S64.h"

#define	DELAY_COUNT	5769	// for 18.432MHz (original 6000000 for 48MHz)
void delay(int n);

int main() {
	AT91C_BASE_PIOA->PIO_PER = (1 << 17) | (1 << 18);
	AT91C_BASE_PIOA->PIO_OER = (1 << 17) | (1 << 18);

	for (;;) {
		AT91C_BASE_PIOA->PIO_CODR = (1 << 18);
		AT91C_BASE_PIOA->PIO_SODR = (1 << 17);
		delay(DELAY_COUNT);
		AT91C_BASE_PIOA->PIO_SODR = (1 << 18);
		AT91C_BASE_PIOA->PIO_CODR = (1 << 17);
		delay(DELAY_COUNT);
	}
}

void delay(int n) {
	while (--n)
		;
}

Makefile

Makefileは、デフォルトのルールを使って、オブジェクトファイルまでコンパイルを行い、最後の allで、ELFファイル(main.out)、バイナリファイル(main.bin)を作成します。

CC = /opt/local/bin/arm-elf-gcc
AS = /opt/local/bin/arm-elf-as
LD = /opt/local/bin/arm-elf-ld -v
CP = /opt/local/bin/arm-elf-objcopy
OD = /opt/local/bin/arm-elf-objdump

CFLAGS	= -march=armv4t -mthumb -g
ASFLAGS = -Wa,-mthumb
LFLAGS	= -Map main.map -Tsam7s_ram.cmd

OBJECTS	= crt0.o main.o

all: crt0.o main.o
	$(LD)  $(LFLAGS) -o main.out -Map main.map $(OBJECTS)
	$(CP) -j .text -j .data -O binary main.out main.bin
	$(OD) -x --syms main.out > main.dmp

main.o: main.c

crt0.o: crt0.S

clean:
	rm -f $(OBJECTS) main.out main.bin main.map main.dmp

crt0.S, sam7s_ram.cmd

crt0.S, sam7s_ram.cmdは、長いのと私のフォロー範囲を超えているので、 修正したポイントだけを説明します。

crt0.Sでは、

をします。

割り込みベクトルの設定は以下のように定義しています。

/* identify all GLOBAL symbols  */
.global _vec_reset
.global _vec_undef
.global _vec_swi
.global _vec_pabt
.global _vec_dabt
.global _vec_rsv
.global _vec_irq
.global _vec_fiq
.global AT91F_Irq_Handler
.global	AT91F_Default_FIQ_handler
.global	AT91F_Default_IRQ_handler

グローバル変数のRAM領域へのコピーは、_init_reset:の

		/* copy initialized variables .data section  (Copy from ROM to RAM) */
                ldr     R1, =_etext
                ldr     R2, =_data
                ldr     R3, =_edata
1:        		cmp     R2, R3
                ldrlo   R0, [R1], #4
                strlo   R0, [R2], #4
                blo     1b

のように定義しています。

sam7s_ram.cmdは、リンク用のコマンドで、MEMORY定義と_stack_endの 部分を修正しました。

/* specify the AT91SAM7S64  memory areas  */
MEMORY 
{
	flash	: ORIGIN = 0,          LENGTH = 256K	/* FLASH EPROM		*/	
	ram		: ORIGIN = 0x00200000, LENGTH = 64K  	/* static RAM area	*/
}

/* define a global symbol _stack_end  (see analysis in annotation above) */
_stack_end = 0x0000FFFC;

makeとデバッグ

通常は、EclipseのMakeを使うのですが、その都度設定するのは面倒なので、ターミナルから makeとopenocdの起動を行います。

make

ターミナルを起動し、プロジェクトのディレクトリに移動します。

$ cd ~/local/workspace/sam7s-t0
$ make

エラーがなければ、これでmakeは完了です。

デバッグ設定

次にEclipseでデバッガの設定をします。

RunメニューからDebug Configurations...を選択すると図のような設定画面が表示されます。

debug-1.jpg

次にDebuggerタグを選択します。

debug-2.jpg

最後にCommandsタグを選択します。

通常は、最後に

load

をしていするのですが、USB Blasterのドライバーがわるいのか、途中でエラーになってしまいますので、

#でコメントアウトしています。

これで、Closeを選択して設定を保存します。

Openocdの起動とデバッグ

openocd.cfgとして今回は、以下のようの内容を設定します。

#define our ports
telnet_port 4444
gdb_port 3333

#commands specific to the USB Blaster
interface usb_blaster
usb_blaster_vid_pid 0x09fb 0x6001

#reset_config <signals> [combination] [trst_type] [srst_type]
reset_config srst_only srst_pulls_trst

#jtag_device <IR length> <IR capture> <IR mask> <IDCODE instruction>
jtag_device 4 0x1 0xf 0xe

#daemon_startup <'attach'|'reset'>
daemon_startup reset

#target <type> <endianess> <reset_mode> <jtag#> [variant]
target arm7tdmi little run_and_init 0 arm7tdmi_r4

#working_area <target#> <address> <size> <'backup'|'nobackup'> 
working_area 0 0x00200000 0x4000 nobackup

#run_and_halt_time <target#> <time_in_ms>
run_and_halt_time 0 30

ターミナルからopenocdを起動します、以下のようにデバイスを認識すればOKです。

$ openocd -f openocd.cfg
Open On-Chip Debugger 1.0 (2009-04-13-07:33) svn:753M
$URL: svn://svn.berlios.de/openocd/trunk/src/openocd.c $
Info:    options.c:50 configuration_output_handler(): Open On-Chip Debugger 1.0 (2009-04-13-07:33) svn:753M
Info:    jtag.c:1403 jtag_examine_chain(): JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)

loadがデバッグ設定でできなかったので、手動でプログラムをロードします。 別のターミナルで

と、少し時間がかかりますが、以下のように出力されます。

term-2 $  telnet localhost 4444
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying fe80::1...
telnet: connect to address fe80::1: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
> load_image main.out
388 byte written at address 0x00200000
downloaded 388 byte in 22.681808s
> 

最後にEclipseのDebugを実行します。

指定したブレークポイントで止まればOKです。USB Blasterのドライバーとても遅く、1分ほどかかります。

ステップ実行もとても遅いですが、プログラムが期待通りに動かなかった最後の砦として、 デバッガは有効です。

debug-4.jpg

ROMへの書き込み

このままでは、電源を切るとプログラムが消えてしまいますので、ROMへの書き込みを行います。 では、なぜRAMに書き込んでいたのでしょう。

RAMのメリットは、

RAMの欠点は

makeの変更

話を先にすすめて、makeの設定を変更します。

Makefileをコピーして、以下の設定を変更します

LFLAGS	= -Map main.map -Tsam7s_ram.cmd

LFLAGS	= -Map main.map -Tsam7s_rom.cmd

にします。

さらに、以下のファイルを追加します。

ここで、script.ocdのFlushへの書き込みコマンドは、openocdのバージョンに よって異なります。ご使用のバージョンに合わせて変更してください。 今回は、flash write_bank を使用しました。

# flash write 0 main.bin 0x0
# flash write is deprecated and my not be available in your OpenOCD-version, update to: 
# flash write_binary 0 main.bin 0x0
# flash write_binary is deprecated and my not be available in your OpenOCD-version, update to:
flash write_bank 0 main.bin 0x0

makeと書き込み

準備ができたので、ターミナルから以下のコマンドを実行します。

$ make clean
$ make -f Makefile.rom
$ openocd -f openocd-rom.cfg 

書き込みが終わったら、JTAGライターをケーブルを外して、ボードの電源を入れ直してください。 LEDが点滅すれば成功です。

ROM版のデバッグ

デバッグ設定は、RAMとROMで若干ことなります。

では、ターミナルでopenocdを起動して、

$ openocd -f openocd.cfg 

デバッグ対象として、sam7s-t0-romを選択します。

しかし、RAMと同様におそいながらも、デバッグできます。

board.jpg

コメント

この記事は、

選択肢 投票
おもしろかった 1  
そうでもない 0  
わかりずらい 0  

皆様のご意見、ご希望をお待ちしております。


(Input image string)

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc