[맥에서 AVR 개발하기] 터미널에 명령어들을 입력해서 소스코드를 컴파일하고 .hex 파일을 개발보드로 넣기 [진행중....]



AVR Studio 는 윈도우 환경에서만 제공되는 avr 개발 환경입니다. 
맥 OS에서 개발하는 방법을 알아보기 위해서 구글링을 했고, 시행 착오를 겪어 포스팅을 하고 있습니다. 

이미 잘 정리된 글이 있어서 참고하여 포스팅하겠습니다 

이전 설치 필요 프로그램 : Xcode




- 툴체인 소스 다운로드 

그런데 툴체인이 뭘까요?? 용어 정리를 하고 갑시다.

툴체인(Toolchain)의 설명에 앞서 툴체인의 필요 목적에 대해서 알아보자.



[ 그림 1 ] Host and Target System

 

임베디드 시스템을 개발을 위해서는 대부분 [ 그림 1 ]처럼 호스트 시스템(Host System)타겟 시스템(Target System)으로 구성된다. 호스트 시스템은 실질적인 임베디드 시스템을 개발하는 환경으로, 이는 임베디드 시스템의 하드웨어의 제한적인 성능 때문에 큰 용량의 저장장치를 가지고 있지 않기 때문이다. 그래서 상대적으로 성능이 좋은 호스트 시스템을 구축하여 타겟 시스템에서 동작 가능한 프로그램을 만드는데 이것을 교차 컴파일(Cross compile)이라고 한다. 여기서 타겟 시스템이란 실질적인 임베디드 시스템이 동작되는 환경을 말한다.

 

툴체인(Toolchain)이란 타겟 시스템에서 동작하는 프로그램 개발에 필요한 호스트 시스템의 소프트웨어들 또는 개발 환경을 통칭하기도 한다. 조금 더 자세하게 설명하면 소스 코드를 컴파일하고 빌드하여 바이너리 실행 파일을 생성하는데 필요한 각종 유틸리티 및 라이브러리의 모음이다.

 

툴체인의 기본적인 구성 요소는 다음과 같다.

-      Assembler   ( 어셈블리 언어를 기계어로 번역해 주는 프로그램.   )

-      Linker          ( 링커(linker) 또는 링크 에디터(link editor)는 컴퓨터 과학에서 컴파일러가 만들어낸 하나 이상의 목적 파일을 가져와 이를 단일 실행 프로그램으로 병합하는 프로그램이다. )

-      C Compiler

-      C Library

등이 있다.






1) Binary Utilies 소스 다운로드

바이너리 유틸리티(binutils)는 여러 종류의 오브젝트 파일 형식을 조작하기 위한 프로그램 도구 모음으로서 어셈블러, 링커등을 포함하고 있습니다. binutils는 일반적으로 gcc, make, gdb와 함께 사용됩니다.

binutils의 최신버전은 http://ftp.gnu.org/gnu/binutils/ 에서 확인할 수 있습니다.

$ curl -O ftp://gcc.gnu.org/pub/binutils/releases/binutils-2.24.tar.bz2




2) GCC 컴파일러 소스 다운로드

gcc는 GNU(GNU is Not Unix) 프로젝트의 프리웨어 컴파일러 입니다. C언어 뿐만 아니라 C++, Objective-C, Pascal, Ada등의 다양한 언어를 지원합니다.

최신버전은 http://ftp.gnu.org/gnu/gcc/ 에서 확인할 수 있습니다.

$ curl -O ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.6.4/gcc-core-4.6.4.tar.bz2
$ curl -O ftp://gcc.gnu.org/pub/gcc/releases/gcc-4.6.4/gcc-g++-4.6.4.tar.bz2



- 여기서 부터 터미널 색을 바꾸겠습니다. 






 3) AVR 라이브러리 소스 다운로드

avr-libc의 공식 사이트는 http://savannah.nongnu.org/projects/avr-libc/ 이며,

최신버전은 http://download.savannah.gnu.org/releases/avr-libc/ 에서 확인할 수 있습니다.


$ curl -O http://download.savannah.gnu.org/releases/avr-libc/avr-libc-1.8.0.tar.bz2



위의 다운로드 사이트는 현재 접속은 되지만 다운로드는 불가능 합니다. 하지만 다음의 미러 사이트에서 다운받을 수 있습니다.


$ curl -O http://mirror.lihnidos.org/GNU/savannah/avr-lib/avr-libc-1.8.0.tar.bz2

 







4) Debugger 소스 다운로드

    최신버전은 https://sourceware.org/gdb/ 에서 확인할 수 있습니다.


