しゅうのマイクロマウス研修キット製作研修

番外編 Part7 プログラムの用意3と書き込み! – しゅうのマイクロマウス研修

番外編 Part7 プログラムの用意3と書き込み! - しゅうのマイクロマウス研修 しゅうのマイクロマウス研修

こんにちは、しゅうです。前々回前回までで環境構築やほぼ必要なファイルを用意できました。
いよいよ残すところは、後2つファイルを用意して書き込みを実行する、です。
ということで今回は、main.cとMakefileを用意して、書き込み手順の解説をしていきます。

main.c

今回はLEDを光らせるだけなので、初期化などを含め1つのファイルにまとめます。書き方自体は今までとそこまで変わりません。
まず初めにポートの設定をしておく必要があります。CS+の時はportdef.hで定義していたので、そこからLEDの分をコピーして今回はグローバル変数として定義します。加えて、そのポートを出力に切り替えるためIO_OUT (1)も定義しておきます(これはstatic_parameters.hで定義されていました)。そしてメイン関数に入る前に初期化を行うので、CS+で使っていたinit.cからinit_clockinit_cmt関数を引っ張ってきます。さらにもう1つ割り込み関数として、LEDのOn/Offをするためのint_cmt関数を用意します。そしてmain関数でポートの設定をしたり初期化の関数を呼び出したりします。
文字で書くとプログラムは以上ですがイメージしづらいと思うので、今回は書き出しちゃいます。

#include "iodefine.h"

#define LED3 (PORTA.PODR.BIT.B0)
#define LED2 (PORTA.PODR.BIT.B4)
#define LED1 (PORTA.PODR.BIT.B6)
#define LED0 (PORTB.PODR.BIT.B0)
#define IO_OUT (1)

void init_clock(void){
	SYSTEM.PRCR.WORD = 0xa50b;
	SYSTEM.PRCR.WORD = 0xa50b;

	SYSTEM.PLLCR.WORD = 0x0F00;		/* PLL 12.000MHz * 16 = 192MHz*/
	SYSTEM.PLLWTCR.BYTE = 0x0F;		/* 4194304cycle(Default) */
	SYSTEM.PLLCR2.BYTE = 0x00;		/* PLL ENABLE */
	// ICK   : 192/2 = 96MHz 		//CPU DMAC DTC ROM RAM
	// PCLKA : 192/2 = 96MHz 		//etc
	// PCLKB : 192/4 = 48MHz 		//PCLKB=PCLK
	SYSTEM.SCKCR.LONG = 0x21C21211;	//FCK1/4 ICK1/2 BCLK??~ SDCLK??~ BCK1/4 PCLKA1/2 PCLKB1/4
	SYSTEM.SCKCR2.WORD = 0x0032;		/* UCLK1/4 IEBCK1/4 */
	SYSTEM.BCKCR.BYTE = 0x01;		/* BCLK = 1/2 */	
	SYSTEM.SCKCR3.WORD = 0x0400;
}

void init_cmt(void){
	SYSTEM.PRCR.WORD = 0xA502;
	MSTP(CMT0) = 0;
	SYSTEM.PRCR.WORD = 0xA500;		
	
	CMT0.CMCR.BIT.CKS=1;	// PCLK/32 1.5MHz
	CMT0.CMCR.BIT.CMIE=1;
	CMT0.CMCNT=0;
	CMT0.CMCOR=1500-1;	//1kHz
	IEN(CMT0,CMI0) = 1;
	IPR(CMT0,CMI0) = 15;
	IR(CMT0,CMI0)=0;

	CMT.CMSTR0.BIT.STR0=1;
}

void int_cmt(void){
	static short i=0;
	if(i==1000){
		LED3=1;
		LED0=LED1=LED2=0;
	}else if(i==2000){
		LED2=1;
		LED0=LED1=LED3=0;
	}else if(i==3000){
		LED1=1;
		LED0=LED2=LED3=0;
	}else if(i==4000){
		LED0=1;
		LED1=LED2=LED3=0;
		i=0;
	}
	i++;
}

