STM32F429i-Discovery 보드에 Linux 올려보기

최근에 IoT 장치에 관하여 좀더 관심이 많아지기 시작했습니다. 그래서 시간이 날때마다 IoT 장치와 관련된 웹 서핑을 종종 해보고 있는데요, IoT 장치로 사용할 MCU와 개발 보드를 찾다보니 우연하게 ST사의 개발보드가 눈에 띄었습니다. 

위 보드는 ST사의 “STM32F429i-Discovery(DISC1)” 라는 개발보드입니다. ARM Core 기반의 프로세서이고 Cortex-M 시리즈 MCU 입니다. 자세한 스펙을 좀 살펴볼까요?

MCU 클럭이 180 Mhz 정도 되니 IoT 장치의 MCU 성능으로는 나쁘지 않을것으로 생각됩니다. 다만 아쉬운 것은 별도의 플래시 메모리가  달려 있지 않고 내장 Flash를 사용한다는 점입니다. 물론 2 MB 의 용량은 적지는 않으나 다소 부족할 수도 있는 용량이군요. 

USB 포트는 1개 입니다. OTG 포트인데 USB WiFi를 달수 있을지 궁금해지는군요. 

“STM32F429i-Discovery” 보드의 구성중에 마음에 드는 부분은 2.4인치 QVGA TFT LCD가 달려있다는 점입니다. 처음에는 단순한 LCD인줄 알았는데 알고 보니 터치가 가능한 LCD 였습니다. 나름 활용 용도가 있을걸로 보이는군요. 거기에 3축 자이로스코프 센서가 달려있는 것도 눈에 띕니다. 

그런데 “STM32F429i-Discovery” 개발 보드를 살펴보는데 있어서 가장 중요한 점은 과연 “STM32F429i-Discovery” 보드에 리눅스가 올라갈 수 있느냐는 점입니다. ST사에서는 공식적으로 “STM32F429i-Discovery” 보드에 리눅스를 지원하지는 않는데요, 구글에서 열심히 검색을 하다 보니 “리눅스”를 올리는게 가능하다는 점을 알게 되었습니다. (아래링크참조)

왠지 꽤 흥미로워 지는군요. 그래서 이 개발보드의 가격을 알아보니 국내에서 대략 4만원 초반대의 가격으로 구입이 가능하다는 것을 알게 되었습니다. 

개발보드가 이 가격이니 실제 MCU 모듈같은 경우에는 훨씬 더 저렴할 수 있을꺼 같네요. 이참에 한번 구입하여 직접 “리눅스”를 올려보기로 하였습니다. 

STM32F429i-Discovery(DISC1) 개발보드 구입

인터넷 마켓에서 주문을 한지 거의 이틀만에 바로 받아보게 되었습니다. 다행히 국내 대리점이었는데요, 재고가 충분히 있었던 모양입니다. 실제 모습을 한번 볼까요?

보드 사이즈는 그리 크지 않은 모습입니다. 그렇지만 제가 가지고 있는 “라즈베리파이 3 B+” 보다는 큽니다. 

“STM32F429i-Discovery” 보드에 컴파일한 바이너리를 다운로드 하기 위해 ST-Link/V2 를 구입했는데요, 받고 나서 보니 “STM32F429i-Discovery” 보드는 별도로 ST-Link/V2 가 필요없다는 것을 알게 되었습니다. 보드 자체에 ST-Link 가 내장되어 있어서 USB로 전원과 동시에 다운로드, 디버깅이 가능합니다. 

뭐 기왕 구매했으니 추후에 다른 ST사의 MCU를 다룰때 써야 되겠습니다. 잘 모셔놓으면 또 쓸때가 있겠지요 ㅋ (가격은 1만원이 채 안되게 주고 구입했습니다.)

“STM32F429i-Discovery” 보드의 포장을 개봉한 모습입니다. 전면에는 2.4 인치 LCD가 장착이 되어 있고 맨 상단에는 USB 전원 및 ST-Link 연결 커넥터가 있습니다. 따라서 USB만 연결해주면 전원 공급 및 ST-Link로 디버깅 및 다운로드가 가능합니다. 

