어제 도착한 Maple r5 보드에 ChibiOS를 올려보았습니다. 참고한 자료는 아래 링크입니다.
http://wiki.leaflabs.com/index.php?title=Running_ChibiOS_on_the_Maple_r5
정보 공유차원에서 번역해 올려봅니다.
따라해보기: Maple r5에 ChibiOS를 올려보자.
이는 처음 해보는 것이고, 확정판은 아니다. OS X를 사용했다. (역주: Windows 7에서도 잘 되었다.) 윈도우즈 환경을 기준으로 어떻게 컴파일하고 만들어 올리는지는 이 페이지의 마지막 부분에 설명해 놓았다.
— 중략: ChibiOS 개략 설명 —-
ChibiOS는 이미 ARM Cortex-M3 아키텍쳐를 완전히 지원한다. 따라서, 나는 Maple r5에 ChibiOS를 올리기 위해 그저 보드의 정의를 추가하고 몇몇 파일을 수정한 것 밖에 없다.
하드웨어
나는 어떻게 ChibiOS를 Maple 부트로더와 함께 사용할 수 있는지를 알아내지 못했다. 나는 아두이노 Duemilanove 보드를 하드웨어 프로그래머로 이용하였다. (이때, ATmega328는 제거한다)
- ATmega 제거.
- GND 와 3v3를 Maple의 GND 와 Vin에 연결.
- 아두이노 보드 시리얼 포트 연결: 0 (RX) 와 1 (TX) 를 Maple 보드의 시리얼: 8 (RX1) 과 7 (TX1)에 연결. 그렇다 , RX 는 RX로 연결하고 TX는 TX로 연결한다.
- 아두이노 보드의 USB를 컴퓨터로 연결.
이상이다!!
소프트웨어
- 이 글을 쓰는 최신 버젼의 ChibiOS 2.2 안정판을 다운받는다.
- OSX용 크로스 컴파일러를 다운받아 설치한다. (http://static.leaflabs.com/pub/codesourcery/gcc-arm-none-eabi-latest-osx32.tar.gz) (역주: 필자는 YAGARTO 툴체인을 사용했다.)
- 시험적으로 ChibiOS 폴더에서 일단 빌드를 실행해 본다. ./demos/ARMCM3-STM32F103/ 에서 ‘make’ 실행. 모든 빌드가 끝나고 나면 OLIMEX_STM32_P103 폴더에 bin 파일을 볼 수 있을 것이다. 이제 Maple r5 사용을 위해 보드의 설정을 좀 바꿔 볼 것이다.
- OLIMEX_STM32_P103 폴더 (./boards/OLIMEX_STM32_P103)를 LEAFLABS_STM32_F103_R5 (./boards/LEAFLABS_STM32_F103_R5) 라는 이름으로 복사한다.
- board.h 열어서, “IO pins assignments” 이라는 부분을 바꿔준다.
#define VAL_GPIOACRL 0x88884B84 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888888 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFF
를 아래와 같이 바꾼다.
#define VAL_GPIOACRL 0x88384B88 /* PA7...PA0 */ #define VAL_GPIOACRH 0x888884B8 /* PA15...PA8 */ #define VAL_GPIOAODR 0xFFFFFFFF
그리고 Port A의 설명 부분도 아래와 같이 바꾼다.
* Port A setup. * Everything input with pull-up except: * PA2 - Alternate output (USART2 TX). * PA3 - Normal input (USART2 RX). * PA5 - Push Pull output (LED). * PA9 - Alternate output (USART1 TX). * PA10 - Normal input (USART1 RX).
- board.h 안의 내용도
/* * Board identifier. */ #define BOARD_OLIMEX_STM32_P103 #define BOARD_NAME "Olimex STM32-P103"
를 아래와 같이 바꾼다.
#define LEAFLABS_STM32_F103_R5 #define BOARD_NAME "LeafLabs Maple r5"
일단 간단하게 테스트 하기 위해 LED를 깜빡이게 할 것이다. 그래서 다른 포트의 설정을 바꾸지 않을 것이다. 회로도를 보고 Maple r5용으로 완전한 보드 정의를 해야 한다. 당신의 번젼을 올려주면 수정하겠다.
이제 board.mk 파일을 연다. 그리고 아래와 같이 바꾼다.
# List of all the board related files. BOARDSRC = ${CHIBIOS}/boards/LEAFLABS_STM32_F103_R5/board.c # Required include directories BOARDINC = ${CHIBIOS}/boards/LEAFLABS_STM32_F103_R5
- ./demos/ARMCM3-STM32F103 폴더로 가서 ‘make clean’ 을 수행한다.
- mcuconf.h 파일을 열서 다음과 같이 바꾼다.
/* * SERIAL driver system settings. */ #define STM32_SERIAL_USE_USART1 FALSE #define STM32_SERIAL_USE_USART2 TRUE
위의 내용을 아래와 같이….
/* * SERIAL driver system settings. */ #define STM32_SERIAL_USE_USART1 TRUE #define STM32_SERIAL_USE_USART2 FALSE
우리는 아두이노를 통해 시리얼 디버깅을 하기위해 USART1 를 이용할 것이다.
- Makefile을 열어서 아래와 같이 수정한다.
# Imported source files CHIBIOS = ../.. include $(CHIBIOS)/boards/OLIMEX_STM32_P103/board.mk
위를 아래와 같이 바꾼다.
# Imported source files CHIBIOS = ../.. include $(CHIBIOS)/boards/LEAFLABS_STM32_F103_R5/board.mk
이렇게 하면 Maple r5의 새롭게 정의된 보드의 내용을 이용하게 된다.
- 이상이다. 그리고 main.c의 내용을 아래 것으로 복사해 넣는다.
/* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. ChibiOS/RT is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/RT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. --- A special exception to the GPL can be applied should you wish to distribute a combined work that includes ChibiOS/RT, without being obliged to provide the source code for any proprietary components. See the file exception.txt for full details of how and when the exception can be applied. */ #include "ch.h" #include "hal.h" #include "test.h" /* * Red LED blinker thread, times are in milliseconds. * GPIOA,5 is the LED on the Maple r5 */ static WORKING_AREA(waThread1, 128); static msg_t Thread1(void *arg) { (void)arg; while (TRUE) { palClearPad(GPIOA, 5); chThdSleepMilliseconds(500); palSetPad(GPIOA, 5); chThdSleepMilliseconds(500); } } /* * Application entry point. */ int main(void) { /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Activates the serial driver 1 using the driver default configuration. */ sdStart(&SD1, NULL); /* * Creates the blinker thread. */ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); /* * Normal main() thread activity, in this demo it does nothing except * sleeping in a loop and check the button state. * GPIOC,9 is the button on the Maple r5 */ while (TRUE) { if(palReadPad(GPIOC, 9)) TestThread(&SD1); chThdSleepMilliseconds(500); } }
- ‘make’를 실행하고, stm32loader.py를 이용한다. (Leaflabs의 http://leaflabs.com/docs/bootloader.html 부트로더 사용법을 참고한다.) 아두이노 IDE를 이용하여 USB 시리얼 포트 주소를 알아낸다. Maple을 시리얼 부트로도 모드로 바꾼다. (RESET버튼과 BUT버튼을 동시에 누른다. 그리고 RESET버튼에서 손을 떼고, 다음 BUT버튼에서 손을 뗀다.) 그리고, ‘stm32o.py -p /dev/tty.usbserial-A700e1x5 -evw ch.bin’ 라는 명령을 실행한다. “/dev/tty.usbserial-A700e1x5” 부분은 아두이노 IDE에서 알아낸 USB 시리얼 포트 주소를 넣는다. (역주, 윈도우즈 7을 사용하는 나의 경우엔 COM7 이었음.)
- 이게 끝이다!! 보드를 리셋하고 나면 보드에 있는 “LED”가 깜박일 것이다. 더구나, 아두이도 IDE의 시리얼 모니터를 38400 bps에 맞추면ㄱ스트 까지도 볼 수 있다. 보드의 버튼을 누르면 시리얼 모니터에 글씨도 출력되 감동 받을 것이다.
Windows에서 컴파일하고 설치하기
순서는:
- 경로 (PATH) 설정
- makefile 수정
- make 실행
- 설치
경로 설정하기
Maple IDE 는 윈도우즈와 호환되는 도스모드의 툴체인을 포함하고 있다. 이는 “<메이플 IDE 설치 위치>\hardware\tools\arm\bin” 에 있다. 그러나, 이를 이용하기 위해선 이 경로가 PATH 환경 변수에 추가되어야 한다.
makefile 수정하기
아래는 ChibiOs 를 윈도우에서 만들기 위한 수정된 makefile 이다. BUILDDIR 의 수정에 주목..
디렉토리 파일은 ChibiOS_2.2.4\os\ports\GCC\ARMCMx\rules.mk 에 있다.
아래에 내 경우에 동작하던 rules.mk 를 올려놓았다.
# ARM Cortex-Mx common makefile scripts and rules. # Output OUTFILES = $(BUILDDIR)/$(PROJECT).elf $(BUILDDIR)/$(PROJECT).hex $(BUILDDIR)/$(PROJECT).bin $(BUILDDIR)/$(PROJECT).dmp ifeq ($(BUILDDIR),) BUILDDIR = . CLEANDIR = else CLEANDIR = $(BUILDDIR) endif #ENSUREBUILDDIR = $(shell test -d $(BUILDDIR) || mkdir $(BUILDDIR)) ENSUREBUILDDIR = $( -@md $(BUILDDIR) >NUL 2>&1 || echo "" >NUL ) # Automatic compiler options OPT = $(USE_OPT) CPPOPT = $(USE_CPPOPT) ifeq ($(USE_CURRP_CACHING),yes) OPT += -ffixed-r7 -DCH_CURRP_REGISTER_CACHE='"r7"' endif ifeq ($(USE_LINK_GC),yes) OPT += -ffunction-sections -fdata-sections endif # Source files groups ifeq ($(USE_THUMB),yes) TCSRC += $(CSRC) TCPPSRC += $(CPPSRC) else ACSRC += $(CSRC) ACPPSRC += $(CPPSRC) endif ASRC = $(ACSRC)$(ACPPSRC) TSRC = $(TCSRC)$(TCPPSRC) SRC = $(ASRC)$(TSRC) # Object files groups ACOBJS = $(ACSRC:.c=.o) ACPPOBJS = $(ACPPSRC:.cpp=.o) TCOBJS = $(TCSRC:.c=.o) TCPPOBJS = $(TCPPSRC:.cpp=.o) ASMOBJS = $(ASMSRC:.s=.o) OBJS = $(ASMOBJS) $(ACOBJS) $(TCOBJS) $(ACPPOBJS) $(TCPPOBJS) # Paths IINCDIR = $(patsubst %,-I%,$(INCDIR) $(DINCDIR) $(UINCDIR)) LLIBDIR = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR)) # Macros DEFS = $(DDEFS) $(UDEFS) ADEFS = $(DADEFS) $(UADEFS) # Libs LIBS = $(DLIBS) $(ULIBS) # Various settings MCFLAGS = -mcpu=$(MCU) ODFLAGS = -x --syms ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS) CFLAGS = $(MCFLAGS) $(OPT) $(CWARN) -Wa,-alms=$(<:.c=.lst) $(DEFS) CPPFLAGS = $(MCFLAGS) $(OPT) $(CPPOPT) $(CPPWARN) -Wa,-alms=$(<:.cpp=.lst) $(DEFS) ifeq ($(USE_LINK_GC),yes) LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch,--gc-sections $(LLIBDIR) else LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(BUILDDIR)/$(PROJECT).map,--cref,--no-warn-mismatch $(LLIBDIR) endif # Thumb interwork enabled only if needed because it kills performance. ifneq ($(TSRC),) CFLAGS += -DTHUMB_PRESENT CPPFLAGS += -DTHUMB_PRESENT ASFLAGS += -DTHUMB_PRESENT ifneq ($(ASRC),) # Mixed ARM and THUMB mode. CFLAGS += -mthumb-interwork CPPFLAGS += -mthumb-interwork ASFLAGS += -mthumb-interwork LDFLAGS += -mthumb-interwork else # Pure THUMB mode, THUMB C code cannot be called by ARM asm code directly. CFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING CPPFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING ASFLAGS += -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -mthumb LDFLAGS += -mno-thumb-interwork -mthumb endif else # Pure ARM mode CFLAGS += -mno-thumb-interwork CPPFLAGS += -mno-thumb-interwork ASFLAGS += -mno-thumb-interwork LDFLAGS += -mno-thumb-interwork endif # Generate dependency information CFLAGS += -MD -MP -MF .dep/$(@F).d CPPFLAGS += -MD -MP -MF .dep/$(@F).d # # Makefile rules # all: $(ENSUREBUILDDIR) $(OBJS) $(OUTFILES) $(ACPPOBJS) : %.o : %.cpp @echo $(CPPC) -c $(CPPFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@ $(TCPPOBJS) : %.o : %.cpp @echo $(CPPC) -c $(CPPFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@ $(ACOBJS) : %.o : %.c @echo $(CC) -c $(CFLAGS) $(AOPT) -I . $(IINCDIR) $< -o $@ $(TCOBJS) : %.o : %.c @echo $(CC) -c $(CFLAGS) $(TOPT) -I . $(IINCDIR) $< -o $@ $(ASMOBJS) : %.o : %.s @echo $(AS) -c $(ASFLAGS) -I . $(IINCDIR) $< -o $@ %elf: $(OBJS) @echo $(LD) $(OBJS) $(LDFLAGS) $(LIBS) -o $@ %hex: %elf $(HEX) $< $@ %bin: %elf $(BIN) $< $@ %dmp: %elf $(OD) $(ODFLAGS) $< > $@ clean: -cs-rm -f $(OBJS) -cs-rm -f $(ACSRC:.c=.lst) $(TCSRC:.c=.lst) $(ACPPSRC:.cpp=.lst) $(TCPPSRC:.cpp=.lst) $(ASMSRC:.s=.lst) -cs-rm -f $(OUTFILES) $(BUILDDIR)/$(PROJECT).map -cs-rm -fR .dep $(CLEANDIR) # # Include the dependency files, should be the last of the makefile # #-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) -include $(-@md ".dep" >NUL 2>&1 || echo "" >NUL) $(wildcard .dep/*) # *** EOF ***
make 실행하기
위의 수정을 한다음, cs-make 라는 명령을 실행한다.
설치
윈도우에서 설치를 하려면 똑같은 python 스크립트를 이용하면 된다. 그렇지만, 이를 위해선 좀 번거로운 일들을 해야한다.
- 32 bit 버젼의 of Python 2.7을 사용해야만한다. 절대 64bit 버젼을 사용하면 안된다.
- python 이 경로에 설정되어있어야 한다.
- python 2.5 또는 이상 버젼용 PySerial이 설치되어 있어야 한다.
Windows 삽질기
- 시간을 꽤 잡아먹는 일이다. stm32loader를 이용할 때, -ewv 대신 -w 옵션을 사용했었다. 그렇게 하면 원하는 결과를 얻을 수 없다!!!