int main(void){
	init_clock();
	PORTA.PDR.BIT.B0 = IO_OUT; //LED3
	PORTA.PDR.BIT.B4 = IO_OUT; //LED2
	PORTA.PDR.BIT.B6 = IO_OUT; //LED1
	PORTB.PDR.BIT.B0 = IO_OUT; //LED0
	init_cmt();

	while(1){
	}
    
	return 0;
}

これでmain関数は出来上がりです。次はmakefileを作っていきます。

makefile

makefileの書き方は基本的に

作りたいファイル:入力するファイル
-TAB-作り方

という構造になります。CS+の時はボタン1つで書き込むための.motファイルを生成してくれましたが、今回は上の構造を使いながら1個ずつ記載していく感じになります。ちなみに基本的に上から順番に実行が行われますが、既にmakeを実行して「作りたいファイル」が既にある場合、「入力するファイル」の最終更新日が「作りたいファイル」よりも後だった時のみ実行されるようになります。なかなか賢いですね。
基本構造以外には作り方や入力ファイルがないような構造もあります。よくみる、ビルドしたものを一旦消すコマンドのmake cleanなんかは次のように記述されています。

clean:
-TAB-rm -rf <makeしたときに生成されたファイルやディレクトリ>

ここでは、入力するファイルが指定されていないのでそのまま作り方、すなわちコマンドの部分が実行されます。
後は、初めにmakeでビルドしたいファイルやビルドに用いるライブラリなどを指定していきます。今回は次のようにかけます(詳しいことはmakefileの書き方!などの記事を参照してください)。

TARGET = PiCoClassic3
DEVICE = R5F5631M
BUILD = build
VPATH = ../
ASOURCES = start.s
CSOURCES = main.c \
		intprg.c \
		vecttbl.c
LDSCRIPT = $(DEVICE).ld
USER_DEFS = SIG_RX631 F_ICLK=96000000 F_PCLKA=96000000 F_PCLKB=48000000 F_FCLK=48000000 F_BCLK=96000000
WRITER = rx_prog
INC_APP = . ../ include
OPTIMIZE = -O0
CP_OPT = -Wall -Werror \
	-Wno-unused-variable \
	-Wno-unused-function \
	-fno-exceptions \
	-fno-rtti
CC_OPT = -Wall -Werror \
	-Wno-unused-variable \
	-fno-exceptions

SYSINCS = $(addprefix -I, $(INC_SYS))
APPINCS = $(addprefix -I, $(INC_APP))
AINCS = $(SYSINCS) $(APPINCS)
CINCS = $(SYSINCS) $(APPINCS)
PINCS = $(SYSINCS) $(APPINCS)
LIBINCS = $(addprefix -L, $(LIB_ROOT))
DEFS = $(addprefix -D, $(USER_DEFS))
LIBS = $(addprefix -l, $(USER_LIBS))

#You should not have to change anything here
AS = rx-elf-as
CC = rx-elf-gcc
CP = rx-elf-g++
AR = rx-elf-ar
LD = rx-elf-ld
OBJCOPY = rx-elf-objcopy
OBJDUMP = rx-elf-objdump
SIZE = rx-elf-size

ALL_ASFLAGS = $(AFLAGS) $(MCU_TARGET) $(DEFS)
CFLAGS = -std=gnu99 $(CC_OPT) $(OPTIMIZE) $(MCU_TARGET) $(DEFS)
PFLAGS = -std=c++14 $(CP_OPT) $(OPTIMIZE) $(MCU_TARGET) $(DEFS)
override LDFLAGS = $(MCU_TARGET) -nostartfiles -Wl, -Map, $(TARGET).map -T $(LDSCRIPT)

OBJCOPY_OPT = --srec-forceS3 --srec-len 32
OBJECTS = $(addprefix $(BUILD)/,$(patsubst %.s,%.o,$(ASOURCES))) \
	$(addprefix $(BUILD)/,$(patsubst %.c,%.o,$(CSOURCES))) \
	$(addprefix $(BUILD)/,$(patsubst %.cpp,%.o,$(PSOURCES)))
