2014년 5월 7일 수요일

NanoQplus is IPv6 Ready!



NanoQplus가 IPv6 Ready 로고를 획득했다. IPv6 Ready는 IPv6 Forum이 주관하는 인증 프로그램으로 어떤 장치가 IPv6 통신을 수행하기에 적합한지에 관한 것이다. IPv6 통신을 수행하기에 적합하다는 것은 IPv6 패킷을 수신하여 올바르게 처리하고, 또 올바른 IPv6 패킷을 송신하는 것을 뜻하며, 이는 곧 타 IPv6 장비와 문제없이 통신이 가능함을 뜻한다.

IPv6 Ready는 IPv6를 구현함에 있어서 정상적인 동작을 검증하기에 좋은 방법이다. IPv6 Ready는 장치와 프로토콜의 종류에 따라 여러가지 버전이 있지만, 이 글은 Core Protocols Phase 2만 대상으로 한다. 난 Host 버전만 했는데, Router 버전은 Host 버전에 비해 테스트 항목이 월등히 많이 늘어날 뿐, 그 근본적인 개념은 거의 비슷하지 않을까 싶다. 물론, 우리나라에 직접 IPv6를 구현하려는 사람이 얼마나 있을지는 모르겠지만, 혹시나 이런 삽질을 시작하려는 분들께 도움이 되길 바라며 메모를 남겨본다.

IPv6 Ready는 기본적으로 Ethernet 장치를 가정하고 있다. 사실, IPv6는 네트워크 계층이므로, 링크 계층에 상관없어야 하지만, IPv6 Ready는 링크 계층에 의존적인 Neighbor Discovery까지 시험 범위에 두고 있다. NanoQplus는 본래 IEEE 802.15.4 WPAN 기반으로 통신하는 하드웨어를 타겟으로 하는 운영체제이기에 Ethernet을 지원하는 하드웨어에 올려서 시험해봐야 했다. 우리 연구실은 씨알지 테크놀러지(주)에 의뢰하여 Mango-EToI라는 보드를 제작했다. 그리고 그 위에 NanoQplus를 포팅하였다.


Mango-EToI는 STM32F103VCT6 ARM Cortex-M3 기반의 보드이며, (페이지에는 STM32F2xx인 것으로 나와있는데, 내가 갖고 있는 보드는 STM32F103이다.) 2개의 통신보드 커넥터와 센서나 기타 장치를 연결할 수 있는 확장 커넥터로 구성되어 있다. 통신보드에는 2.4GHz IEEE 802.15.4를 지원하는 CC2520, Sub-1GHz IEEE 802.15.4를 지원하는 CC1120과 Ethernet을 지원하는 ENC28J60 칩으로 구성된 보드들이 있다. NanoQplus에서는 이 보드들을 메인보드의 어떤 포트에 연결하든지 따라 환경설정을 통해 유연하게 구성할 수 있다. Application code는 NanoQplus 저장소에 있다.

IPv6 Ready는 conformance test, interoperability test 등 두 가지 시험이 있으며, 이 두 시험을 모두 통과하여야 한다. Conformance test는 기본적인 패킷 처리를 테스트하는 것으로 conformance test tool이 설치된 FreeBSD 머신과 크로스케이블로 연결하여 테스트한다. 대부분 테스트 항목들이 자동으로 넘어가며, 일부는 수동으로 보드를 직접 리셋해주며 넘어가는 식이다. 여기까지는 그냥그냥 할만하다. 물론, NanoQplus의 IPv6는 리눅스 커널같은 오픈소스를 이용하지 않고 scratch부터 시작해서 쌩짜로 작성한 것이기 때문에, 버그들을 때려잡고 이해안가는 RFC 문서들을 이해하고 구현하느라 오래 걸렸다.

Interoperability test는 4대의 서로 다른 제조사가 만든 IPv6 장치(호스트 2대, 라우터 2대)로 여러 형태의 네트워크 토폴로지에서 상호운용성을 시험하는 것을 말한다. NanoQplus는 OpenWrt Linux와 FreeBSD를 라우터로 사용하고, Apple MacBook Air와 MS Windows XP를 호스트로 사용했다. Interoperability test도 자동으로 하는 방법도 있지만, 모든 장치들이 BSD 계열이어야 가능한 관계로 그냥 수동으로 진행했다. 이 테스트는 conformance test에 비해 항목 수가 엄청나게 적지만, 매 항목마다 서로 다른 토폴로지를 구성하는게 오래걸린다.


