オフラインでGCCを使ったmbed開発環境を作る。(第二版)
mbedって何ぞや?
NXP LPC1768のARMのMPUにブレッドボードで使いやすい足が生えて簡単にファームウェアを焼くことができるUSBクライアントポートがついたお手軽マイコン。
ADC/CAN/DAC/イーサネット/DMA/外部割込み/GPIO/I2C/I2S/PWM/RTC/SPI/SSP/UART/WDT/USBホスト/USBクライアントなど機能が盛りだくさん。
ただしハードウエアDSPは持ってません。(乗算除算のみ)
しかし、このmbedはWeb上からコンパイルを行うためにネット環境がなかったりPCのスペックやブラウザのバージョンが低かったりすると色々と問題なのでオフラインでエディタかIDEとmakeで開発したい…。
というときのための私的なメモです。
ちなみにこの開発環境はLPC1769の乗ったLPCXpressoにも対応してたりします。というかまんま上位互換です。
必要なソフトウエア
- コンパイラ: Sourcery G++ Lite for ARM EABI
- http://www.codesourcery.com/sgpp/lite/arm
- arm-2010q1-188-arm-none-eabi.exe以前を推奨、これより新しいコンパイラはlibcs3ライブラリが欠損してNXP謹製のリンカスクリプトでは正常にコンパイルできません。
- CMSIS: LPC175x and LPC176x CMSIS-Compliant Standard Peripheral Firmware Driver Library (GNU, Keil, IAR)
- http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1769
- lpc17xx.cmsis.driver.library.zip
CMSISから必要なファイルを抽出、そして修正を行う。
- \lpc17xx.cmsis.driver.library\Core\CM3\CoreSupport から
- core_cm3.c
- core_cm3.h
- core_cmFunc.h
- core_cmInstr.h
- \lpc17xx.cmsis.driver.library\Core\CM3\DeviceSupport\NXP\LPC17xx から
- LPC17xx.h
- system_LPC17xx.c
- system_LPC17xx.h
- \lpc17xx.cmsis.driver.library\Core\CM3\DeviceSupport\NXP\LPC17xx\startup\gcc から
- startup_LPC17xx.s
- \lpc17xx.cmsis.driver.library\makesection\makerule\example から
- ldscript_rom_gnu.ld
以上のファイルをひとつのフォルダに設置してください。
Makefileを作る。
# Project Name PROJECT=mbed_test # List of the objects files to be compiled/assembled OBJECTS=startup_LPC17xx.o core_cm3.o system_LPC17xx.o $(PROJECT).o LSCRIPT=ldscript_rom_gnu.ld OPTIMIZATION = s -fno-schedule-insns2 -fsection-anchors -fpromote-loop-indices -ffunction-sections -fdata-sections #DEBUG = -g # Compiler Options GCFLAGS = -Wall -mcpu=cortex-m3 -mfloat-abi=softfp -mthumb -mfix-cortex-m3-ldrd -O$(OPTIMIZATION) $(DEBUG) GCFLAGS += -D__RAM_MODE__=0 LDFLAGS = -mcpu=cortex-m3 -mfloat-abi=softfp -mthumb -mfix-cortex-m3-ldrd -O$(OPTIMIZATION) -Wl,-Map=$(PROJECT).map -T$(LSCRIPT) ASFLAGS = -mcpu=cortex-m3 --defsym RAM_MODE=0 # Compiler/Assembler/Linker Paths GCC = arm-none-eabi-gcc AS = arm-none-eabi-as LD = arm-none-eabi-ld OBJCOPY = arm-none-eabi-objcopy OBJDUMP = arm-none-eabi-objdump REMOVE = rm -f SIZE = arm-none-eabi-size ######################################################################### all:: $(PROJECT).hex $(PROJECT).bin $(PROJECT).lss $(PROJECT).lss: $(PROJECT).elf $(OBJDUMP) -h -S $(PROJECT).elf > $(PROJECT).lss $(PROJECT).bin: $(PROJECT).elf $(OBJCOPY) -O binary -j .text -j .data $(PROJECT).elf $(PROJECT).bin $(PROJECT).hex: $(PROJECT).elf $(OBJCOPY) -R .stack -O ihex $(PROJECT).elf $(PROJECT).hex $(PROJECT).elf: $(OBJECTS) $(GCC) $(LDFLAGS) $(OBJECTS) -o $(PROJECT).elf stats: $(PROJECT).elf $(SIZE) $(PROJECT).elf clean: $(REMOVE) $(OBJECTS) $(REMOVE) $(PROJECT).bin $(REMOVE) $(PROJECT).elf $(REMOVE) $(PROJECT).hex $(REMOVE) $(PROJECT).lss $(REMOVE) $(PROJECT).map ######################################################################### # Default rules to compile .c and .cpp file to .o # and assemble .s files to .o .c.o : $(GCC) $(GCFLAGS) -c $< .cpp.o : $(GCC) $(GCFLAGS) -c $< .S.o : $(AS) $(ASFLAGS) -o $@ $< #########################################################################
上記をコピーアンドペーストしてMakefileを作成してください。
最後に
あとはMakefileのPROJECTで指定した名前のソースファイル、ここではmbed_test.cppを作成し、
#include "LPC17xx.h" volatile unsigned long tick; extern "C" { void SysTick_Handler(void) { tick++; // 1ms Tick... } } int main(void) { SysTick_Config(SystemCoreClock/1000 - 1); /* ... */ return 0; }
ではじめることができます。
気を付けなければならないことは拡張子がcppつまり、C++でコンパイルした場合において割り込みハンドラはC言語による関数宣言をしておかないと呼出規約のせいかスタックの取り方がちがうのか正常に動作にしません。
あと、ペリフェラルのライブラリは
- \lpc17xx.cmsis.driver.library\Drivers
にありますので適宜インクルードしてコードをOBJECTSに追加してください。あとはMakeすればコンパイルできるはず。
予断ですが、CodeSourceryのコンパイラのlibcはnewlibを使っているみたいですね。組み込みでまともなstdio.hとstrings.hが手に入るのは強力だと思います。
devkitpro環境を作るために必死でパッチをあてbinutils,gcc,newlibをコンパイルした時代と比べれば楽な世の中になりましたね。
mbed.hなどは
とかでソースがダウンロードはできるもののARM謹製のコンパイラでlibcなどのシステムコールの実装が大きく違っているので流用できません。