$ curl -O ftp://sourceware.org/pub/gdb/releases/gdb-7.7.tar.bz2

  




- 환경설정

우선 크로스 컴파일러 툴체인을 만들기 전에 다음과 같이 컴파일 환경설정을 합니다.

 

크로스 컴파일러의 위치를 prefix라는 환경변수로 설정합니다.

일반적인 사용자 설치 파일은 /usr/local 아래에 설치하지만 필자의 경우는 /opt 아래에 설치합니다. 어느 위치이건 관계 없습니다.

$ export target=avr
$ export prefix=/opt/$target

 

크로스 컴파일러가 위치할 디렉토리를 만듭니다. (수퍼유저 권한으로 디렉토리를 만들므로 비밀번호 필요)

$ sudo mkdir -p $prefix/bin 


크로스 컴파일러의 실행파일이 있는 디렉토리 위치를 PATH로 설정합니다.

$ export PATH=$prefix/bin:$PATH 




앞에서 한 컴파일 환경설정은 일시적인 설정입니다.

그러므로 터미널을 종료했다 다시 시작하거나, 다른 터미널을 실행시키면 앞에서 한 환경설정이 적용되지 않습니다.

터미널을 실행시킬 때 마다 위의 환경설정이 항상 적용되는것을 원한다면 사용자 홈 디렉토리의 .bash_profile 파일에 다음을 추가하면 됩니다.

$ gedit ~/.bash_profile

$ export target=avr

$ export prefix=/opt/$target

$ export PATH=$prefix/bin:$PATH



저는 gedit 을 이용해서 수정했습니다.

 




이제 새로 터미널을 실행할 때마다 환경설정이 적용된 것을 확인할 수 있습니다.

$ env

TERM_PROGRAM=Apple_Terminal

SHELL=/bin/bash

.

.

.

PATH=/opt/avr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin

.

.

.

prefix=/opt/avr

.

.

.

target=avr

 



- 툴체인 컴파일

 

1) Binary Utility 컴파일

다운받은 압축파일을 풉니다. 


$ tar -jxf binutils-2.24.tar.bz2

 

컴파일할 폴더를 만듭니다. 


$ cd binutils-2.24 

$ mkdir build-$target 
$ cd build-$target

 

컴파일 환경을 설정하기 위하여 comfigure를 실행시킵니다.

$ ../configure --target=$target --prefix=$prefix --disable-nls --disable-shared --disable-threads --with-gcc --with-gnu-as --with-gnu-ld

 

컴파일을 합니다. 

$ make

 








만일 다음과 같은 에러가 나온다면

../../gas/as.c:977:24: error: 'sbrk' is deprecated [-Werror,-Wdeprecated-declarations]

  char *lim = (char *) sbrk (0);

                       ^

/usr/include/unistd.h:582:7: note: 'sbrk' declared here

void    *sbrk(int);

         ^

../../gas/as.c:1146:25: error: 'sbrk' is deprecated [-Werror,-Wdeprecated-declarations]

  start_sbrk = (char *) sbrk (0);

                        ^

/usr/include/unistd.h:582:7: note: 'sbrk' declared here

void    *sbrk(int);




 

Makefile에서 CFLAGS를 찾아 다음과 같이 수정합니다. (이 에러를 해결하기 위해 몇일을 고생하였습니다).

$ vi Makefile

 

 

.

.

.

 

 

//CFLAGS = -g -O2

CFLAGS = -g -O2 -Wno-error=deprecated-declarations

 

.

.

.

 



 




에러가 없이 모든 컴파일이 완료되면 설치를 합니다.

$ sudo make install

$ cd ../..

 







2) AVR Cross Compiler 컴파일 

 

다운받은 압축파일을 풉니다.

$ tar -jxf gcc-core-4.6.4.tar.bz2

$ tar -jxf gcc-g++-4.6.4.tar.bz2

 



컴파일할 폴더를 만듭니다.

$ cd gcc-4.6.4

$ mkdir build-$target

$ cd build-$target 






 

컴파일 환경설정을 합니다.

$ ../configure --target=$target --prefix=$prefix --disable-nls --disable-shared --disable-threads --with-gcc --with-gnu-ld --with-gnu-as --with-dwarf2 --enable-languages=c,c++ --disable-libssp -v




 

내용 추가: 2014.09.16


만일 다음과 같은 에러가 발생한다면 

gmp나 mpfr, mpc중 하나가(또는 모두) 설치가 안된것이므로 해당 패키지를 설치해야 합니다.

.

.

.

 

checking for objdir... .libs

checking for the correct version of gmp.h... no

configure: error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+.

Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify

their locations. Source code for these libraries can be found at

their respective hosting sites as well as at

ftp://gcc.gnu.org/pub/gcc/infrastructure/. See also

http://gcc.gnu.org/install/prerequisites.html for additional info. If

you obtained GMP, MPFR and/or MPC from a vendor distribution package,

make sure that you have installed both the libraries and the header

files. They may be located in separate packages.


맥에서의 패키지 설치는 Homebrew나 MacPort와 같은 패키지 관리자를 사용하여 설치할 수 있습니다.

참고로 Homebrew에서는 다음과 같이 설치하면 됩니다.

# brew install gmp

# brew install mpfr

# brew install libmpc









Homebrew에 대한 자세한 사용법은 다음에서 확인할 수 있습니다.

맥에서 패키지를 관리하자 Homebrew




컴파일 및 설치를 합니다.

$ make

$ sudo make install

$ cd ../..












어마어마하게 오래동안 설치하는군요.... 

컴파일러가 정상적으로 설치 되었는지 확인합니다.

$ avr-gcc —-version

avr-gcc (GCC) 4.6.4

Copyright (C) 2011 Free Software Foundation, Inc.

This is free software; see the source for copying conditions.  There is NO

warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.






 

3) Library 컴파일

 

다운받은 압축파일을 풉니다.

$ tar -jxf avr-libc-1.8.0.tar.bz2

 


저같은 경우 압축 해제 에러가 나서 아래의 링크에 가서 다운받아서 다시 압축을 풀었습니다. 
http://download-mirror.savannah.gnu.org/releases/avr-libc/old-releases/



컴파일할 폴더를 만듭니다.

$ cd avr-libc-1.8.0

$ mkdir build-$target

$ cd build-$target

 

컴파일 환경설정을 합니다.

$ ../configure --prefix=$prefix --build=`../config.guess` --host=$target

 

컴파일 및 설치를 합니다.

$ make

$ sudo make install

$ cd ../..




 

4) Debugger 컴파일

 

다운받은 압축파일을 풉니다.

$ tar -jxf gdb-7.7.tar.bz2

 

컴파일할 폴더를 만듭니다.

$ cd gdb-7.7

$ mkdir build-$target

$ cd build-$target

 

컴파일 환경설정을 합니다.

$ ../configure --target=$target --prefix=$prefix --disable-nls

 

컴파일 및 설치를 합니다.

$ make

$ sudo make install

$ cd ../..

 





5) 바이너리 축소
 

컴파일한 바이너리 파일의 용량을 줄이고 로딩 속도를 빠리게 하기 위하여 바이너리를 축소 합니다.