Interoperability test 중 가장 애먹었던 부분은 이더넷 멀티캐스트 부분이다. IPv6는 이더넷 브로드캐스트를 사용하는 IPv4와 달리, DAD (Duplicate Address Detection) 등을 위해서 스코프가 한정된 멀티캐스트(i.e., all nodes, all routers)를 사용한다. 이러한 멀티캐스트 패킷은 목적지 주소로 IPv6 멀티캐스트 주소를 사용하며, 이 주소는 RFC 2464에 따라 이더넷 멀티캐스트 주소로 매핑된다. 통상의 스위치 허브들은 이더넷 멀티캐스트 프레임을 모든 포트로 내보내지 않는다. 즉, 어떤 포트로 이더넷 멀티캐스트 프레임이 들어가면, 스위치는 각 포트에 연결된 장치의 MAC 주소에 따라서 내보낼지 안내보낼지 여부를 결정하는 것이다. 이러한 이유로 시험 결과서 제출시 함께 제출해야 할 패킷 캡쳐를 하는 것도 불가능하고, DAD 같은 것은 시험 자체를 진행하는 것이 불가능했다. 구글링 결과, 통상의 스위치 허브보다 훨씬 다양한 기능을 제공하는 managed switch가 있으면 해결이 된다. Managed switch에는 모든 포트로부터의 입력 패킷들을 관찰할 수 있는 포트 미러링 기능이 있어 패킷 캡쳐할 때 사용할 수 있고, 멀티캐스트 프레임을 강제로 모든 포트로 내보내게 하는 등 설정을 할 수 있다. 다행히 연구실에 여분의 스위치 중 managed switch인 Cisco 300 스위치가 있어서 시험을 성공적으로 진행할 수 있었다.

모든 시험 항목이 완료되면, IPv6 Ready 사이트를 통해 시험결과서를 제출하면 된다. 제출 시 examination lab을 선택해야 하는데, 우리나라에는 TTA가 이 역할을 한다. TTA는 시험결과서를 검토하고 미비한 부분에 대해서 알려주게 된다. 그러면 다시 부족한 부분을 고쳐서 올리고, 이런 과정을 반복해서 최종적으로 TTA가 리뷰를 완료하게 되면, 타 lab들에 의한 public review까지 거쳐서 최종적으로 로고를 획득하게 된다. IPv6 Ready 사이트를 거치지 않고, TTA를 통해서 바로 시험 진행이 가능하기도 하다. 이러한 경우 비용은 조금 더 올라가지만 테스트별 삽질을 대행해주니 개발자의 정신건강에 도움이 되기도 할 것 같다. NanoQplus의 경우 앞서 언급한대로, scratch 단계에서부터 손수 구현한 것이라 시험하면서 디버깅을 해야 해서 사실상 시험대행이 불가능했던 점은 있다. 하지만, 이런 경우가 아니라면 TTA Verified 인증을 통해 대행 서비스를 이용할 것을 강추(!!)한다.

TTA의 리뷰를 거치면서 MS Windows 7에 얽힌 에피소드도 있다. MS Windows 7은 interoperability test 중 호스트로 사용했었는데, 표준대로 동작하지 않는 Windows 7 때문에 일부 항목을 Windows XP로 바꿔서 다시 진행했어야 했다. 시험 항목 중에 all nodes link-local multicast 주소로 ping을 보내면 응답이 오는지 여부를 검사하는 것이 있었는데, 이게 문제가 되었다. Windows 7에서 all nodes link-local multicast (ff02::1)로 ping을 보내면, 타겟장치가 이에 해당되기 때문에 응답을 한다. 반면, 타겟장치에서 ping을 보내면, Windows 7은 멀티캐스트 멤버이어야 함에도 응답하지 않는다. 방화벽을 풀어봐도 소용없다. 그냥 보안상의 이유로 막아놓은 것으로 보인다. 그래서 결과보고서에 코멘트를 달아서 보냈는데, TTA에서 이를 지적한 것이다. 결론은 호스트를 바꿔야 한다는 것. 결국 Windows XP 노트북을 동원해서 몇가지 실험을 다시 해서 보냈다.

인증이 완료된 것은 3월이고, ETRI 차원에서 보도자료가 나간 것은 4월. 계속 마음속으로 '블로그에다 글 하나 남겨야 하는데...' 하고 생각만하다가 드디어 포스팅을 하였다. 이 글을 쓰면서 다시 지난 날들을 돌이켜보니 힘들었던 순간들이 다시금 떠오른다.ㅎㅎ 참고로, 모든 시험을 끝내고 IPv6 Ready에 등록했던 순간이 2014년 1월 31일 설날 밤 12시를 막 넘긴 시점이었다. 곧 끝낼 수 있으리란 마음으로 설 연휴 첫날에도 출근해서 야근을 했었고, 저녁도 거른체 마무리를 지은게 밤 12시. 설날 밤 12시에 편의점에서 컵라면 한 그릇 먹고 집에 들어가 잤던 기억이 난다. 그 때 그 순간의 심정은 참...ㅎㅎㅎ

