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;

コメント

この記事は、

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

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


(Input image string)

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