$ sudo strip $prefix/bin/*

$ sudo strip $prefix/$target/bin/*

$ sudo strip $prefix/libexec/gcc/$target/4.2.2/*


 



- 개발 프로그램 설치하기 

 

설치된 툴체인을 사용하여 개발된 프로그램을 컴파일해 보도록 하겠습니다.

우선 프로젝트에 맞는 AVR 프로그램을 개발합니다.

예를 들어 초음파 거리측정을 하는 프로그램을 개발했다고 가정합니다.

Project 이름은 SonicCalc 입니다.

SonicCalc.h SonicCalc.c

ExtInt.h ExtInt.c

TimerInt.h TimerInt.c

UART.h UART.c

 

필자는 프로그램을 모듈별로 파일을 분리하여 개발합니다.

파일의 이름에서 보듯이 SonicCalc는 초음파 거리 계산을 하는 모듈이며 메인 모듈입니다.

ExtInt는 외부 인터럽트 모듈, TimerInt는 타이머 인터럽트 모듈, UART는 시리얼 통신 모듈을 의미합니다. 


- 빌드폴더 만들기

 

소스가 있는 프로젝트 폴더에서 컴파일해도 무관하지만, 필자는 object 파일 등이 소스와 함께 존재하는 것이 별로 좋아하지 않으므로 빌드 폴더를 만들어서 사용합니다.

 

$ mkdir build

$ cd build




 

- Makefile 만들기

 

그럼 컴파일을 하기 위한 Makefile을 만듭니다.

Makefile은 직접 만들어도 되지만 여러가지 옵션들을 고민하면서 만들어야 하므로 공부를 좀 해야 합니다.

그래서 가장 쉬운 방법으로 윈도우즈의 AVR Studio에서 자동으로 만들어주는 Makefile을 가지고 왔습니다.

윈도우즈의 AVR Studio를 사용하여 만든 프로젝트 폴더 아래의 default 폴더를 보면 Makefile이 있습니다.

이 Makefile을 복사해 온 후, 파일에서 Target MCU와 PROJECT, 컴파일 할 소스등을 수정하면 됩니다.

(아래의 Makefile은 필자의 개발 환경에 맞는 설정들이며 사용자에 따라 다를 수 있습니다).

 

$ vi Makefile
 
###############################################################################
# Makefile for the project SonicCalc
###############################################################################
 
## General Flags
PROJECT = SonicCalc
MCU = atmega128
TARGET = SonicCalc.elf
CC = avr-gcc
CPP = avr-g++
 
## Options common to compile, link and assembly rules
COMMON = -mmcu=$(MCU)
 
## Compile options common for all C compilation units.
CFLAGS = $(COMMON)
CFLAGS += -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d
 
## Assembly specific flags
ASMFLAGS = $(COMMON)
 
ASMFLAGS += $(CFLAGS)
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
 
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=SonicComm.map
 
## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
 
HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
 
## Libraries
LIBS = -lm -lprintf_flt
 
## Objects that must be built in order to link
OBJECTS = SonicCalc.o ExtInt.o TimerInt.o UART.o
 
## Objects explicitly added by the user
LINKONLYOBJECTS =
 
## Build
all: $(TARGET) SonicCalc.hex SonicCalc.eep SonicCalc.lss
 
## Compile
SonicCalc.o: ../SonicCalc.c
        $(CC) $(INCLUDES) $(CFLAGS) -c  $<
 
ExtInt.o: ../ExtInt.c
        $(CC) $(INCLUDES) $(CFLAGS) -c  $<
 
TimerInt.o: ../TimerInt.c
        $(CC) $(INCLUDES) $(CFLAGS) -c  $<
 
UART.o: ../UART.c
        $(CC) $(INCLUDES) $(CFLAGS) -c  $<
 
##Link
$(TARGET): $(OBJECTS)
         $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
 
%.hex: $(TARGET)
        avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@
 
%.eep: $(TARGET)
        -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
 
%.lss: $(TARGET)
        avr-objdump -h -S $< > $@
 
## Clean target
.PHONY: clean
clean:
        -rm -rf $(OBJECTS) SonicCalc.elf dep/* SonicCalc.hex SonicCalc.eep SonicCalc.lss SonicCalc.map
 
## Other dependencies
-include $(shell mkdir dep 2>NUL) $(wildcard dep/*)

 

4. 컴파일 하기

 

Makefile을 만들었으면 이제 프로젝트 소스를 컴파일 합니다.

컴파일을 단순히 make 명령을 입력하는 것으로 끝납니다.

 

$ make

 

컴파일 과정에서 에러가 발생하면 에러를 확인하고 소스를 수정합니다.

에러가 없이 컴파일이 완료되었습니다.

.

.

.

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT SonicCalc.o -MF dep/SonicCalc.o.d  -c  ../SonicCalc.c

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT ExtInt.o -MF dep/ExtInt.o.d  -c  ../ExtInt.c

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT TimerInt.o -MF dep/TimerInt.o.d  -c  ../TimerInt.c

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT UART.o -MF dep/UART.o.d  -c  ../UART.c

avr-gcc -mmcu=atmega8 -Wl,-Map=SonicComm.map SonicComm.o UART.o ExtInt.o TimerInt.o Utility.o EEPROM.o SPI.o    -lm -lprintf_flt  -o SonicComm.elf

avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  SonicComm.elf SonicComm.hex

avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex SonicComm.elf SonicComm.eep || exit 0

avr-objdump -h -S SonicComm.elf > SonicComm.lss

 

에러가 없이 컴파일이 완료되면 다음과 같이 컴파일 후 생성된 결과 파일들을 확인할 수 있습니다.

$ ls

NUL             SonicCalc.elf   SonicCalc.map   UART.o          ExtInt.o

SonicCalc.hex   SonicCalc.o     Makefile        SonicCalc.eep   SonicCalc.lss

TimerInt.o      dep

 

AVR 툴체인을 사용하여 개발된 소스의 컴파일을 완료하였습니다.

이제 컴파일 결과로 생성된 .hex 파일을 타겟 보드에 다운로드 하면 됩니다.

 

다음에는 이렇게 생성된 HEX 파일을 다운로드 하기위한 ISP 드라이버 설치 방법에 대하여 알아보도록 하겠습니다.



  







- 출처 -
http://macworld.hjsong.net/73
http://leeyongjeon.tistory.com/entry/툴체인Toolchain이란
https://ko.wikipedia.org/wiki/%EB%A7%81%EC%BB%A4_(%EC%BB%B4%ED%93%A8%ED%8C%85)