2014년 5월 6일 화요일

블로거에서 구글 웹 폰트 사용하기

네이버 블로그에서 벗어나 Blogger에 적응 중인 여자친구를 위해 바칩니다.ㅋ

1. 구글 웹 폰트

https://www.google.com/fontshttp://www.google.com/fonts/earlyaccess

2. 마음에 드는 글꼴 찾았으면, CSS에 추가.

'Blogger 템플릿 디자이너' - '고급' - 'CSS 추가'
link 태그를 사용하던가, import를 사용하던가 해서 CSS에 추가

3. 블로그 글 쓰기 편집기에서 'HTML'로 바꾸고, 바꾸고자 하는 영역을 <span> ~ </span> 태그로 지정

4. <span style="font-family: ~~~">로 폰트 지정

<span style="font-family: 'Nanum Brush Script', cursive;">나눔 붓 글씨</span>

나눔 붓 글씨

5. 페이지 전체의 글꼴을 바꾸고 싶은 경우, 템플릿 HTML 편집

템플릿마다 다를 수 있지만, 대충 비슷비슷할 듯?

<head>~</head> 내에 <Variable name="body.font" description="Font" type="font" default="~~~" value="~~~"/>를 찾아서, default와 value 값을 원하는 폰트로 바꿔주면 됨.

자세한 것은 레이아웃용 글꼴 및 색상을 참고하세요. :)

끝!

2014년 4월 10일 목요일

터미널에서 클립보드로 복사 & 붙여넣기

그 동안 터미널의 출력 내용을 메일에 써 넣을 때 양이 너무 많을 경우, 파일로 pipe시키고, 파일 내용 터미널 외의 편집기 프로그램에서 읽어 copy & paste를 해왔다. 매번 파일 만들고, 지우고, 너무 번거로운 것 같아 터미널에서 클립보드로 접근하는 방법을 찾아보니, 역시 방법은 다 있더라.

http://stackoverflow.com/questions/749544/pipe-to-from-clipboard

터미널에서 클립보드 접근하는 방법은 운영체제마다 다 다른데, 내가 사용하는 Mac OS X에서는 pbcopy, pbpaste를 사용하면 된다.

https://langui.sh/2010/11/14/pbpaste-pbcopy-in-mac-os-x-or-terminal-clipboard-fun

2014년 3월 17일 월요일

Safari에서 PDF 뷰어를 Preview로 사용하기

iPhone에서는 Google Chrome보다 Safari의 사용이 편하기에 기본 브라우저를 바꾸기로 결심. 이왕에 바꾸는 김에 데스크탑 브라우저도 바꾸는게 iCloud에 연동 등등에 편하지 않을까 해서 바꿔봤는데, PDF를 브라우저 내에서 보기가 시원치않았다.

해결방법은 생각보다 간단하다.

출처: https://igppwiki.ucsd.edu/groups/publichelpwiki/wiki/a1538/Howto_Disable_Acrobat_as_the_Safari_PDF_Viewer.html

근데 난 Adobe Reader를 설치한 적이 없는데 왜 깔려있는건지 모르겠다.


휴~ 이제 IEEE Xplore에서 논문보기가 편해졌구나.ㅋㅋ

2014년 2월 11일 화요일

ARM용 GNUC 툴체인 삽질

NanoQplus는 실제 산업현장부터 많이 적용되다 보니, ARM 프로세서용 툴체인으로는 IAR EWARM과 Keil MDK-ARM을 먼저 지원하게 되었다. 그 둘은 한 카피 당 가격이 500~600만원을 호가하는 관계로 개인용으로는 적합하지 않다. 그 동안 과제 준비와 업체 지원으로 정신이 하나도 없었는데, 약간 짬이 되는 요새를 틈타 그 동안 미뤄왔던 bare metal용 ARM GCC를 적용해보았다.

툴체인은 GNU Tools for ARM Embedded Processors 4.8. LaunchPad에 둥지를 틀고 있는 프로젝트인데, 가장 최근까지 업데이트를 계속 이어가는 것으로 보인다. 게다가 다운로드 섹션을 보면, Linux 뿐만 아니라, Windows, Mac OS X 버전까지 지원하고 있는 것으로 봐서 믿음까지 간다.