반대면에는 “STM32F429i” MCU와 메모리가 보이는군요. 또한 핀 헤더로 GPIO를 쉽게 연결할 수 있게 되어 있습니다. 

테스트겸 해서 제 PC의 USB 포트로 케이블을 연결해봤더니 전원이 바로 들어옵니다. 그러더니 LCD에 데모용 펌웨어 기능이 동작하는거 같네요. UI가 나름 예쁘게 잘 꾸며져 있는듯 합니다. 

LCD의 화면 구성에서 “System Info”를 꾹 눌러보니 위와 같이 정보가 나타납니다. 데모 펌웨어가 2013년에 릴리즈 된거면 꽤 출시가 된 개발보드인거 같네요. 구매한 보드는 정상적으로 동작하는 듯 보입니다. 

STM32F429i-Discovery 에 리눅스를 올리기 위한 사전준비

일단 “STM32F429i-Discovery” 보드에서 필요한 준비물들이 몇가지가 있습니다. USB 케이블과 USB to Serial TTL 어뎁터가 필요합니다. 

USB케이블은 USB mini B 타입을 사용하면 됩니다. USB 케이블은 “STM32F429i-Discovery” 보드에 컴파일한 리눅스의 이미지를 다운로드 할때 사용합니다. USB to Serial TTL 어뎁터는 시중에 판매하는 저렴한 제품을 사용하면 됩니다. 

USB to Serial TTL 어뎁터는 “STM32F429i-Discovery” 보드와 PC간에 시리얼 통신을 하기 위해 사용합니다. “STM32F429i-Discovery” 보드에 리눅스를 올리고 나서 동작 여부를 확인하려면 USB to Serial TTL 어뎁터는 꼭 필요하다고 볼 수 있습니다. 시리얼 통신 관련해서는 위의 링크 글을 참고하시기 바랍니다. 

다음으로 “STM32F429i-Discovery” 개발보드에 컴파일한 리눅스 이미지를 다운로드 하기 위해서는 ST-Link Tool의 컴파일 및 설치가 필요합니다.  리눅스 BSP의 소스에도 “STM32F429i-Discovery” 보드에 다운로드 할 수 있는 툴인 “OpenOCD”가 포함되어 있으나 제가 확인해본 결과 정상적으로 동작을 하지 않더군요. 아마 config 파일을 수정해 줘야 할 듯 한데 이 부분은 좀더 확인해 보고 기술하도록 하겠습니다. 

ST-Link Tool은 Windows용을 사용해도 되나 리눅스의 특성상 리눅스용 툴을 사용하는게 편리합니다. 먼저 “stlink” 의 소스를 다운로드 받습니다. 

git clone https://github.com/stlink-org/stlink.git stlink

혹은

git clone https://github.com/texane/stlink.git stlink

stlink의 소스는 위의 2개의 링크가 있습니다. 둘중에 아무거나 받아서 사용해도 상관은 없습니다. 저는 첫번째 주소의 stlink 소스를 다운로드 받아서 컴파일을 했습니다. 

stlink의 소스를 git으로 clone 했다면 stlink 소스를 컴파일하기 위해 몇가지 패키지를 설치해야 합니다. 제 개발서버 환경은 우분투 16.04 입니다. 여기서 필요한 패키지를 아래와 같이 설치합니다.

$ sudo apt-get install libtool autoconf automake texinfo
$ sudo apt-get install libusb-dev libusb-1.0

설치가 끝나면 이제 st-link를 컴파일 합니다. “make” 입력하여 컴파일을 진행합니다. 

컴파일이 끝나면 stlink의 소스 루트에서 “build/Release/bin” 에 컴파일된 stlink 유틸의 실행파일이 생성된것을 확인할 수 있습니다. 이중에서 “STM32F429i-Discovery” 보드에 다운로드 할때 사용하는 실행파일은 “st-flash” 입니다. 실행을 시켜보면

딱 봐도 보드에 Download를 하는 툴 같아 보입니다. ㅋ 다시 원래 stlink 소스의 루트로 돌아가서 “sudo make install” 명령어로 개발 PC에다가 컴파일한 stlink 실행파일을 설치합니다. 

위의 과정이 끝나면 stlink 툴을 사용할 준비가 된것입니다. 이제 본격적으로 “STM32F429i-Discovery” 개발보드에 리눅스 BSP를 올려보도록 하겠습니다. 