DEPENDS = $(patsubst %.o,%.d, $(OBJECTS))

.PHONY: all clean
.SUFFIXES: .rc .hpp .h .s .c .cpp .o

all: $(BUILD) $(TARGET).elf text

$(TARGET).elf: $(OBJECTS) $(LDSCRIPT) Makefile
	$(CC) $(LDFLAGS) $(LIBINCS) -o $@ $(OBJECTS) $(LIBS)
	$(SIZE) $@

$(BUILD)/%.o: %.s
	mkdir -p $(dir $@); \
	$(AS) -c $(AOPT) $(AFLAGS) $(AINCS) -o $@ $<

$(BUILD)/%.o: %.c
	mkdir -p $(dir $@); \
	$(CC) -c $(COPT) $(CFLAGS) $(CINCS) $(CCWARN) -o $@ $<

$(BUILD)/%.o: %.cpp
	mkdir -p $(dir $@); \
	$(CP) -c $(POPT) $(PFLAGS) $(PINCS) $(CPWARN) -o $@ $<

$(BUILD)/%.d: %.cpp
	mkdir -p $(dir $@); \
	$(CC) -MM -DDEPEND_ESCAPE $(COPT) $(CFLAGS) $(APPINCS) $< \
	| sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
	[ -s $@ ] || rm -f $@

$(BUILD)/%.d: %.cpp
	mkdir -p $(dir $@); \
	$(CP) -MM -DDEPEND_ESCAPE $(POPT) $(PFLAGS) $(APPINCS) $< \
	| sed 's/$(notdir $*)\.o:/$(subst /,\/,$(patsubst %.d,%.o,$@) $@):/' > $@ ; \
	[ -s $@ ] || rm -f $@

text: mot lst
bin: $(TARGET).bin
mot: $(TARGET).mot
lst: $(TARGET).lst

%.lst: %.elf
	$(OBJDUMP) -h -S $< > $@

%.mot: %.elf
	$(OBJCOPY) $(OBJCOPY_OPT) -O srec $< $@

%.bin: %.elf
	$(OBJCOPY) -O binary $< $@

clean:
	rm -rf $(BUILD) $(TARGET).elf $(TARGET).mot $(TARGET).lst $(TARGET).map

保存したら、あとはmakeを実行するだけで.motファイルなどが生成されます。残すはPi:Coに書き込むだけです!

書き込み

ハードウェア側の書き込み手順はCS+の時と同じです。CPUボードのモードスイッチをFWの方に切り替えてから電源を入れて、こちらの記事でご紹介したようにパソコンとUSB-serialモジュールとPi:Coを接続しましょう。次はソフト側に移ります。
ターミナルで、makeをしたディレクトリにいるようにしましょう(.motファイルが生成されたところです。)。そこでこちらの記事でご紹介したrx_progを使います。次のように実行しましょう。僕の場合、は/dev/tty.usbserial-DM01OYUOです。

$ rx_prog --verbose --progress --port= --speed=57600 --device=RX631 --write PiCoClassic3.mot

これで書き込みができる!と思ったらエラーが返って来ちゃいました。
エラー
でも安心してください、CPUボードのリセットボタンを押してからもう一度実行して見てください。すると、Connection OK.と表示されて書き込みが始まります。次のように表示されて再度コマンドが打てるようになれば完了です。
コマンドが打てる状態

それでは、Pi:Coの電源を切って、CPUボードのモードスイッチをRUNに切り替えてからもう一度電源を入れると、LEDが順番に光ります。
LEDが順番に光る

まとめ

長い道のりでしたが、これでMacからでも開発ができるようになりました!早速、今までのプログラムを盛り込んでmakeして見たりしたのですが、まだ不具合がちらほらあるみたいです。
迷路解析までは、もう少し時間がかかりそうです・・・でも無事できるようになったらまた情報をまとめたり、コードなどを公開していきたいなって考えています♪

タイトルとURLをコピーしました