타겟 보드는 STM32 기반 Mango EToI. 조만간 공개될 NanoQplus 공개버전에서 레퍼런스 보드로 활약할 녀석이다. IAR EWARM으로는 잘 동작하는 것을 이미 확인하였으므로, 보드에는 거의 문제가 없다고 봐도 된다.

일단, Makefile은 GCC 패키지 내 샘플을 참조하였다. Linker script는 STM32F10x standard periph library에 있는 예제와 템플릿을 참조하였다.

이제부터 문제 시작!

1. OS interface

시작부터 컴파일 에러를 뱉지만, 당황하지 않고 newlib manual에 나온대로 minimal implementation으로, 끝!

2. main() 진입 전 멈춤

뭐, 쉽게 될꺼라 생각하진 않았지만, main() 조차 들어가지 않으니 당혹스러웠다. Linker script에서는 시작 지점을 Reset_Handler로 지정한 상태. Reset_Handler에서는 data 영역 및 bss 영역 초기화 후, 클럭 설정을 위한 SystemInit()main()을 차례로 호출하게 되는 것... 으로만 생각했으나, STM32 라이브러리에 있는 startup 어셈 코드를 잘 보니 그 사이에 __libc_init_array() 를 한번 다녀온다. 구글링을 해보니 C++ constructors를 위한 초기화 코드를 부르는 영역이란다. 헌데, NanoQplus는 C++을 지원하지 않으니 이 부분을 주석 처리했다. 안되는 것도 이상하긴 하지만, 일단 main() 이라도 들어가보자는 정신으로 과감히 제거! LED를 깜빡거리는 데까지, 끝!

3. printf() 호출 시 멈춤

역시 한번에 넘어가주면 섭섭하다. 다시 구글링 결과, printf() 호출 전에는 setvbuf()stdin, stdout, stderr용 IO 버퍼를 설정해야 한단다. 버퍼를 사용하지 않으므로, 세번째 인자를 _IONBF로 지정하여, 끝!

4. setvbuf() 호출 시 멈춤

이때부터 제대로 멘붕. 찾다 찾다 비슷한 사례로 data 영역이 초기화 되지 않을 경우, malloc()에서 멈추는 현상이 있다고 해서 의심해보기도 하고, QEMU에서 에뮬레이팅 하려다 실패하기도 하고, OpenOCD로 디버깅 연결을 시도하기도 하고, map 파일과 list 파일 들여다보기를 수차례, 거의 포기 직전까지 갔다. 그러다 map 파일을 보고 '아!' 하는 순간이 왔다. 바로 링킹된 libc.a가 이상한 것을 발견했다. 다시 한번 컴파일러 옵션과 링킹 옵션을 확인해보니 컴파일러에는 -mcpu=cortex-m3 -mthumb가 되어 있는데, 링커에는 -mthumb가 빠져있었다. 그래서 Thumb이 아닌 ARM mode 버전의 libc.a가 연결된 것. 결국 이것도 해결하고, 2번 문제도 원상복구했다. 이것 찾으려고 하루가 꼬박 걸렸네. 암튼, 끝!

5. 멀티쓰레드 컨텍스트 스위칭 중 멈춤

NanoQplus는 멀티쓰레드를 지원하기 때문에 새 MCU를 포팅하거나 새 툴체인을 적용할 때 반드시 통과해야 하는 관문이 멀티쓰레드이다. 특히, 컨텍스트 스위칭 부분은 어셈블리 코드 등으로 구성되며 프로세서나 툴체인에 의존적인 부분이 많아 늘 한번에 통과되지 않는 부분이다. 이번에도 역시 쓰레드간 컨텍스트 스위칭 중 HardFault가 발생하며 멈췄다. 컨텍스트 스위칭 부분의 함수는 어셈블리로 구성된 함수로 보통 함수의 진입과 종료시 붙는 스택관련 시퀀스가 붙으면 안된다. 따라서, __attribute__ ((naked))를 함수선언부에 붙여줘야 한다. 이걸로 끝!

우여곡절 끝에 적용이 끝났다. 물론 다른 것들도 테스트해봐야 하지만, 대부분 STM32 StdPeriph Library에 의존적인 부분이라 잘 통과될 것 같다. ARM GCC가 standard library로 newlib을 이용하기 때문에 혹시나 용량이 너무 커지지 않을까 걱정했는데, 최근에 추가된 newlib-nano (--specs=nano.specs)를 사용하게 하니 용량도 걱정 없을 듯 싶다. 당분간은 ARM GCC만 쓰게 될 듯...

아, 그리고 공개버전용 소스코드도 조만간 공개 예정!