STM32F429i-Discovery 개발보드에 올릴 리눅스 BSP 소스 다운로드 및 컴파일

자 그럼 “STM32F429i-Discovery” 보드에 올릴 리눅스 BSP의 소스를 다운로드 하고 컴파일을 해보겠습니다. 찾아보니 “STM32F429i-Discovery” 보드에 Buildroot 를 올릴수 있는거 같더군요. 

위의 링크는 처음에 제가 시도했던 리눅스 소스입니다. 커널버전이 4.15인 비교적 최신 커널을 탑재하고 있습니다. 

하지만 위 링크의 리눅스 소스를 올렸을때 부팅이 정상적이지 않습니다. 

컴파일하여 올린 후 터미널의 모습인데요, 부팅 막판에 exception 이 발생하면서 죽어버리는 상황이 발생하더군요. 좀더 찾아보니 “binutil” 버전을 2.28.1 로 변경하면 정상적일꺼라고 했지만 최종적으로 확인해본 결과 터미널에서 Rx는 정상동작이지만 Tx가 동작하지 않는 문제가 발생합니다. 즉 터미널에서 입력한 값들이 정상적으로 “STM32F429i-Discovery”에 전송이 되지 않는걸로 보입니다. 

음.. 더이상 확인하는건 시간이 많이 걸릴 듯 하군요. 그래서 일단 다른 방법을 찾아본 결과 다른 리눅스 BSP 소스를 발견했습니다. 

위 소스는 uClinux 기반의 BSP 소스입니다. 커널 버전은 2.6.33 입니다. 그래서 위 BSP 소스를 한번 올려보기로 하겠습니다. 위 Buildroot BSP 소스는 다시 확인 후 추후에 문제점을 공유해보도록 하지요. 

먼저 git으로 BSP 소스를 내려받습니다. 

git clone https://github.com/jserv/stm32f429-linux-builder.git stm32f429

다음으로 컴파일에 필요한 패키지를 설치합니다. 

sudo apt-get install genromfs

 genromfs 라는 패키지입니다. 마지막으로 컴파일을 하기 위해 툴체인을 다운로드 받아 위의 BSP 소스 디렉토리 안에서 다운로드 및 아래 절차대로 압축을 풀고 PATH를 설정합니다.

# 툴체인 다운로드
wget https://sourcery.mentor.com/public/gnu_toolchain/arm-uclinuxeabi/arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2

# 툴체인 압축 파일 해제
tar jxvf arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2

# 툴체인 PATH 설정
export PATH=`pwd`/arm-2010q1/bin:$PATH

위 절차가 끝났다면 컴파일할 준비는 다 된것입니다. 이제 “make” 명령어를 입력하여 컴파일을 진행합니다. 

개발 환경마다 다르지만 저같이 우분투 16.04 에서는 아래와 같이 오류가 발생할 수도 있습니다. 

....중략
Can't use 'defined(@array)' (Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at kernel/timeconst.pl line 373. ?) at kernel/timeconst.pl line 373. 
....중략

위 오류를 제거하려면 아래와 같이 kernel의 소스파일을 수정해줍니다. (uclinux/kernel/timeconst.pl 파일을 vi 로 열어줍니다.)

line 373 
  if (!defined(@val)) { 
/* 위의 defined를 아래와 같이 변경 */
  if (!@val) {

위와 같이 수정을 해주면 이후에 컴파일은 정상적으로 진행됩니다. 

제 리눅스 PC 에서 컴파일이 완료된 모습입니다. 여기까지 진행되었다면 컴파일이 완료된거라고 볼 수 있습니다. 

컴파일한 리눅스 이미지를 STM32F429i-Discovery 에 Download 하기

자 그럼 이제 좀전에 컴파일 했던 이미지 파일들을 “STM32F429i-Discovery” 개발 보드에 다운로드를 해보도록 하겠습니다. 리눅스 PC에 보드를 USB 케이블로 연결하면 자동적으로 ST-Link Driver가 인식됩니다. 이 상태에서 리눅스를 올리기 위해 컴파일하여 설치했던 “st-flash”를 사용하겠습니다. 

먼저 컴파일한 이미지 파일들의 위치를 알아볼까요?

보드에 리눅스를 올릴려면 3개의 파일이 필요합니다. 3개는 각각 u-boot, kernel, Root Filesystem 이미지 파일들입니다. 위치는 아래와 같습니다. 

# u-boot 파일 위치
$ROOT/out/uboot/u-boot.bin

# kernel 파일 위치
$ROOT/out/kernel/arch/arm/boot/xipuImage.bin

# ROOT Filesystem 파일 위치
$ROOT/out/romfs.bin

위 3개의 파일을 st-flash를 사용하여 다운로드 하면 됩니다. 명령어는 아래를 참고하세요.

# u-boot 다운로드
sudo st-flash write u-boot.bin 0x08000000

# kernel 다운로드
sudo st-flash write xipuImage.bin 0x08020000

# Root Filesytem 다운로드
sudo st-flash write romfs.bin 0x08120000 

st-flash는 “st-flash (옵션) (파일명) (Flash Offset Address)” 형태로 사용하면 됩니다. 저같은 경우는 리눅스 PC의 계정이 root 권한이 아니기 때문에 “sudo”를 사용하였습니다. 

먼저 u-boot를 다운로드 해보면

write 및 verify 가 정상적으로 된것을 확인할 수 있습니다. 이 상태에서 kernel을 다운로드 합니다. 

커널도 위의 화면으로 봤을때 정상적으로 된것을 확인할 수 있습니다. 이제 마지막으로 Root Filesystem을 다운로드 합니다. 파일이 위치한 경로로 이동해서 st-flash로 다운로드를 하면

위와 같이 메시지가 나타나면서 정상적으로 다운로드가 되는 것을 확인할 수 있습니다. 

다운로드한 STM32F429i-Discovery 보드 부팅하기

이제 개발보드에 리눅스를 올리는 모든 작업은 마무리가 되었습니다. 실제로 동작을 잘 하는지 확인을 해봐야 겠네요. 다운로드가 끝나고 USB 케이블을 제거한 상태에서 USB to Serial TTL 어뎁터를 준비합니다. 

올린 BSP에서는 UART 핀이 다음과 같이 설정되어 있습니다. 

pin PC10 -> TXD
pin PC11 -> RXD

따라서 보드의 핀과 USB to Serial TTL 어뎁터의 각각 RXD, TXD 핀과 GND 핀을 각각 연결합니다. 

제가 연결한 모습입니다. 위 사진과 같이 연결을 해주면 “STM32F429i-Discovery” 개발보드와 시리얼 통신을 통해 동작 여부를 확인 할 수 있습니다. 그럼 터미널에서 부팅 메시지를 확인해 볼까요?

부팅이 잘 되는 모습을 확인 할 수 있습니다. “STM32F429i-Discovery” 개발보드의 MCU는 MMU가 없는 MCU 이기 때문에 “uClinux”를 올릴 수 있습니다. 

부팅 후에 LCD를 확인해 보니 리눅스의 상징인 “턱스”가 덩그라니 반겨주고 있군요ㅎ 

이상으로 “STM32F429i-Discovery” 개발보드에 리눅스를 올리는 방법에 대해 기술해봤습니다. 현재는 통신용 이더넷, WiFi, 블루투스 등이 없는 빈 깡통 상태인데요, 여기에다 이더넷이든, WiFi든 블루투스등을 한번 붙여봐야 될꺼 같습니다. 

대신에 현재 “STM32F429i-Discovery” 보드의 플래시 메모리의 용량이 꽤 적은 상태인데요, 외부 플래시를 추가여 붙여서 사용할지 아니면 SD Card를 붙여서 사용할지 검토를 좀 해봐야 될꺼 같습니다. 이후에 이들 디바이스들을 붙여서 구동하는 것에 대한 것은 별도로 작성하여 공유해 보도록 할께요.

STM32F429i-Discovery 보드는 아래 링크를 통해 구입도 가능합니다. 

원래 ST STM32F429I-DISCOSTM32F429I-DISC1 STM32F429IDISCOVERY

 

'코드도사(codedosa.com)'에는 쿠팡파트너스 등의 제휴링크가 포함되어 있으며 수수료를 제공받을 수 있습니다.