X-HYPER320TKU_응용교재_V1.1.hwp

Size: px
Start display at page:

Download "X-HYPER320TKU_응용교재_V1.1.hwp"

Transcription

1 X-Hyper320 TKU 기반의 임베디드 시스템 응용과 실습 하이버스(주) - 1 -

2 목 차 이론편 1. 임베디드 시스템 4p 1.1 임베디드 시스템의 개요 1.2 임베디드 시스템의 활용 1.3 임베디드 시스템의 향후 전망 1.4 임베디드 프로세서 (Marvell Monahans PXA320) 1.5 임베디드 소프트웨어 1.6 임베디드 리눅스 시스템 1.7 임베디드 시스템 개발 환경 2. X-Hyper320TKU 임베디드 시스템 17p 2.1 X-Hyper320TKU의 특징 2.2 X-Hyper320TKU의 구성 2.3 X-Hyper320TKU의 하드웨어 2.4 X-Hyper320TKU의 메모리 맵 2.5 X-Hyper320TKU의 Pin Assign Table 3. X-Hyper320TKU 환경설정 53p 3.1 Overview 3.2 Quick Start 3.3 개발환경 - 2 -

3 실습편 Chapter 1. 스톱워치 65P Chapter 2. MP3 Player 78P Chapter 3. 산성비 게임 93P Chapter 4. DC 모터 제어 108P Chapter 5. CGI를 이용한 DC 모터 원격 제어 114P Chapter 6. Hmote2420 연동 시리얼 모니터링 134P Chapter 7. Berkeley DB 응용 145P Chapter 8. GTK Painter 163P Chapter 9. PXA Camera 185P Chapter 10. SDL 애니메이션 210P Chapter 11. Qtopia Core-4 포팅 실습 226P Chapter 12. 리눅스 기반의 무선 NAT 라우터 구축 240P - 3 -

4 제1장 임베디드 시스템 1.1 임베디드 시스템의 개요 임베디드 시스템(embedded system)이란 어떤 시스템에 내장되어 특정한 목적만을 수행하는 컴퓨터의 하드웨어와 소프트웨어가 결합된 고기능의 전자 제어 시스템을 말한다. 임베디드 시스 템의 일반적인 의미는 마이크로프로세서/마이크로컨트롤러를 내장(embedded)하여 원래 제작자 가 의도한 특정한 기능만을 수행하는 장치이다. 임베디드 시스템의 구성을 살펴보면, 임베디드 하드웨어는 임베디드 프로세서/임베디드 컨트롤 러, 메모리, I/O 장치, 네트워크 장치, 센서, 구동기 등으로 구성되어 있고 임베디드 소프트웨어는 운영체제, 시스템 소프트웨어 및 응용 소프트웨어로 구성되어 있다. [그림 1-1] 임베디드 시스템의 구성 임베디드 시스템의 특징은 특정한 기능에 부합하는 최적화(application- specific functionality), 소형, 경량화, 저전력화, 고신뢰성이면서 네트워크를 지원하고 멀티미디어를 지원 하는 시스템으로 실시간 운영이 되는 열악한 환경 하에서도 데드라인(deadline) 이내, 즉 반응에 요구되는 시간의 한계 값에 논리적으로도 결과 산출에 걸리는 시간에서도 적시성(timeliness)을 가지며 외부 자극에도 예측 가능한(predictable) 방식으로 반응하는 시스템으로서 가격에 민감하 고 안전하게 동작할 수 있는 시스템의 특징을 가지고 있다

5 [그림 1-2] 임베디드 시스템의 특징 실시간 시스템(real time system)의 정의는 정해진 시간 내에 시스템이 결과를 출력하는 시스템 을 말한다. 이는 주어진 작업을 빨리 처리하는 것이 아니고 정해진 시간을 넘어서는 안 된다는 뜻이다. 실시간 시스템의 분류는 하드웨어 실시간 시스템(hardware real-time system)과 소프트 웨어 실시간 시스템(software real-time system)으로 분류된다. 1 하드웨어 실시간 시스템은 정해진 시간(deadline) 내에 즉, 시간 내에 처리하지 않으면 치명 적인 결과를 초래하는 경우에 작업의 결과가 절대적으로 출력되어야 하는 시스템으로 주로 전투 기의 비행제어 시스템, 핵발전소의 제어 시스템, 인공위성의 제어 시스템 등이 이에 해당된다. 2 소프트웨어 실시간 시스템은 정해진 범위를 넘는 시간(deadline) 지연이 발생하더라도 그것이 시스템의 에러가 되지 않는 시스템으로 주로 컴퓨터, 정보기기, 네트워크 관련기기 등이 이에 해 당된다. 임베디드 시스템은 대부분 실시간적인 요소가 내포되어 있고 실시간 시스템이 포함되어 있어야 한다. 1.2 임베디드 시스템의 활용 정보가전 : 세탁기, 오디오, 인터넷 냉장고, HDTV 등 제어분야 : 공장자동화, 가정자동화, 로봇 제어, 공정제어 등 정보기기 : 핸드폰, PDA, 스마트 폰, LBS 등 네트워크기기 : 교환기, Router, 공유기, 홈 게이트웨이 등 게임기기 : 가정용 게임기(PS2, Xbox, PSP), 지능형 장난감 등 항공/군용 : 비행기, 우주선, 로켓, 야전 이동단말(GPS, GIS) 물류/금융 : ATM, RFID, 물류단말, 영업단말 등 차량/교통 : 자동차, ITS 등 사무, 의료 : 전화기, 프린터, Heart pacer, 수술로봇, 증강현실장비 - 5 -

6 [그림 1-3] 임베디드 시스템의 응용 1.3 임베디드 시스템의 향후 전망 프로세서 대부분의 프로세서가 임베디드 시스템용으로 사용한다. 데이터 처리용량 증가로 인하여 32비트 코어에서 64비트 코어로 발전한다. 고성능의 파이프라인, DSP, 자바 처리 전용 H/W 추가한다. 많은 종류의 마이크로프로세서/컨트롤러들 중에서 응용에 최적인 제품을 찾아내는 것이 설계 에서 매우 어렵고 중요한 작업이다. SOC(System-On-a-Chip) CPU, 메모리, DSP, I/O 등을 하나의 칩으로 만드는 기술로써 CPU칩, 메모리 칩, 주변장치 칩 들을 따로 사용하여 설계한다. 각 칩에 해당되는 회로를 각각의 IP(Intellectual Property 또는 지적재산권)로 확보해서 한 개의 칩으로 설계한다. 수백만 게이트 급의 칩으로 제작된다. [그림 1-4] 임베디드 시스템의 향후 전망 - 6 -

7 [그림 1-5] 새로운 시대의 가능성 1.4 임베디드 프로세서 (Marvell Monahans PXA320) 임베디드 프로세서는 8비트에서 64비트까지 다양한 종류와 특징을 가지고 있다. 특히 <표 1-1>에서 보는바와 같이 프로세서의 CISC와 RISC별, 제조사별 다양한 종류가 생산되 고 있다. 프로세서 제 조 사 종 류 8051계열 Atmel, Cirrus, intel, TI 등 8051 PowerPC계열 모토로라(현재 ; Freescale) MPC860,850,8260 ARM계열 ARM ARM7, ARM9, ARM10, ARM11 INTEL계열 Intel strongarm, Xscale(PXA255), Bulverde(PXA270) 삼성계열 삼성Korea S3C2410, S3C2440 등 MIPS계열 MIPS MIPS32,MIPS63 등 X86계열 AMD, Intel 등 I386,I686 등 <표 1-1> 임베디드 프로세서의 종류 본 임베디드 시스템에 사용된 프로세서는 Marvell PXA320 32비트 고성능 프로세서로 제작되었 다. PXA320은 기존의 PXA270에 비해 성능 개선, 연장된 배터리 수명을 제공하기 때문에 비디 오와 오디오 능력의 개선을 실현할 수 있게 한다. MusicMax 기술을 채택한 Wireless Intel SpeedStep(R) 은 지능형 전력관리 기능을 제공해 가변적인 전력상태를 가능케 하기 때문에 사 용자들은 배터리 수명에 손상을 주지 않으면서도 핸드셋에서 최고 30시간까지 MP3를 재생할 수 있다

8 PXA3x0 애플리케이션 프로세서 제품군에 탑재된 Intel VideoMax 기술은 고성능 비디오 능력을 지원하며, PXA3x0 프로세서 제품군의 미래 버전에도 개선된 해상도를 계속 제공할 것이다. 전력 효율적인 비디오 플레이백과 캡처능력은 고해상도 콘텐츠를 가능케 해주며 30fps에서 최고 D1 해상도까지의 풍부한 비디오 품질을 위해 H.264 같은 첨단 코덱을 지원한다. PXA3x0 제품군은 또한 디지털 카메라, 떨림방지 같은 첨단 카메라 효과, 최고 5 메가픽셀까지의 카메라 센서를 지 원한다. Intel XScale 프로세서 기술에서 기대되는 바와 같이, Marvell PXA3x0 프로세서 제품군은 주파수 확장과 범용 컴퓨팅 능력부문에서 시장을 계속 리드해 나가고 있다. 사용자들은 Marvell PXA3x0 프로세서 기반의 휴대전화와 소비자용 핸드헬드 기기들을 체험한 후에는 "624 또는 806Mhz로의 확장성"이라는 것이 즉각적인 반응 (기다리지 않음)뿐만 아니라 배터리 수명의 연장도 의미한다 는 사실을 바로 이해하게 될 것이다. 마벨의 독자적인 구조개선은 운영환경과 범용 애플리케이 션이 높은 주파수로 임무를 신속하게 처리한 후 저전력 소비상태로 효과적으로 축소될 수 있게 한다. 이러한 기능은 Marvell PXA 3x0 프로세서들이 작동이 느린 경쟁제품들에 비해 전체적으로 더욱 훌륭한 전력효율성을 제공한다. 소비자 관점에서 볼 때, 배터리 수명에 손상을 주지 않으면 서 성능이 크게 개선되는 것을 발견한다는 것은 "624 또는 806Mhz로의 확장성"이 2007년에 핸 드헬드 기기의 큰 특징으로 만들어 줄 것이다. PXA3x0 제품군은 사용자들에게 성능이나 배터리 수명에 손상을 주지 않고 옵션형의 안전한 프 레임워크 내에서 이동중에도 웹 브라우징과 고급 뮤직감상 및 최신 비디오 시청을 가능케 해준 다. 무선통신 고객들은 이메일을 검색하거나, WIFI를 통해 액티브 콘텐츠를 열어 보거나, 개인화 된 MIDI 통화연결음과 콜러 ID를 사용해 휴대전화 통화를 하면서 스테레오 블루투스* 헤드셋을 통해 음악을 들을 수 있다. 마이크로소프트*, 리눅스, 팜* 그리고 RTOS 스펙트럼 오퍼링 이용이 가능한 솔루션을 가능케 해주는 플랫폼을 통해서, 기기 개발자들은 고객들의 요구를 충족시키는 체험, 애플리케이션 및 서비스를 선택할 수 있다. 다양한 운영환경을 개발하는 것은 다양한 무선 통신 사업자들의 요구에 대응하는 제조업체들에게 개발작업을 보존하고, 제품의 시장화 시간을 단축시키며, 위험을 줄여준다. ARM* 아키텍처에 따를 경우, 기존의 ARM 기반 애플리케이션은 PXA3x0 제품군에 신속하게 이식될 수 있다. 마벨은 또한 현재 셀룰러 베이스밴드 프로세서인 PXA 800 (사내 코드명칭: 하몬 (Hermon)) 시 리즈를 대량 출하하고 있다. 마벨 애플리케이션과 셀룰러 베이스밴드 프로세서를 업계를 리드하 는 마벨의 스토리지, WLAN, 전력관리, VOIP 및 블루투스 솔루션들과 결합할 경우, 개발자들에 게 다양한 시장부문들의 요구와 가격 포인트를 충족시키는 광범위한 종류의 무선 핸드헬드 기기 들을 개발할 수 있는 종합적인 플랫폼을 제공할 것이다

9 [그림 1-6] PXA320 Processor Block Diagram CPU 클록 Monahan PXA3x0 최대클록주파수;806MHz ARM구조 v.5te compliant PXA270보다 30% 더 빠른 코어 스피드 시스템 버스의 분리로 병목 현상 제거 LCD 및 mini lcd controller로 2개의 LCD를 필요로 하는 smart phone에 적용 장점 Bulverde PXA27x 624MHz ARM구조 v.5te compliant CPU core ARM11 ARM9 Internal SRAM Application SRAM Touch screen controller External memory Power consumption Camera interface 6(banks) x 128(KB)=768KB 메모리 버스의 병목현상 제거 768KB VGA 또는 그보다 작은 해상도의 저전력 refresh를 위한 Frame buffer touch screen controller 내장 separate x32 external memory interfaces for DDR and for Flash (Intel Flash or Nand) 고성능의 우수한 장치를 위해 조정된 속도와 대역폭 및 Nor, Nand 지원 Enhanced wireless intel speedstep technology 동일 주파수에서 PXA270보다 50%까지 전 력 소비 감소 Enhanced intel quick capture technology 5Mega pixel (2560 x 2048)까지 지원 향상된 카메라 인터페이스 4(banks) x 64(KB) = 256KB 256KB 없음 Single shared external memory interface Wireless intel SpeedStep technology Intel quick capture technology <표 1-2> PXA320과 PXA270 비교 - 9 -

10 1.5 임베디드 소프트웨어 임베디드 소프트웨어란 임베디드 시스템에 탑재되는 소프트웨어를 말한다. 임베디드 시스템의 응 용 분야가 다양해지면서, 예전에는 단순했던 임베디드 소프트웨어가 점점 더 복잡하고 다양한 기능을 처리하게 되었다. 임베디드 OS를 사용하는 이유는 인공위성이나 미사일 제어 등과 같이 오류에 견고한 시스템이 나 실시간 시스템을 위해 최적화된 운영체제가 필요할 경우이다. 이러한 경우에는 다양한 목적 의 범용적인 운영체제보다는 RTOS(Real Time Operating System)와 같은 임베디드 OS를 사용 한다. RTOS는 표준 하드웨어 환경이 정해져 있지 않다는 점이 윈도우나 유닉스 등 범용 운영체제와 커다란 차이이며, 이는 곧 응용 프로그램뿐 아니라 운영체제 자체에 대해서도 사용자가 환경을 설정해야 하고 때에 따라서는 포팅 노력이 요구된다는 뜻이다. 그리고 시스템의 하드웨어 자원, 특히 메모리 사용에 대해서 많은 제약이 따른다. 예를 들어 일반 OS에서 작동하는 응용 프로그램이 몇 백 KB 메모리를 더 사용한다고 해서 무슨 큰 문제가 되는 것은 아니다. 그러나 임베디드 시스템에서는 메모리를 더 사용하면 그만큼 제품 단가가 올라가고, 특히 이동 환경에서는 제품의 크기와 전지의 사용 시간에도 직접적인 영향을 주게 된다. RTOS는 실시간 처리에 대한 강력한 지원과 통합 개발 및 디버깅 환경을 지원한다. RTOS는 그 종류는 대단히 많이 있다. 대표적으로 화성 착륙선인 패스파인더(PathFinder)와 혼다에서 만든 로봇인 아시모(ASIMO)의 운영체제로 쓰인 윈드리버(WindRiver)의 VxWorks, ISI에서 개발해서 지 금은 윈드리버에 통합된 psos, Mentor Graphics의 VRTX, 윈도우 CE 닷넷, 윈도우 XP 임베디 드, 임베디드 리눅스 등이 있으며 교육용으로 만들어진 uc/os-ii가 있다. 임베디드 시스템의 운영체제(OS) 임베디드 시스템(embedded system)이라는 것은 통상적으로 일반적인 시스템과는 달리 특정한 작업만을 수행하도록 설계되며 초기의 임베디드 시스템은 비교적 아주 단순해서 특별한 운영체 제가 필요 없이 사람이 순차적인 프로그램을 작성해서 실행하도록 되어있고, 중간에 인터럽터가 발생되는 경우에만 그 순차적인 프로그램에서 잠시 벗어나는 정도였다. 이전의 임베디드 시스템 들은 주로 간단하고 단순한 순차적인 작업에 관련되었기 때문에 굳이 운영체제(OS : Operation System)를 사용한다는 것은 낭비가 되었고 그럴 필요조차 없었다. 최근의 임베디드 시스템 분야에서는 그 시스템 자체가 상당히 커지게 되고, 네트워크나 멀티미 디어가 시스템에 기본으로 포함되면서 임베디드 시스템이 해야 할 일들도 많아지고 복잡해졌기 때문에 순차적인 프로그램을 작성하기가 매우 어렵게 되었다. 따라서 임베디드 시스템에서는 운영체제의 개념이 필요하게 되었고 임베디드 시스템의 특성상 실시간(real time)이라는 요소를 만족해야 하였으므로 실시간 운영체제가 임베디드 시스템에 도 입되게 되었다. 지금도 실시간 RTOS를 채택하여 개발 되는 제품들이 점점 늘어나고 있는 추세이며, 이제는 수 많은 임베디드(embedded)시스템에서 그 목적에 맞게 실시간 운영체제와 함께 적절하게 사용되 고 있는 실정이다. 그리고 임베디드 운영체제(embedded operation software)는 크게 아래와 같이 RTOS(Real

11 Time OS)와 GPOS(General Purpose OS)로 분류할 수 있다. Window CE Window CE는 마이크로소프트사에서 개발한 임베디드 시스템용 운영체제이다. 마이크로소프트(이하 MS)는 임베디드 시장에 대한 공략을 위해 1996년 윈도우 CE를 발표했다. MS에서 제작된 기존의 윈도우 인터페이스에 모바일 네트워크 기능을 강화해 가전제품, PDA, 셋 톱박스 등에 주로 사용되고 있다. 적외선 통신, 웹 브라우징 기능 이외에도 편리한 개발환경을 가지고 있으며 UI가 기존의 윈도우와 매우 유사하게 제작돼 있어 대부분의 사용자들은 별도의 학습 없이도 바로 사용이 가능하다. 또한 윈도우 CE 계열의 PDA는 흑백 및 컬러 디스플레이가 가능하며 동영상, WAV, MP3 등 멀티미디어 파일의 재생이 가능하여 PDA의 엔터테인먼트 기기 화를 가져왔다. 또한 PC용의 윈도우 OS나 각종 오피스 프로그램들과 완벽한 호환이 가능해 기존의 데스크톱이 나 노트북에서 가능하던 각종 애플리케이션들을 PDA에서도 그대로 사용할 수 있다는 이점이 있 다. 그러나 제한적인 하드웨어를 가진 임베디드 시스템에 너무 많은 기능을 구현하려 했기 때문 에 느린 실행 속도와 불편한 UI를 초래했다. 이를 개선해 MS는 2000년 4월 윈도우 CE 3.0을 개발하고 기존의 윈도우 CE와는 전혀 다른 것 이라는 것을 강조하기 위해 그것을 포켓PC(PocketPC)라고 명명했다. 포켓PC의 등장으로 기존 윈도우 CE에서 보여주었던 수행속도의 저하와 비효율적인 하드웨어의 활용 등의 문제점들이 보 완됐다. 윈도우 PC는 사운드와 동영상 재생 및 컬러 디스플레이 구현 등 다양한 멀티미디어 기 능을 기본적으로 제공하며 PC와의 호환성이 뛰어나다. 또한 포켓 인터넷 익스플로러를 기본으로 내장해 모바일 인터넷을 실현했다. 게다가 데스크톱과 거의 흡사한 UI를 갖춤으로써 윈도우에 익 숙한 사용자들을 쉽게 끌어들이고 있다. 그럼에도 불구하고 PDA 업계에서 윈도우 CE의 시장점 유율은 팜 OS에 미치지 못했다. 하지만 유명 PDA 업체들이 윈도우 CE 채용 제품들을 대거 출 시함에 따라 점유율은 계속 증가 추세에 있다. 윈도우 CE는 성능이 상당히 우수하며, 특히GUI환경과 많은 어플리케이션을 가지고 있어서 현재 널리 사용되고 있다. 멀티 태스킹 오퍼레이팅 시스템인 Windows CE는 32개에 달하는 동시 프 로세스를 지원하고 각각의 프로세스는 어플리케이션의 단일 개체이다. 또한, 멀티 스레딩 지원은 각각의 프로세스가 다중 실행 스레드를 생성할 수 있게 한다. 스레드(thread)는 다른 부분들과 병행하여 실행되는 프로세스의 한 부분이며 스레드(thread)들은 독립적으로 실행한다. 그러나 각 각의 스레드는 특별한 프로세스에 속하고 같은 메모리 공간을 공유한다. 스레드들의 총 수는 단지 사용 가능한 물리적인 메모리에 의해 제한된다. Windows CE는 최소 의 프로세서 자원에서 스레드 동기화를 실현한다. 그리고, 다른 많은 오퍼레이팅 시스템과는 다 르게 Windows CE 는 스레드와 관련된 작업, 즉 스케줄링, 동기화, 자원관리 등을 다루는 것은 커널을 이용한다. 따라서, 어플리케이션은 다른 스레드 함수들로 프로세스나 스레드의 수행과 완료를 위한 폴(poll) 이 필요하지 않다. Windows CE는 선점형이기 때문에 우선순위가 더 높은 프로세스나 스레드가 선점적인 실행을 해야 한다. 그것은 스레드 스케줄링을 위해 여섯 개 등급인 스레드 우선순위를 기초로 한 시분할 알고리즘을 사용한다. Windows CE 는 선택한 수의 네트워크 스택을 제공한다. 네트워크 통신들은 적외선 통신, 이더넷, 무선 통신을 포함한 여러 가지 하드웨어를 지원한다. 비 록 네트워크 스택이 윈속 인터페이스를 통해 유일하게 접근할 수 있어도 Windows CE 는 또한 내 부적으로 윈속에 사용하고 윈속 연결을 설정하고 관리하는 섬세한 부분을 다루는 여러 가지 상위

12 레벨의 API들을 제공한다. WinInet API는 FTP와 HTTP 1.0을 포함한 인터넷 브로우징 프로토콜들을 지원한다. 또한Secure Sockets Layer(SSL) 2.0, Secure Sockets Layer(SSL) 3.0 그리고 Private Communication Technology(PCT) 1.0을 포함한 세 가지 보안 프로토콜의 접근을 제공한다. WinInet API는 Common Internet File System(CIFS) 리디렉터를 통한 원격 파일 시스템의 접근을 제공한다. 적 외선 통신을 위해 Windows CE 는 산업 표준 IrDA 프로토콜들을 사용하는 소켓 기반 적외선 통 신이 가능한 윈속에서 확장된 IrSock을 지원한다. Windows CE는 윈속으로써 네트워크 스택과 같은 레벨인 RAS 클라이언트를 제공한다. 인터넷을 위해 개발된 TCP/IP 프로토콜 그룹은 가장 복잡하고 넓게 알려진 네트워크 프로토콜이다. 그것 은 광범위한 시스템에 의해 지원되고 Windows CE 네트워크 스택의 핵심을 형성한다. 많은 윈 도우 기반 이동 장치들은 무선 통신을 사용할 수 있다. 그러나, 전통적인 TCP/IP 스택은 유선 네트워크에서 효과적인 함수에 의해서 만들어지기 때문에 무선 기술에서는 불충분하게 동작 할 수 있다. 그러나, Windows CE TCP/IP 스택은 무선 네트워킹을 위해 설정되게 디자인 되었다. 네트워크 스택의 기반에 있어서 Windows CE 는 시리얼 연결 네트워크와 LAN을 위해 데이터 연결 계층 을 지원한다. 많은 Windows CE 기반 장치들은 모뎀과 같은 시리얼 통신 연결을 사용하여 네트워크에 연결한 다. 시리얼 연결 네트워크를 지원하기 위해 Windows CE 는 많이 사용되는Serial Line Internet Protocol(SLIP)와 Point-to-Point Protocol(PPP)를 구현하였다. Password Authentication Protocol(PAP), Challenge Handshake Authentication Protocol(CHAP)와 Microsoft CHAP의 세 가지 프로토콜들은 시리얼 연결 통신에 사용하고 있다. LAN 연결에 대한 지원은 Windows CE에서는 NDIS((2) NDIS, Network Driver Interface Specification2) 4.0으로 구현하였다. 그러나, 단지 이더넷 미니 포트 드라이버들만 지원한다. 그리고 Windows CE를 여러 가지 다른 플랫폼의 사용자 입력 요구를 받아들일 수 있게 지정할 수 있다. 현재로, 키보드, 입력 패널, 음성 그리고 스타일러스는Windows CE 를 기반으로 한 장치들의 사 용자 입력 방법이다. MS는 윈도우 CE 3.0의 소스 코드를 공개한 후 2002년 초 코드명 탈리스커(Talisker)로 알려졌 던 윈도우 CE 닷넷과 윈도우 XP 임베디드를 공식 발표했다. MS는 윈도우 CE 닷넷을 Non-X86 프로세서 계열이거나 실시간이 요구되는 시스템에 대해서 권고를 하고 있으며 PC 운영체제인 윈도우 XP 프로페셔널의 컴포넌트 버전인 윈도우 XP 임베디드는 네트워킹과 서버 기능을 수행 하는 시스템 개발에 권고를 하고 있다

13 1.6 임베디드 리눅스 시스템(Embedded Linux System) 리눅스란? 리눅스는 운영체제이다. 운영체제란 하드웨어와 응용프로그램, 혹은 사용자 사이에서 시스템을 제어하고 운영하는 프로그램이다. 엄밀한 의미로 말하면, 리눅스는 프로세스 스케줄링, 가상 메 모리, 파일 관리, 장치 입/출력이라는 기본적인 서비스를 제공하는 운영체제의 커널일 뿐이다. 초기의 리눅스는 핀란드 헬싱키 대학의 교수에 의해 개발된 유닉스 기반의 마이크로 커널 구조 를 가지는 인텔 프로세스에서 동작하는 운영체제인 미닉스(Minix)를 이 대학 학생인 리누즈 토발 즈(Linus Torvalds)가 수정하여 인터넷에 공개한데서부터 출발한다. 그 이후 리눅스는 전 세계의 해커들에 의해서 지속적으로 수정 보완 되면서 급속히 발전하여 왔다. 또한 리처드 스톨만(Richard Stallman)에 의해 창시된 자유 소프트웨어 재단(FSF:Free Software Foundation)과 노선을 함께하여 GNU GPL(General Public License)하에 커널 소스를 공개하여 오늘에 이르고 있다. 이러한 소스 코드 공개에 기초한 자유 소프트웨어 정신에 입각하 여 리눅스는 해커들에 의해 급속한 진전을 이루었으며, 비로소 1994년 5월에 커널 버전(리눅스 커널 버전이 홀수(odd)이면개발 버전, 짝수(even)이면 안정 버전임을 의미한다.) 1.0.0이 발표되 었고 1996년 6월에는 커널 버전 2.0.0이 발표되었다. 그리고 2001년 1월에는 커널 버전 이 발표되었다. 이제 리눅스는 저렴한 중소형 컴퓨터뿐만 아니라 서버급 컴퓨터에 널리 사용되 고 있는 실정이다. 또한, 최근에는 크기를 현격히 줄여 임베디드 시스템에 리눅스가 포팅되어 임 베디드 운영체제로 각광받고 있다. 리눅스는 유닉스 시스템의 표준 인터페이스로 자리잡고 있는 POSIX 표준을 따르고 있으나, 진정 한 자유 소프트웨어를 구현하기 위해 유닉스 소스 코드 사용을 배제하고, 모든 소스를 새로 작 성하였다. 초기의 리눅스는 i386이상의 x86 CPU를 탑재한 PC에서 운영되는 것을 목표로 하였 으나, 현재에는 Macintosh, SPARC, MIPS, Alpha f 머신 등에서 동작하는 최고의 이식성을 자랑 하는 운영체제가 되었다. 리눅스는 진정한 개념의 멀티태스킹이 가능하며, 가상 메모리를 구현하며, 공유 라이브러리, 메 모리 관리, TCP/IP 네트워킹과 유닉스 계열 시스템들이 가지는 특징들을 포함하는 공개 운영체 제인 것이다. 리눅스는 상용 임베디드 OS보다는 실시간적 요소를 충족하지 못하고 윈도우 CE보다는 개발환경 이 좋지는 않지만, 오픈소스에 라이선스 비용이 없기 때문에 커널 크기를 줄여 다양한 임베디드 시스템의 개발에 유리하다. 리눅스는 소스를 공개하는 오픈소스 정책을 따르는 관계로 관련 개발자가 세계 곳곳에 있어 현 지의 응용 프로그램을 개발할 수 있는 개발자 층이 넓다는 것이 다른 OS들과 구별되는 큰 장점 이다. 이에 따라 리눅스를 채용한 임베디드 시스템은 다른 제품에 비해 가격 경쟁력이 우수하고 다양한 응용 프로그램의 개발이 가능할 것으로 기대된다. 임베디드 리눅스는 소스 공개와 아울러 안정성, 신뢰성 및 성능의 확보에 따라 활용도가 급격히 증대되고 있으며, 레드햇, 몬타비스타, 리니오 등이 임베디드 리눅스 개발 및 기술 지원 사업에 주력하고 있다. 임베디드 리눅스 운영체제는 특정 어플리케이션에 맞도록 리눅스 커널을 최적화 한 것이다. 이 는 라이센스비가 무료이며, 커널 소스 또한 공개되며 현재 전 세계의 수 많은 개발자들에 의해 지속적으로 업데이트 되고 있다. 그러나 임베디드 리눅스는 열악한 개발환경에 따른 개발기간에 대한 부담과 라운드로빈 방식의

14 스케줄링을 하므로 실시간 시스템에는 적합하지 않다는 문제점을 가지고 있다. New Mexico Tech에서 기존 리눅스 커널에 실시간 기능을 추가한 RT-Linux를 개발했으며 또한 오픈소스 진 영에서는 임베디드 리눅스를 기반으로 한 표준화를 통해 시장 확대를 도모중인데, 2000년에 애 질런트, 알카텔, HP, IBM, 윈드리버, ARM, 모토롤라 등이 참여하는 세계 최대 규모의 임베디드 리눅스 컨소시엄(ELC:Embedded Linux Consortium)이 결성되어 임베디드 리눅스 및 실시간 운영체제 API 표준인 EL/IX(Em bedded Linux based on POSIX)를 기반으로 플랫폼 표준화를 추진하고 있다. 임베디드 운영체제 시장은 전통적인 RTOS 중심에서 다기능 임베디드 OS 중심으로 발전하는 추 세에 따라 VxWorks, psos 등의 RTOS의 시장 성장률이 둔화되고 있으며, 전용 실시간 임베디 드 시스템에서 높은 시장 점유율을 보였던 VxWorks, psos, VRTX와 같은 전통적인 RTOS는 2001년을 기점으로 시장 점유율이 하락하고 있다. 2003년에는 임베디드 리눅스, 임베디드 윈도우 CE 및 팜 OS 등의 임베디드 OS 시장이 기존의 RTOS 시장을 능가할 것으로 예측된다. 전통적인 RTOS의 시장 점유 하락으로 임베디드 OS 시 장에서는 MS와 임베디드 리눅스가 시장 선점을 위해 치열한 각축을 벌일 것으로 예상된다. 임베디드 리눅스의 장점 - 산학계에 걸친 수많은 사용자들로부터 지난 수년간 직접 사용되면서 검증된 들로 효율적이고 안정적이며 성숙된 내용을 가진다. - 오픈 소스이기 때문에 소스 코드 자체가 공개되어 있고 이의 공급에 따른 로열티 자체가 없기 때문에 부담 없이 쉽게 자체 개발 아키텍처에 공급할 수 있다. - 리눅스 커널 자체가 태생적으로 모듈 형식의 코드로 이루어져 있어 쉽게 최소, 최적화 가능하 다. - 네트워킹 어플리케이션에 필수적인 TCP/IP, PPP, X.25, HDLC, FDDI 등의 네트워크 코드를 가지며 그 종류에 있어서도 다양하고 무료로 사용할 수 있어 개발에 용이하다. - 네트워킹 디바이스에서 현존하는 거의 대부분의 프로세스에 포팅되어 있고 대부분의 컨트롤러 를 위한 디바이스 드라이버가 제공되기 때문에 그 공급 영역 또한 방대하다 - 사용자뿐만 아니라 개발자 그룹의 크기도 오픈 소스이면서도 개발을 위한 자체 툴과 라이브러 리를 가지고 있는 현대적인 운영체제라는 특성에 맞물려 전세계적으로 거대한 수의 개발자들이 존재한다. 따라서 어플리케이션은 물론 자체 문서도 거의 모든 영역에 대해 상용 운영체제 못지 않게 잘 이루어져 있다. - 이미 PC상에 리눅스 어플리케이션과 커널의 개발에 익숙한 사람들에게 있어 임베디드 리눅스 는 자신에게 익숙한 환경을 제공하기 때문에 쉽게 임베디드 어플리케이션을 개발할 수 있게 해 준다. 또한, 개발 툴은 어떤 운영체제나 아키텍처 상에도 포팅이 되어 있으므로 한번 개발 툴에 익숙해지면 개발 환경에 제약이 없어진다는 장점이 있다. - 실시간(real time)을 지원하여 지금까지 상용 OS에 열세였던 Real Time성을 크게 확보하고 보다 다양한 분야에 공급을 할 수 있다. 임베디드 리눅스의 단점 - 임베디드 리눅스(embedded Linux)위에서 실행될 수 있는 어플리케이션이 상당히 부족한 실 정이다. 따라서 임베디드 리눅스를 OS로 채택하고 이를 확산 시키는 데 걸림돌이 되고 있는 실 정이다

15 - 임베디드 리눅스(embedded Linux)를 이용하여 장비개발 시 개발환경에 접근하는 데 상당히 어렵다. 커널을 비롯하여 마이크로 프로세스(micro process), 네트워크, 각종 툴(tool) 등을 다루 어야 하는 내용이 방대하므로 단시일 내에 전문적인 개발자 양성에 문제가 있다. 1.7 임베디드 시스템 개발 환경 임베디드 시스템 개발 환경의 개요 임베디드 시스템 개발시 전체 시스템의 가격이나 소비되는 전력을 낮추기 위해 하드웨어 및 소 프트웨어의 많은 제한을 가하게 된다. 따라서 임베디드 시스템에 사용하는 OS는 일반적인 일반 OS보다는 시스템에 특화된 운영체제를 사용한다. 임베디드 시스템을 개발하기 위해선 기본적으로 다음과 같은 요소들이 갖춰져 있어야 한다. 호 스트PC 는 임베디드 시스템 개발을 위한 컴퓨터를 말하며, 타깃PC(Target PC) 은 실제 임베디 드 시스템이 설치된 개발하고자 하는 하드웨어를 말한다. 호스트에는 개발을 위한 개발 툴, 개발 된 응용 프로그램을 임시로 수행해 볼 수 있는 타깃 시뮬레이터, 타깃과 연결되어 타깃에 개발 된 이미지를 업로드하거나 타깃에 반응하는 디버그 에이전트를 통해 원격 디버깅을 할 수 있게 하는 타깃 서버가 설치돼 있다. 또한 타깃에는 호스트에서 만들어져서 설치된 여러 컴포넌트가 존재하는데 타깃을 부팅하기 위한 부트 로더와 커널, 그리고 임베디드 응용 프로그램이 존재하 게 된다. 호스트에 설치된 개발 툴에는 타깃에서 수행될 수 있는 바이너리를 생성하는 크로스 컴파일러가 존재하며 그 밖에 오류를 검색해 주는 디버거 등으로 이루어져 있다. 임베디드 시스템 개발 과정 임베디드 시스템 개발 과정은 대략적으로 부트 로더 개발, 커널 및 파일 시스템 개발, 응용 프로 그램 개발의 세 단계로 볼 수 있다 - 부트 로더 개발 부트 로더는 타깃 보드에 전원이 인가되면 부트 롬으로부터 가장 먼저 수행되는 프로그램이다. 보통 부트 로더는 OS의 커널을 로드하는 순수 로더로서의 기능뿐만이 아니라 현재 레지스터나 메모리 값, 버스 상태 등을 살펴볼 수 있는 모니터 기능, 기초적인 네트워크 모듈을 내장해 네트 워크를 통한 커널을 다운받아서 커널 로드를 할 수 있는 기능을 포괄하고 있다. 부트 로더는 보 통 부트 롬에 내장되어 있으며 부트 로더를 새로 작성하여 타깃에 설치하려면 호스트와 JTAG 인터페이스 혹은 기타 인터페이스를 통하여 설치할 수 있으며 이외의 방법에는 롬 라이터를 이 용하여 롬에 구워서 설치할 수 있다. 대부분 상용 임베디드 OS에서는 부트 롬 부분을 앞서 잠깐 언급한 BSP라 불리는 패키지의 일 부분으로 규정하고 있다. 반면 임베디드 리눅스의 경우는 규격화된 BSP가 존재하지 않으므로 하 드웨어 벤더가 리눅스용 BSP를 제공하지 않을 경우 부트 롬 부분을 각 하드웨어 플랫폼에 맞게 작성해야 한다

16 - 커널 및 디바이스 드라이버 및 파일 시스템 개발 커널 및 디바이스 드라이버의 개발은 호스트의 임베디드 시스템 개발 툴에서 이뤄진다. 개발을 위해서는 개발자가 먼저 시스템에 대한 하드웨어 사양을 숙지해야 하며 이를 바탕으로 커널 및 디바이스 드라이버를 설정하게 된다. 이렇게 생성된 커널 및 디바이스 드라이버들은 부트 롬과 같이 하나의 이미지 파일 형태로 되어 부트 롬에 저장되거나 별도의 저장 장치에 파일 시스템을 통한 파일 형태로 구현된다. 만일 부트 롬의 용량이 작거나 기타 저장장치가 없는 경우 부트 로 더에서 네트워크 모듈을 통해 별도의 서버로부터 커널을 다운받아 부팅이 진행될 수도 있다. 특 히 부트 롬이나 저장장치의 용량이 제한적일 경우는 커널 이미지 자체를 압축해 저장되는 것이 일반적이다. - 임베디드 응용 프로그램 임베디드 응용 프로그램은 앞에서 구현된 커널과 파일 시스템을 바탕으로 수행된다. 응용 프로 그램의 개발은 커널과 마찬가지 방법으로 호스트에서 생성이 가능하며 호스트에 설치된 개발 툴 의 크로스 컴파일러에 의해 타깃 보드에 맞는 바이너리가 생성되게 된다. 생성된 응용 프로그램 의 실행은 임베디드 OS 개발 툴 내의 타깃 에뮬레이터나 실제로 타깃 보드에 옮겨서 실행이 가 능하다. 또한 응용 프로그램은 네트워크를 이용한 원거리 디버깅을 이용하거나, JTAG 인터페이 스를 이용한 디버깅을 통하여 에러를 확인해 볼 수 있다

17 제2장 X-Hyper320TKU 임베디드 시스템 2.1 X-Hyper320TKU의 특징 이 장은 마벨 모나한(Manahan) PXA320기반의 X-Hyper320TKU 임베디드 시스템에 대한 주요 특징 및 임베디드 시스템 사양에 대하여 서술하였다. 본 임베디드 시스템은 최신의 임베디드 시스템 기술 트랜드가 적용된 교육용 실험 실습장비이 다. Bulverde 후속인 Marvell PXA320 프로세서 기반으로 제작되어 모바일용에 적합한 멀티미디 어, 파워 메니지먼트 기술이 강화 된 첨단 교육 임베디드 실험 장비이다. [그림 2-1] X-Hyper320TKU 임베디드 시스템 장비 모습 1. 주요 특징 본 장비는 CPU보드 + 메인보드 + IEB 보드 로 모듈별 구성되어 있어 추가 기능을 위한 확장 및 CPU 업그레이드, FPGA 독립 실험등의 가능한 특징이 있다. PXA320은 PXA270 보다 더 빠른 Core Speed (806MHz)를 제공한다. 266MHz DDR SDRAM의 사용으로 SDRAM보다 성능이 뛰어나서 빠른 프로그램 실행 속도를 가지고 있다. (266MHz DDR SDRAM 128Mbyte) PXA320은 내부 SRAM용량이 768K Byte(PXA270 은 256K)이어서 800 x 480 LCD를 사용했 을 경우, Refresh를 위한 Frame Buffer를 내부 SRAM 으로도 가능하다. 이러한 이점은 저 전력 으로 LCD를 구동할 수 있고, 인터페이스 또한 빠르게 동작한다

18 NAND Flash의 장점은 NOR Flash보다 가격이 저렴하며, 보드 수정 없이도 용량이 더 큰 NAND Flash로 교체가 가능하다. LCD 및 Mini LCD Controller를 가지고 있어 2개의 LCD를 필요로 하는 Smart Phone에 적용 에 가능하다. Touch Controller가 기본 내장되어 별도의 외장 Touch controller가 필요 없다. DMB 장착으로 DMB 시청 및 교육이 가능하다. Wireless LAN 모듈이 기본 장착되어 Touch Controller가 기본 내장되어 별도의 외장 Touch controller가 필요 없다

19 2.2 X-Hyper320TKU의 구성 X-Hyper320TKU 하드웨어 사양 CPU 보드 X-Hyper320TKU 임베디드 시스템은 CPU 보드가 별도로 제작되어 있다. 모듈형태로 제작되어 PXA310, PXA300 등 다른 CPU로 업그레이드 및 변경이 가능하게 설계되어있다. 본 CPU 모듈 을 사용하여 사용자가 별도 임베디드 장비 제작도 가능하다. CPU보드 하드웨어 사양은 <표 2-1>과 같다. [그림 2-2]는 실제 CPU보드의 실물 사진이다. 분 류 항 목 내 용 CPU PXA320(806MHz) Monahan-P 메모리 NAND Flash memory 128MByte 266MHz DDR SDRAM 128MByte PMIC PMIC MAX8660 <표2-1> CPU 보드 사양 [그림 2-2] X-Hyper320TKU 임베디드 시스템 (CPU 보드)

20 메인 보드 X-Hyper320TKU 임베디드 시스템의 메인보드이다. DMB, TFT 7" LCD, Wireless LAN, Ethernet, USB 등 고급 디바이스들이 장착되어 첨단 장비 개발이 가능하다. 하드웨어 사양은 <표 2-2>과 같다. [그림 2-3]는 실제 메인보드의 사진이다. 분 류 항 목 내 용 외부 장치 CPLD USB Host 2.0 2Port Display Touch Screen IDE I/F Analog RGB(VGA Monitor) Ethernet(10/100) Wireless LAN Audio-AC97 (WM9712) DMB Camera GPS USB UART VGA Key Button / LED Mic, Speaker MMC/SD Xilinx CoolRunner-II TD242LP 7" Wide TFT Color LCD CPU 에 내장 mini IDE THS Port Max 54Mbps, IEEE802.11g/b SPEAKER 내장 DMB 모듈 CMOS Camera 1.3M Pixel GPS Module USB Host/Client 1.1 각 1port USB Host port USB Client port Debug(RS232), GPS(TTL), FFUART(RS232) 1port(3EA) Bluetooth(RS232), IrDA(TTL), RS232, TTL 1port(4EA) VGA I/F GPIO 4EA Jack Type MMC/SD 1Slot 확장 커넥터 160 pin 2.54mm pitch <표 2-2> 메인보드 사양

21 [그림 2-3] X-Hyper320TKU 임베디드 시스템 (메인 보드) [그림 2-4] X-Hyper320TKU 임베디드 시스템 (메인 보드) 부품 배치도

22 IED 확장 보드 임베디드 시스템의 기초 실험을 위해서 저급디바이스만을 모아 놓은 IEB 확장 보드를 제작하여 학생들이 저급디바이스로 처음에 교육하고 추후에 고급디바이스로 공부 할 수 있도록 단계별 교 육이 가능한 장비이다. IED확장보드의 사양은 <표 2-3>과 같다. [그림 2-5]는 IDE보드의 실물 사진이다. <표 2-3> IEB 확장 보드의 하드웨어 사양 분류 항 목 내 용 FPGA EP1C6240PQFP Cyclone (PQFP-240) Programming ROM EPC2 EP2(PLCC/SOCKET) RF 디바이스 CC2420 CC2420(QLP48) DC 모터 제어 L298 DIP Step모터 제어 L297 DIP ADC DAC ADC0804 DAC Segment 7-Segment * 8 DOT Matrix 글자 LCD DOT Matrix 글자 LCD [그림 2-5] X-Hyper320TKU 임베디드 시스템(IEB확장 보드)

23 [그림 2-6]은 X-Hyper320TKU의 전체 블록도를 나타낸다. DF_IO[15..0] DATA[15..0] DATA[15..0] GP105/ETHERNET 1_INT GP84/ETHERNET 2_INT GP17/NET2272_nIRQ GP9/INT_A GP10/INT_B GP13/INT_C GP14/INT_D GP30/UBI9032_INT GP1/CF-nINT Monahans CPU Module (PXA3xx) ncs2 ncs3 nxcvren nlla nlua DF_SCLK nbe0 nbe1 noe nwe nreset_out ADDRESS [2] ncs0 nior niow ADDRESS[2] ncs0 nior niow GP105/ETHERNET 1_INT DATA[15..0] ETHERNET1 (DM9000E) ETHERNET2 (DM9000E) 3 Port UART nrdy ADDR[25..0] ncs0 nior niow GP84/ETHERNET 2_INT DATA[15..0] ADDR[5..1] USB 2.0 Device (NET2272) GP17/NET2272_nIRQ VGA (FS453) 7Inch Wide LCD I2C Bus LDD[15..0] LDD[15..0] FCLK,LCLK,PCLK Resistor SW MMC WP MMC DETECT MMC Interface SPI4 Interface CTX305R_INT MMC/SD DMB (CTX305R) nreset PWR_DN CPLD XC2C256 ncsa ncsb ncsc ncsd noe nwe DATA[7..0] ADDR[3..1] GP9/INT_A GP10/INT_B GP13/INT_C GP14/INT_D 4Channel UART (TL16C554) Audio&Touch (WM9712L) Touch AC97 Interface Touch_INT Touch_PENDOWN CMOS Interface GATE noe I2C Bus DMB ( ) ncs0 nior niow USB 2.0 Host (UBI9032) DMB_nSELECT GP30/UBI9032_INT USB 1.1 Client USB Client INT USB Client Interface USB Client Enable CMOS Interface I2C Bus GATE noe CMOS 1.3M Pixel CAM_SELECT USB TO IDE (GL811) USB HUB USB 1.1 Host USB Client INT USB Client Interface USB Client Enable MMC2 Interface SPI3 Interface Resistor SW Wireless LAN WAKE_UP npd USB 2CH (GL850) [그림 2-6] X-Hyper320TKU 블록 다이어그램

24 2.1.2 X-Hyper320TKU 소프트웨어 사양 소프트웨어 사양 분 류 항 목 내 용 O/S Linux Linux Compiler GNU Tool for ARM JTAG XDB OPTION 파일시스템 Bootloader GUI JFFS2(Rootfile system) Ext2, ext3, YAFFS, RAMFS, NFS hybus-boot320 GTK QT/Embedded Ethernet 10/100Base-T Wireless LAN TFT LCD Touch Screen AC'97 Codec 7 inches TFT LCD Interface Toch Screen Controller Audio 디바이스 드라이버 PMIC MMC/SD USB 1.1 Host/Client USB 2.0 Host/Client CMOS Camera PCMCIA/CF VGA IDE mini-ide Tiny X-Server MatchBox Windows manager MP3 Player 응 용 동영상 Player MPEG1,2,4, WMV1/2/3, DivX 5 Web Brower USB Cam OV511 CAM 지원 Access Pointer 802.a, 802.b

25 IEB 확장보드의 소프트웨어 사양 분 류 항 목 내 용 디바이스 드라이버 DC Mocter Control Step Mocter Control ADC DAC 7-Segment L298 L297 ADC0804 DAC ea DOT Matrix 5 * 7 Character LCD 2 * 16 응 용 IEB Test Program X-Hyper320TKU GUI Application 본 장비는 아래 그림처럼 응용 프로그램을 GUI 형태로 제작하여 동작할 수 있도록 제작되어 있 다. 임베디드 시스템에서 어플에 대한 요구가 많아지는 실정에서 이런 아이콘을 학생이 직접 제 작하여 만들어서 연동 실험한다면 좋은 효과가 있을 것이다. [그림 2-7] X-Hyper320TKU 응용 GUI 화면

26 2.3 X-Hyper320TKU의 하드웨어 전 원 X-Hyper320TKU의 전원의 구성을 [그림 3-6]과 같은 블록도로 구성되어 있다. PMIC 1.4V 1.8V 3.3V Monahans P CPU Module DC 12V 5V Step Down Regulator 3.3V LDO CPLD, Ethernet, DMB, MMC, CMOS... IEB Board Backlight, USB Power... [그림 2-8] X-Hyper320TKU 전원 블록 다이어그램 X-Hyper320TKU 보드는 DC 12V(2A 이상)를 사용한다. DC 12V는 IEB 보드에 전원 공급을 해 주고, CPU Module은 DC 5V 전원 공급을 한다. 보드 내부는 DC 5V 와 DC 3.3V로 보드 전체 디바이스에 공급을 해 주고 있다

27 2.3.2 시스템 버스 DFI Interface DF[15..0] nlla Dn Qn DF[00] -> Addr[0] DF[01] -> Addr[1] DF[02] -> Addr[2] DF[03] -> Addr[3] DF[04] -> Addr[4] DF[05] -> Addr[5] DF[06] -> Addr[6] DF[07] -> Addr[7] DF[08] -> Addr[8] DF[09] -> Addr[9] DF[10] -> Addr[10] DF[11] -> Addr[11] DF[12] -> Addr[12] DF[13] -> Addr[13] DF[14] -> Addr[14] DF[15] -> Addr[15] Addr[25..0] npreg npce1 nlua Dn Qn DF[00] -> Addr[16] DF[01] -> Addr[17] DF[02] -> Addr[18] DF[03] -> Addr[19] DF[04] -> Addr[20] DF[05] -> Addr[21] DF[06] -> Addr[22] DF[07] -> Addr[23] DF[08] -> Addr[24] DF[09] -> Addr[25] DF[10] -> Addr[26](nPREG) DF[11] -> Addr[27] DF[12] -> Addr[28] DF[13] -> Addr[29](nPCE1) DF[14] -> Addr[30](nPCE2) DF[15] -> Addr[31](RDnWR) npce2 RDnWR DIR Dn Qn DATA[15..0] nxcrven CPU Module CPLD EN [그림 2-9] X-Hyper320TKU 시스템 버스 블록 다이어그램 PXA320 CPU의 System Bus는 두가지가 있다. 하나는 DDR SDRAM 전용 Bus(EMPI)와 다른 하 나는 FLASH 및 외부 디바이스를 위한 DFI Bus이다. DFI Bus는 기존 Intel PXA CPU들과 달리 16bit Bus로 순차적으로 Address /Address /Data 순으로 access하는 Multiplex 방식을 사용한 다. 이는 (nlla, nlua, nxcrven) Signal에 의해 상/하위 Address, Data로 구분한다. 외부 디 바이스들을 제어하기 위해서는 이런 Multiplex 방식을 VLIO방식이나 SRAM Interface 방식으로 변환해 주어야 한다. X-Hyper3320TKU에서는 이러한 변환 과정이 CPLD에 구현 되어 있다. DF[15..0] Address_sig<25..0> ncs2 ncs3 nlla nlua nxcrven nwe noe AA/D Multiplex Bus EBI Bus Data_sig<15..0> noe nwe ncs RDnWR Device PXA320 CPLD

28 2.3.3 Ethernet [그림 2-10] X-Hyper320TKU Ethernet 블록 다이어그램 10/100을 지원하는 DM9000E는 CPU와는 16bit Data Bus로 결선되어 있고, CPU의 Address[2] bit가 DM9000E의 CMD와 연결되어 있다. CMD의 High/Low에 의해 DM9000E는 16Bit Bus가 Data/Address로 동작한다. DM9000E의 Chip Select와 간단한 로직들은 전부 CPLD(Address Decoding)에서 구현되어 있 다

29 2.3.4 TFT LCD LCD Connector DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder LDD[15..0] L-CLK P-CLK F-CLK GP11/PWM0 LDD[15..0] HSync CLK VSync ADJ LDD[15..0] GP125/SCL GP126/SDA PXA320 HSync CLK VSync SCL SDA FS453 [그림 2-11] X-Hyper320TKU TFT LCD 블록 다이어그램 PXA320 CPU의 LCD 풀력 핀은 18핀(18Bit)로 구성되어 있으나, X-HYPER320TKU 에서는 16Bit 로 사용하고 있다. 본 LCD는 LED Backlight 내장 타입이라 Backlight용 5V 전원만 공급해 주면 Back light는 동작하며, Logic Input Voltage는 3.3V, 밝기 조절은 PWM 방식을 사용한다. FS453은 RGB 출력을 위해 사용되었다 USB(Internal) GP15/USBC USBC_N USBC_P VBUS USBC_N USBC_P GP16/USBC_INT USB Client USBH1_PWR USBH1_EN USBH_N USBH_P FLAG VBUS EN VBUS Negative Positive PXA320 USB HOST [그림 2-12] X-Hyper320TKU USB 블록 다이어그램 PXA320은 USB HOST 1.1과 USB Client 1.1 Controller를 내장한다

30 USB Client는 Vbus에 의해 CPU쪽으로 Interrupt를 발생 시키고, CPU의 레벨을 맞추기 위해 중 간에 buffer를 사용했다. CPU의 Interrupt에 의해 USB 접속을 확인하고, GPIO로 USB를 활성화 시킨다. USB HOST는 Connecotr와 직접적으로 연결되어 있고, CPU의 USBH1_EN signal로 USB Power 을 enable하고 USB Overcurrent flag인 USBH1_PWR로 USB Power를 관리 한다 USB Host 2.0 (External) DF[15..0] nlla nlua nxcrven ADDRESS & DATA LATCH ADDRESS Decoder ADDRESS[8..1] ADDRESS[16..1] DATA[15..0] ncs2 USBH_CS0 0x10E0_0000 ncs noe nwe nrd nwr HOST_DM HOST_DP nreset CPLD nreset GP30/OXU210INT INTERRUPT CPU Module UBI9032 [그림 2-13] X-Hyper320TKU USB Host 2.0 블록 다이어그램 UBI9032는 Host 2.0으로 Hi-Speed를 지원하며, 16Bit Data Bus를 사용한다. Chip Select와 간 단한 로직들은 전부 CPLD(Address Decoding)에서 구현되어 있다. X-Hyper320TKU에서는 USB Hub Controller(GL850)를 사용하여 USB Port를 확장 하였다. GL850은 Hardware적으로 구성되어 있어서, USB Interface가 동작하면 GL850도 자동적으로 동 작하게 되어 있다. GL850의 4 Port중 2 Port 는 Connector로서 연결되어 있고, 1 Port는 USB TO IDE Controller(GL811)를 사용하여 1.8Inch Mobile Hard Disk를 연결하였다. GL811 역시 USB interface가 동작하면 GL811도 자동적으로 동작하게 되어 있다. USB 2.0 Host DM/DP USB Hub DM/DP USB TO IDE (GL811) (UBI9032) (GL850) DM/DP DM/DP USB 2CH

31 2.3.7 USB Client 2.0 (External) DF[15..0] nlla nlua nxcrven ADDRESS & DATA LATCH ADDRESS Decoder ADDRESS[5..1] ADDRESS[4..0] DATA[15..0] ncs2 NET2272_CS0 0x1040_0000 ncs0 noe nior nwe niow VBUS nreset CPLD nreset DM DP GP17/NET2272_nIRQ INTERRUPT CPU Module NET2272 [그림 2-14] X-Hyper320TKU USB Client 2.0 블록 다이어그램 USB Client 2.0을 지원하는 NET2272는 3가지의 Address Mode를 지원한다. 각 Mode에 따라서 하드웨어 방식이 틀리며, X-Hyper3xxTKU에서는 Non-Multiplexed Direct Address Mode를 사용 하였다. Chip Select와 간단한 로직들은 전부 CPLD(Address Decoding)에서 구현되어 있다 Wireless LAN DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder D0 D1 WLAN Control 0x1050_0000 D0 Q0 D1 Q1 WLAN_nPD WAKEUP_WLAN GP90/SSP_FRM GP92/SSP_RXD GP91/SSP_TXD GP89/SSP_CLK SPI_nCS SPI_SDO SPI_SDI SPI_CLK GP102/nWLAN_IRQ SPI_SINTN PXA320 Wireless LAN [그림 2-15] X-Hyper320TKU Wireless LAN 블록 다이어그램 모듈로 구성되어 있는 Wireless LAN은 IEEE802.11b/g 와 호환하고, SPI interface로서 제어한 다. Wireless LAN의 기본 제어 Signal(WLAN_nPD, WAKEUP_WLAN)들은 CPLD에서 제어 할 수 있도록 구성되어 있다

32 2.3.9 MMC / SD / SDIO DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder GP22/MMC_CLK GP23/MMC_CMD GP18/MMC_DATA0 GP19/MMC_DATA1 GP20/MMC_DATA2 GP21/MMC_DATA3 GP98/MMC_CD GP99/MMC_WP CLK CMD DATA0 DATA1 DATA2 DATA3 CD WP PXA320 MMC [그림 2-16] X-Hyper320TKU MMC/SD 블록 다이어그램 PXA320은 MMC(MultiMedia Card), SD(Secure Digital),SDIO(Secure Digital I/O)를 지원하는 controller를 2포트 제공한다. MMC/SD/SDIO에 대한 통신 protocol을 지원하며 아래 스펙을 만 족한다. MultiMedia Card System Specification Version 4.0 Secure Digital Memory Card Specification Version 1.10 Secure Digital I/O Card Specification Version 1.0 X-HYPER320TKU 보드에서 MMC/SD/SDIO Controller를 사용하기 위해서는 CPU의 MMC/SD/SDIO Controller에 전원 공급해야 한다. 본 보드에서는 MAX8660 6번 전원 출력 단자 가 PXA320 CPU의 MMC/SD/SDIO Controller로 공급되는 전압으로 설계되어 있다. 먼저 MAX8660에 접근해서 6번 전원 출력을 3.3V로 세팅해 주어야 한다

33 Audio DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder HPOUTR HPOUTL MIC2 MICBIAS SPKR EAR JACK MIC JACK AC97_DOUT AC97_BITCLK AC97_DIN AC97_SYNC AC97_RESET DOUT BITCLK DIN SYNC RESET SPKL PXA320 DMB LINE_L LINE_R Audio [그림 2-17] X-Hyper320TKU Audio 블록 다이어그램 X-Hyper320TKU 보드에서는 EAR JACK, MIC JACK, 그리고 2개의 스피커로 구성되어 있다. 그리 고 DMB에서 나오는 오디오 Signal들이 Audio Codec의 LINE Input에 연결되어 있다 UART DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder UART Control 0x1090_0000 D0 D1 D2 D3 D4 D0 Q0 D1 Q1 D2 Q2 D3 Q3 D4 Q4 UARTA_ON_OFF (BLUETOOTH) IrDA_SC GPS_onoff STDTXD STDRXD BTTXD BTRXD RX TX RX TX Debug GPS CPU Module GP9/INTA GP10/INTB GP13/INTC GP14/INTD noe nwe CSA :0x10A0_0000 CSB :0x10B0_0000 CSC :0x10C0_0000 CSD :0x10D0_0000 CPLD ncsa ncsb ncsc ncsd INTA INTB INTC INTD nior niow 16C554 ON_OFF Fulll UART Fulll Signal GP111/BTTXD GP110/BTRXD GP107/STDTXD GP108/STDRXD BTTXD BTRXD STDTXD STDRXD FFUART [그림 2-18] X-Hyper320TKU UART 블록 다이어그램 X-Hyper320TKU는 Internal 3 Port, External 4 Port로 총 7 Port의 UART를 지원하며, Internal중 Standard UART는 Debug용으로, FF UART는 Full UART용으로, BT UART는 GPS 전용으로 설 계되어 있다. External 4 Port중 Port A는 BLUETOOTH(Bluetooth Module 바로 사용 가능)전용 으로, Port B 는 IrDA전용으로, 나머지 2 Port는 Connector로서 구성되어 있다

34 DMB DF[15..0] nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder D3 D4 D3 Q3 D4 Q4 DMB Control 0x1080_0000 CTX_nRESET CTX_BB_PWR_DN GP86 GP93/SSP4_SCLK GP95/SSP4_TXD GP96/SSP4_RXD Control_nCS Control_CLK Control_MOSI Control_MISO GP75 DATA_nCS DATA_CLK DATA_MOSI DATA_MISO GP101 INT I2S Audio PXA320 DMB DMB(CTX305R) [그림 2-19] X-Hyper320TKU DMB 블록 다이어그램 CTX305R DMB는 Interface가 SPI로 되어 있으며, Control Interface와 Data Interface로 분리되 어 있다. DMB를 제어하기 위한 기본 Control Signal들은 CPLD에서 출력이 이루어지며, 각각의 Chip Selec에 SPI 라인은 브릿지 되어 있다 PMIC DF[15..0] nlla POWER_EN_sig nlua nxcrven ncs2 DATA[0] D0 Q0 ADDRESS & DATA LATCH ADDRESS Decoder Power Control 0x1000_0000 DATA[1] DATA[2] DATA[3] DATA[4] DATA[5] DATA[6] DATA[7] DATA[8] DATA[9] DATA[10] DATA[11] DATA[12] DATA[13] DATA[14] DATA[15] D1 Q1 D2 Q2 D3 Q3 D4 Q4 D5 Q5 D6 Q6 D7 Q7 D8 Q8 D9 Q9 D10 Q10 D11 Q11 D12 Q12 D13 Q13 D14 Q14 D15 Q15 DM9000E1_PWREN DM9000E2_PWREN LCD_PWREN LCD_BL_PWREN VGA_PWREN AUDIO_PWREN USBH_PWREN NET2272_PWREN GL850_PWREN IDE_PWREN WLAN_PWREN CAM_PWREN DMB_PWREN MMC_ON UART_PWREN CPU Module CPLD [그림 2-20] X-Hyper320TKU PMIC 블록 다이어그램 X-Hyper320TKU는 각각의 디바이스들을 ON/OFF 할 수 있도록 설계되어 있다. 이는 CPLD에서 담당하며, CPLD의 ON/OFF 동작에 의해 각각의 디바이스들로 전원이 공급된다

35 CMOS Camera DF[15..0] CMOS Control 0x1080_0000 nlla nlua nxcrven ncs2 ADDRESS & DATA LATCH ADDRESS Decoder D0 D1 D2 D0 Q0 D1 Q1 D2 Q2 CMOS RESET CIF_DD[9..0] GP62/FV GP61/LV GP63/PCLK noe GATE CIF_DD[7..0] VSync HSync PCLK CPU Module noe GATE nreset CIF_DD[7..0] PCLK GP82/SCL GP80/SDA SCL SDA DMB [그림 2-21] X-Hyper320TKU CMOS Camera 블록 다이어그램 X-Hyper320TKU에서는 C-MOS Camera와 DMB Module(광성전자)에서 CIF Interface를 입력 받 는다. 회로 설계상 두개는 동시에 사용 불가능하고, 한 개씩의 디바이스만 사용 가능하다. 그래서 중간에 Buffer Gate를 사용하여 Select 할 수 있도록 설계 되어 있다

36 2.4 X-Hyper320TKU의 메모리 맵 플레시 메모리 맵 [그림 2-22] 플래시 메모리 맵 SDRAM 메모리 맵 [그림 2-23] SDRAM 메모리 맵

37 2.4.3 Static 메모리 맵 메인 보드 이름 어드레스 범위 설명 CPLD 0x x XHYPER320TKU CPLD Power DM x x /100 Base-T Ethernet Controller DM x x /100 Base-T Ethernet Controller CPLD ID 0x x CPLD ID NET2272 0x x USB2.0 Slave WLAN 0x x wireless module CMOS 0x x cmos camera UART ON_OFF 0x x External uart power on/off 16C554 CSA 0x10A x Serial Controller CS A 16C554 CSB 0x10B x Serial Controller CS B 16C554 CSC 0x10C x Serial Controller CS C 16C554 CSD 0x10D x Serial Controller CS D

38 IEB 확장보드 이 름 어드레스 범위 설명 FND1 0x x segment 1 FND2 0x x segment 2 FND3 0x x segment 3 FND4 0x x segment 4 FND5 0x x segment 5 FND6 0x x segment 6 FND7 0x x segment 7 FND8 0x x segment 8 DOT_1 Col 0x x Dot collumn 1 DOT_2 Col 0x x Dot collumn 2 DOT_3 Col 0x11A x Dot collumn 3 DOT_4 Col 0x11B x Dot collumn 4 DOT_5 Col 0x11C x Dot collumn 5 KEY_W 0x11D x Key Write KEY_R 0x11E x Key Read DAC 0x11F x Digital to Analog Convertor ADC 0x x Analog to Digital Convertor STEP Motor 0x x Step Motor controller DC Motor 0x x DC Motor controller Character LCD 0x x Character LCD Control LED 0x x LED

39 2.5 X-Hyper320TKU 의 Pin Assign Table CPLD JTAG Connector (J1) NO Name Description 1 GND Ground 2 Vref CPLD Reference Voltage 3 GND Ground 4 TMS CPLD Test Mode Select 5 GND Ground 6 TCK CPLD Test Clock 7 GND Ground 8 TDI CPLD Test Data Input 9 GND Ground 10 TDO CPLD Test Data Output 11 GND Ground 12 NC Not Connect 13 GND Ground 14 NC Not Connect Ethernet Standard Connector (J2, J3) NO Name Description 1 TPOP Ground 2 TPNP CPLD Reference Voltage 3 TPIP Ground 4 COM11 CPLD Test Mode Select 5 COM11 Ground 6 TPIN CPLD Test Clock 7 COM12 Ground 8 COM12 CPLD Test Data Input 9 Link LED Ground 10 DC3P3V CPLD Test Data Output 11 LAN LED Ground 12 LAN LED Not Connect

40 Touch Connector (TOUCH1, TOUCH2) NO Name Description 1 XM X Minus 2 YM Y Minus 3 XP X Plus 4 YP Y Plus LCD Connector (LCD1) NO Name Description 1 U/D Display Control(Up or Down) 2 DMS Selection(DE or SYNC) 3 Hsync Horizontal SYNC 4 VDD Power Supply for LED Driver circuit 5 VDD Power Supply for LED Driver circuit 6 VDD Power Supply for LED Driver circuit 7 Vcc Power Supply for Digital circuit 8 Vsync Vertical SYNC 9 DE Data Enable 10 Vss Power Ground 11 Vss Power Ground 12 ADJ Adjust for LED brightness 13 B5 Blue Data 5(MSB) 14 B4 Blue Data 4 15 B3 Blue Data 3 16 Vss Power Ground 17 B2 Blue Data 2 18 B1 Blue Data 1 19 B0 Blue Data 0 20 Vss Power Ground 21 G5 Green Data 5(MSB) 22 G4 Green Data 4 23 G3 Green Data 3 24 Vss Power Ground 25 G2 Green Data 2 26 G1 Green Data 1 27 G0 Green Data 0 28 Vss Power Ground 29 R5 Red Data 5(MSB) 30 R4 Red Data 4 31 R3 Red Data 3 32 Vss Power Ground 33 R2 Red Data

41 LCD Connector (LCD2) NO Name Description 1 GND Power Ground 2 PCLK Pixel Clock 3 NC Not Connect 4 LCLK Line Clock 5 FCLK Frame Clock 6 GND Power Ground 7 LDD12 LCD Data 12 8 LDD13 LCD Data 13 9 LDD14 LCD Data LDD15 LCD Data LDD16 LCD Data LDD17 LCD Data GND Power Ground 14 LDD6 LCD Data 6 15 LDD7 LCD Data 7 16 LDD8 LCD Data 8 17 LDD9 LCD Data 9 18 LDD10 LCD Data LDD11 LCD Data GND Power Ground 21 LDD0 LCD Data 0 22 LDD1 LCD Data 1 23 LDD2 LCD Data 2 24 LDD3 LCD Data 3 25 LDD4 LCD Data 4 26 LDD5 LCD Data 5 27 GND Power Ground 28 BIAS LCD BIAS 29 NC Not Connect 30 DC3P3V DC 3.3V Power 31 DC3P3V DC 3.3V Power 32 DP3P3V DC 3.3V Power Backlight Connector (BL1) NO Name Description 1 DC5V DC 5V Power 2 DC5V DC 5V Power 3 LCD_BL_PWREN LCD Backlight Power Enable 4 DC5V DC 5V Power 5 GND Power Ground

42 RGB Output Connector (VGA) NO Name Description 1 RED Red Video. 2 GREEN Green Video. 3 BLUE Blue Video. 4 GND Monitor ID Bit 2. 5 GND Ground 6 RGND Red Ground. 7 GGND Green Ground. 8 BGND Blue Ground. 9 GND Key(No Pin). 10 SGND Sync Ground. 11 GND Monitor ID Bit DDC DATA Monitor ID Bit HSYNC Horizontal Sync. 14 VSYNC Vertical Sync. 15 DDC CLOCK Monitor ID Bit 3. USB Mini Connector (CN2, J4) NO Name Description 1 Vbus DC 5V USB Pow er Supply 2 DM Data Negative 3 DP Data Positive 4 ID ID 5 GND Pow er Ground USB Connector (CN3) NO Name Description 1 Vbus DC 5V USB Power Supply 2 DM Data Negative 3 DP Data Positive 4 GND Power Ground

43 USB Dual Connector (CN4) NO Name Description 1 Vbus DC 5V USB Power Supply 2 DM Data Negative 3 DP Data Positive 4 GND Power Ground 5 Vbus DC 5V USB Power Supply 6 DM Data Negative 7 DP Data Positive 8 GND Power Ground 1.8" HDD Disk (IDE1) NO Name Description 1 Factory use NC 2 Factory use NC 3 RESET- RESET 4 GND Ground 5 DD7 DATA 7 6 DD8 DATA 8 7 DD6 DATA 6 8 DD9 DATA 9 9 DD5 DATA 5 10 DD10 DATA DD4 DATA 4 12 DD11 DATA DD3 DATA 3 14 DD12 DATA DD2 DATA 2 16 DD13 DATA DD1 DATA 1 18 DD14 DATA DD0 DATA 0 20 DD15 DATA GND Ground 22 DMARQ DMA request 23 GND Ground

44 24 DIOW_ Write strobe signal 25 DIOR_ Read strobe signal 26 GND Ground 27 IORDY Data transfer ready 28 GND Ground 29 DMACK_ DMA acknowledge signal 30 INTRQ Interrupt signal for the host system 31 DA1 Register address signal 1 32 PDIAG_ NC 33 DA0 Register address signal 0 34 DA2 Register address signal 2 35 CS0_ Device chip select(command black) 36 CS1_ Device chip select(control black) 37 DASP Indicates that a device is active V DC 3.3V Power V DC 3.3V Power 40 Reserved Reserved CMOS Camera Connector (J6) NO Name Description 1 DC3P3V 3.3V Power Supply 2 DC3P3V 3.3V Power Supply 3 DC3P3V 3.3V Power Supply 4 DC3P3V 3.3V Power Supply 5 NC 6 CAM_PCLK CIF Pixel Clock 7 NC 8 CAM_VSYNC CIF Frame Clock 9 NC 10 CAM_HSYNC CIF Line Clock 11 NC 12 CAM_D9 CIF DATA9 13 NC 14 CAM_D8 CIF DATA8 15 CAM_RESET RESET 16 CAM_D7 CIF DATA7 17 NC 18 CAM_D6 CIF DATA6 19 NC 20 CAM_D5 CIF DATA5 21 NC 22 CAM_D4 CIF DATA4 23 NC

45 24 CAM_D3 CIF DATA3 25 GND Ground 26 CAM_D2 CIF DATA2 27 SDA I2C DATA 28 CAM_D1 CIF DATA1 29 SCL I2C Clock 30 CAM_D0 CIF DATA0 31 CMOS_GP0 CMOS GPIO 32 CIF_MCLK CIF MCLK 33 CMOS_GP1 CMOS GPIO 34 GND Ground 35 GND Ground 36 GND Ground 37 GND Ground 38 CMOS_ID CMOS Detect 39 GND Ground 40 GND Ground

46 Cenronix DMB Connector (J16) NO Name Description 1 DC3P3V 3.3V Power Supply 2 DC3P3V 3.3V Power Supply 3 DC3P3V 3.3V Power Supply 4 DC3P3V 3.3V Power Supply 5 CTL_SPI_CS DMB Control Chip Select(SPI) 6 NC 7 DATA_SPI_CS DMB Data Chip Select(SPI) 8 NC 9 SSP4_RXD SPI RXD 10 NC 11 SSP4_TXD SPI TXD 12 NC 13 SSP4_SCLK SPI Clock 14 NC 15 CTX_nRESET DMB RESET 16 NC 17 I2SC_MCLK No Use 18 NC 19 I2S_LRCK No Use. 20 NC 21 I2S_BCLK No Use. 22 NC 23 I2S_SDO No Use

47 24 NC 25 GND Ground 26 NC 27 NC 28 NC 29 NC 30 NC 31 DMB_nINT DMB Interrupt 32 NC 33 CTX_BB_PWR_DN DMB Power Down 34 DMB_ID0 DMB DETECT ID 35 Ground Ground 36 DMB_ID1 DMB DETECT ID 37 GND Ground 38 GND Ground 39 GND Ground 40 GND Ground 16C554 A Port UART (for Bluetooth) (J8) NO Name Description 1 DCDA Data Set Ready 2 RXDA Receive Data 3 TXDA Transmit Data 4 DTRA Data Terminal Ready 5 GND Ground 6 DSRA Data Set Ready 7 RTSA Ready To Send 8 CTSA Clear To Send 9 DC5V DC 5V

48 16C554 C Port UART (J12) NO Name Description 1 DC3P3V DC 3.3V Power Supply 2 TXD RS232 Level TXD 3 RXD RS232 Level RXD 4 GND Ground 16C554 D Port UART (J10) NO Name Description 1 DC5V DC 5V Power Supply 2 TXD TTL Level TXD 3 RXD TTL Level RXD 4 GND Ground Standard UART (J9) NO Name Description 2 TXD RS232 Level Standard UART 3 RXD RS232 Level TXD 5 GND RS232 Level RXD

49 Full Function UART (J7) NO Name Description 1 DCDA Data Set Ready 2 RXDA Receive Data 3 TXDA Transmit Data 4 DTRA Data Terminal Ready 5 GND Ground 6 DSRA Data Set Ready 7 RTSA Ready To Send 8 CTSA Clear To Send 9 RI Ring Indicator GPS Connector (J11) NO Name Description 1 GPS_ONOFF GPS On Off Signal 2 DC5V DC 5V Power Supply 3 BTRXD Bluetooth UART RXD 4 BTTXD Bluetooth UART TXD 5 GND Ground

50 NO Name Description NO Name Description 1 GND Ground 2 GND Ground 3 GND Ground 4 GND Ground 5 PAD_DDR_EVAL Reserved 6 nrdy GPIO2 7 PAD_EMPI_CLK Reserved 8 ncs2 GPIO3 9 PAD_nOE Reserved 10 ncs3 GPIO4 11 PAD_nWE Reserved 12 DF_ADDR0 DF ADDR0 13 PAD_nCS0 Reserved 14 DF_ADDR1 DF ADDR1 15 PAD_nCS1 Reserved 16 DF_ADDR2 DF ADDR2 17 PAD_nADV Reserved 18 DF_ADDR3 DF ADDR3 19 PAD_nADV2 Reserved 20 nxcvren nxcvren 21 GND Ground 22 DF_SCLK DF SCLK 23 DF0 DF0(DFI Bus) 24 nbe0 nbe0 25 DF1 DF1(DFI Bus) 26 nbe1 nbe1 27 DF2 DF2(DFI Bus) 28 nlla nlla 29 DF3 DF3(DFI Bus) 30 nlua nlua 31 DF4 DF4(DFI Bus) 32 DF_nRE DFI nre 33 DF5 DF5(DFI Bus) 34 DF_nWE DFI nwe 35 DF6 DF6(DFI Bus) 36 DF_nCS0 DFI ncs0 37 DF7 DF7(DFI Bus) 38 DF_nCS1 DFI ncs1 39 DF8 DF8(DFI Bus) 40 DF_CLE_nOE DFI CLE_nOE 41 DF9 DF9(DFI Bus) 42 DF_ALE_nWE DFI ALE_nWE 43 DF10 DF10(DFI Bus) 44 DF_ALE2 Reserved 45 DF11 DF11(DFI Bus) 46 DF_UNLOCK Reserved 47 DF12 DF12(DFI Bus) 48 DF_RnB DFI RnB 49 DF13 DF13(DFI Bus) 50 GND Ground

51 CPU Connector (U68) 51 DF14 DF14(DFI Bus) 52 GP5/nPIOR GPIO5 53 DF15 DF15(DFI Bus) 54 GP6/nPIOW GPIO6 55 GND Ground 56 GP7/nIOIS6 GPIO7 57 GP0/ETHERNET1_INT GPIO0 58 GP8/nPWAIT GPIO8 59 GP1/CF-nINT GPIO1 60 GP11/PWM0 GPIO11 61 GP9/TL16C554_INTA GPIO9 62 GP12/PWM1 GPIO12 63 GP10/TL16C554_INTB GPIO10 64 GND Ground 65 GP13/TL16C554_INTC GPIO13 66 GP59/CIF_MCLK GPIO59 67 GP14/TL16C554_INTD GPIO14 68 GP60/CIF_PCLK GPIO60 69 GP15/USBC GPIO15 70 GP61/CIF_LV GPIO61 71 GP16/USBC_INT GPIO16 72 GP62/CIF_FV GPIO62 73 GP17/NET2272_nIRQ GPIO17 74 GP49/CIF_DD0 GPIO49 75 GP30/OXU210INT GPIO30 76 GP50/CIF_DD1 GPIO50 77 GND Ground 78 GP51/CIF_DD2 GPIO51 79 GP22/MMC_CLK GPIO22 80 GP52/CIF_DD3 GPIO52 81 GP23/MMC_CMD GPIO23 82 GP53/CIF_DD4 GPIO53 83 GP131/CPLD2 GPIO31*** 84 GP54/CIF_DD5 GPIO54 85 GP18/MMC_DATA0 GPIO18 86 GP55/CIF_DD6 GPIO55 87 GP19/MMC_DATA1 GPIO19 88 GP56/CIF_DD7 GPIO56 89 GP20/MMC_DATA2 GPIO20 90 GP57/CIF_DD8 GPIO57 91 GP21/MMC_DATA3 GPIO21 92 GP58/CIF_DD9 GPIO58 93 GP28/MMC2_CLK GPIO28 94 GND Ground 95 GP29/MMC2_CMD GPIO29 96 GP32/SCL GPIO32 97 GP24/MMC2_DATA0 GPIO24 98 GP33/SDA GPIO33 99 GP25/MMC2_DATA1 GPIO GP42/FFTXD GPIO

52 CPU Connector (U69) 101 GP88 GPIO L_LDD7 GPIO13_2 103 GP87 GPIO L_LDD6 GPIO12_2 105 GP86 GPIO L_LDD5 GPIO11_2 107 GP85 GPIO L_LDD4 GPIO10_2 109 GP78 GPIO L_LDD3 GPIO9_2 111 GP77 GPIO L_LDD2 GPIO8_2 113 GP76 GPIO L_LDD1 GPIO7_2 115 GP75 GPIO L_LDD0 GPIO6_2 117 DC5V DC 5V 118 DC5V DC 5V 119 DC5V DC 5V 120 DC5V DC 5V CPU JTAG NO Name Description 1 VREF Reference Voltage 2 VTarget Targer Voltage 3 ntrst Test Reset 4 GND Ground 5 TDI Test Data In 6 GND Ground 7 TMS Test Mode Select 8 GND Ground 9 TCK Test Clock 10 GND Ground 11 RTCK RTCK 12 GND Ground 13 TDO Test Data Output 14 GND Ground 15 RST Reset 16 GND Ground 17 DBGRQ Reserved 18 GND Ground 19 DBGACK Reserved 20 GND Ground

53 제3장 X-Hyper320TKU 환경설정 3.1 Overview 3장에서는 실습에 앞서 기본적으로 타겟보드의 개발환경에 대해서 알아본다. 일반적으로 장비를 구 입할 때 제공되는 매뉴얼을 참조하여 보트의 부트로더, 커널 및 파일시스템들을 빌드 해보고 이미지 를 타겟보드에 올려보았을 것이다. 임베디드 시스템의 개발환경에 익숙해진 후라면 실습의 내용이 쉽게 이해가거나 어렵지 않게 느껴질 것이지만 아직 익숙하지 않거나 처음 장비를 접하는 사람을 위 해 간단히 임베디드 시스템의 개발환경 구축에 대해 설명한다. 문서는 하이버스사의 Marvel PXA 320 processor platform인 X-Hyper320 TKU 보드에 리눅스BSP를 설치, 컴파일 하는 방법을 작성한 것이다 HOST PC 권장사항 리눅스 배포판이 설치된 PC (권장 배포판: redhat 9.0, Fedora Core Series, Asianux ) PC 사양 구 분 사 양 CPU RAM HDD VGA Parallel Ethernet Serial CD-rom Pentium 2.4 G이상 / AMD sempron 2400이상 (x64인 경우 32bit용 배포판을 설치하여 사용한다) 256MB 이상 1.5GB 이상의 여유공간 리눅스 드라이버 호환 모델( ATI, Geforce, Matrox등) 1 port (xdb 사용시, *usb to parallel 사용 불가) 1 port (2 port 권장) 1 port (*usb to serial 사용가능) 32x 이상 배포판 설치시 주의사항 파티션은 일반 ext3로 포멧해서 사용하며, 보안관련 체크를 하게될 경우 NFS등의 문제가 발생 할수 있다. xinetd, tftp, NFS, minicom등의 패키지는 개발시 꼭 필요하므로 최초 설치시 같이 설치하는 것이 좋다

54 * 주의 : VMWARE를 이용하여 리눅스를 설치할 경우, Host PC자원 분리로 컴파일 시간이 오래 걸리고 가상PC내에서 실제 디바이스 제어가 잘 안될 수 있다. 사용하는 것을 권장하지 않는다

55 3.2 Quick Start BSP Install 1. 제공된 BSP CD 최상의 디렉토리의installer-xhyper320-tku.sh를 실행한다 Ex) #../installer-xhyper270-tku.sh [프로젝트 디렉토리:/PROJECT/WENDERS] 2. 다이알로그 화면이 나오면서 Yes/No를 물어본다 YES를 하면 BSP패키지를 프로젝트 디렉토 리에 설치한다. 3. 크로스 컴파일러는 /usr/local/arm-linux 에 설치된다 BSP compile & Build 1. 설치가 완료되면 compile & build 여부를 물어보는 dialog가 표시된다. Yes를 하면 Kernel->Bootloader->Filesystem 순서대로 build한다. 2. Kernel은 zimage, Bootloader는 boot.bin, Filesystem은 lite.img, gtk.img로 생성되며 프로젝 트 디렉토리의 build-image 디렉토리에 복사된다. 3. Lite.img는 최소 부팅 이미지, gtk.img 는 X와 GTK2.10 base 파일시스템이다. * 주의 : tftp-server 의 설치(asianux의 경우) 만일 tftp-server가 HOST PC에 설치 되어 있지 않다면 BSP install시rpm설치를 한다. 아시아 눅 스의 경우 /etc/hosts.deny에 ALL이라고 되어 있다면 이를 삭제한다 Booting Linux 1. Bootloader Fusing (XDB를 사용) (1) Marvell C++ Software Development Tool Suite for Intel XScale Microarchitecture, Professional, v2.1 을설치한다. (2) Marvell XDB Debugger 를 실행하고 start한다. (3) JTAG가 잡혔으면 Flash->Burn Flash를 실행한다. (4) Fusing 하기전에 NAND를 초기화 한다. Extended Flash Functionality 섹션에서 Select NAND Function을 Reset bad block table로 선택하고 Execute 를 클릭한다. 완료 되었으면 Initialize NAND flash 를 선택하고 Execute 를 클릭한다

56 (5) 초기화가 끝났으면 Burning tab에서 Data File로 boot.bin을 고르고Offset in Flash를 0으로 하고 Burn 을 클릭한다. (6) Bootloader Fusing이 완료되었으면 프로그램을 종료하고 보드를 리셋하여 시리얼이 출력되 는지 확인하여 본다. 2. Bootloader, Kernel, Filesystem Fusing Terminal 프로그램(teraTerm, minicom)등을 실행한다 Baud 38400, 8N1, no hardware flow control로 설정을 한다. 부팅중 Autoboot (3 seconds) in progress, press any key to stop.. 메시지가 나오 면 키를 입력하여 blob> 커맨드 상태로 간다. HOST PC와 tartget board의 IP를 설정한다. setip 명령으로 현재 설정된 ip를 알 수 있다. 타겟보드의 IP설정 기본값 Target , Server 이다. 아래와 같은 방법으로 IP를 설정할 수 있다. 아래는 예시이다. blob> setip serverip [서버/HOST PC] IP => ex) setip serverip blob> setip clientip [타겟/보드] IP => ex) setip clientip blob> setip -- 설정된 IP확인 HOST PC의 tftp 디렉토리에 커널 이미지인 zimage를 복사 한다음 각각 이미지를 다운로드 받는다. tftp [file name] -> Ex) blob> tftp zimage 이미지는 램 address 0x 에 다운로드 받으며 이미지 다운로드가 끝났다면 Nandwrite 명령으로 Flash에Fusing한다. 커널은 Nand address 0x 에서 offset은 0x 이다. Ex) blob> nandwrite -z 0x x x 같은 방법으로 gtk.img를 다운받고 Flash에Fusing한다

57 Yaff image의 경우 fusing방법이 다르기 때문에 커맨드의 차이가 있으므로 주의해야 한다. Ex) blob> tftp gtk.img blob> nandwrite -y 0x x Fusing이 모두 끝났다면 타겟을 재부팅 하거나 nkernl명령으로 boot한다. Ex) blob> nkernel Bootloader가 이미 올라가 있는 상태라면 Bootloaer상에서 XDB없이 Fusing이 가능하다. boot.bin을 다운받고 Flash에 Fusing한다. tftp [file name] Ex) blob> tftp boot.bin blob> nandwrite -z 0x x x

58 3.3 개발환경 구축 Serial setting 1. minicom setting (for Linux) (1) s 옵션으로 minicom 설정 창을 띄운다. (2) Serial port setup 에서 Bps N1, Hardware Flow Control : NO로 세팅한다

59 * Serial Device에서 /dev/ttys0는 COM1, /dev/ttys1은 COM2이다 USB to serial을 사용 할 경우 /dev/ttyusb0로 시작된다. 설정이 모두 끝났으면 Save setup as dfl"로 저장하 고 종료한후 다시 minicom을 실행한다 tftp-server setting 1. tftp-server 설치 (For linux) (1) rpm qa grep tftp 옵션으로 tftp-server rpm이 설치되어 있는지 확인한다

60 (2) 설치가 되어 있지 않으면 BSP CD 의 RPM 디렉토리에 있는 tftp-server rpm을 설치한 다. (3) tftp rpm이 설치 되면 /etc/xinetd.d/tftp 파일이 생성된다. 아래와 같이 수정하여야 한 다. /etc/xinetd.d/tftp 파일이 없다면새로 생성하여 아래와 같이 작성한다 (4) server_args를/tftpboot로 설정하면 Bootloader에서 파일을 받을때는 Host의 /tftpboot 안에 있는 파일만 전송이 가능하다. /tftpboot은tftp server daemon의 root directory로 tftp 요청시 필요한 파일을 이곳을 기준으로 찾는다. 이 directory와 subdirectory에서만 찾는다. tftp로 다운로드 하고자 하는 Kernel과 파일시스템 Image는 이곳에 있어야 한다. 필요하다 면 다른 이름을 사용하여도 된다. 위의 스크립트에서 정한 /tftpboot 디렉토리가 호스트PC상에 존재해야 한다. 디렉토리가 없다면 만들어야 한다

61 (5) 설치가 완료 되었으면 xinetd 서비스를 재시작 한다.. /etc/rc.d/init.d/xinetd restart (6) netstat au 명령으로 현재 tftp 데몬이 수행중인지 확인한다. 2. tftp-server 설치 (For Windows) (1) 윈도우 환경에서 tftp를 사용할 경우 윈도우용 tftp server 프로그램을 설치한다. Winagents에서 배포하는 WinAgents TFTP server 프로그램을 설치한다. Winagents 홈페이 지 ( 에서 직접 다운로드 받으수 있으며 BSP CD의 UTIL 디렉 토리에 있는 tftpsetup.exe 를 설치해도 된다. (2) 윈도우 용은 설정이 간단하다. Server->Manage repositry 다운로드를 할 디렉토리를 지정하고 tftpserver를 start하면 된다. client부분은 설정하지 않아도 된다. 설정하였다면 종 료하지 않고 창을 띄어 놓고 사용한다

62 3.3.3 Cross-Complier 경로 설정 1. bash_profile 수정 (1) BSP install이 완료 되었다면 /usr/local/arm-linux-4.1.1/bin 에 크로스 컴파일러가 설 치가 된다.추후에 어플리케이션 크로스 컴파일시 PATH가 있어야 정상적으로 컴파일 되기 때문에.bash_profile을 수정한다..bash_profile은 로그인한 계정 디렉토리에 있다. # vi ~/.bash_profile

63 (2) 수정 후 다시 로그인하면 적용이 된다. echo 명령으로 PATH 가 잘 적용되어있는지 확인해 본다. #echo $PATH

64 320TKU_linux응용 실습에 들어가기전에 응용 어플리케이션을 컴파일하기 위해서는 320TKU 커널과 툴체인이 설치 되어있어야 한다. 본 교재에서는 응용 어플리케이션 중점으로 설명을 하므로 앞에서 개발환경 구축, 커널컴파일 및 이미지 다운로드 방법등을 간단히 설명하였다. 실습 시 발생하는 타겟보드의 자세한 사용법 및 명령어에 대해서는 하이버스 IT교재 시리즈인 임베디드 리눅스 설계 및 응용 교재를 참고 하기 바란다. 응용 실습편에서는 그 외에도 실습에 필요한 기타 지식들이 많이 요구된다. 실습에 필요한 설명을 많이 넣으려고 노력했으나 한권의 책에 모두 자세히 기술 할 수 없으므로 실습위 주의 설명을 하였다., 이해가 가지 않는 부분과 실습에 필요한 이론등은 기타 정보를 이용해 습 득하기 바란다. 기존에 320TKU를 이용하여 커널 컴파일을 해보고 타겟보드에 다운로드를 해 놓은 경우 어플 리케이션 동작을 위해 몇 가지 드라이버가 변경되었으므로, 새로이 커널을 컴파일하여 타겟보드 에 올려야 한다. 이미 변경되어 새로이 컴파일 된 커널은 제공된 CD의 image 디렉토리에서 제 공되고 있으며, 해당 커널이미지와 파일시스템을 올려서 사용한다. 커널 컴파일을 해보지 않았거나 타겟보드에 아무런 커널도 올라가 있지 않은 경우는 하이버스 IT교재 시리즈인 임베디드 리눅스 설계 및 응용 교재를 참고하여 부트로더를 올리고 커널과 파일시스템을 올릴 때는 본 교재에서 제공된 CD의 image 디렉토리에 있는 이미지를 다운로드 하여 사용하면 된다. 검은화면에 마우스 포인터만 보인다면 정상적으로 커널이미지와 파일시스템 이 올라간 것이다. 교재를 이용하여 학습 하는동안 명령어 입력시 오류가 발생방지를 위해서 호스트 PC와 타겟보 드의 입력 방법의 구분은 다음과 같이 하였다. 타겟보드에 명령어를 입력시 320TKU]# 명령어 입력 -- 타겟보드의 명령어 입력 Host PC에 명령어 입력시 ]# 명령어 -- Host PC의 명령어 입력 기타 편집기 실행 또는 파일 수정시 - 내 용

65 Chapter 1. 스톱워치 1. 개요 스톱워치 프로그램은 임베디드 시스템에서 간단하게 구현해볼 수 있는 가장 기본적인 프로그램 들 중 하나이다. X-HYPER320 TKU에 부착되는 IEB 보드의 FND와 KEY matrix를 활용하여 실제 로 스톱워치와 유사한 기능을 가진 프로그램을 구현해보자. 2. 관련기술 2.1 임베디드 S/W 기술 일반적인 컴퓨터가 아닌 각종 전자제품이나 정보기기 등에 설치되어 있는 마이크로프로세서 (Microprocessor)에 미리 정해진 특정한 기능을 수행하는 S/W를 내장시킨 시스템을 임베디드 시스템이라 하고, 여기에 내장된 소프트웨어가 바로 임베디드 S/W이다. 즉, 임베디드 S/W는 산 업 및 군사용 제어기기, 디지털정보가전기기, 자동센서장비 등의 기능을 다양화하고 부가가치를 높이기 위한 핵심 S/W로, 일상생활 속에서 쉽게 접하는 휴대폰, TV, 세탁기, 기차, 비행기, 엘리 베이터 등의 제품 안에 내장된 임베디드 시스템에서 하드웨어를 제외한 나머지 부분이라고 할 수 있다. 최근 IT 기술은 마이크로프로세서의 가격이 낮아지고 소형화 및 고성능화가 진행됨에 따라 제품 경쟁력의 핵심이 H/W 생산기술에서 S/W 최적화 기술로 이동하는 변혁기를 맞이하여 임베디드 S/W가 탑재된 상품의 가치가 H/W보다는 S/W에 의해 좌우되는 기술 집약적 고부가가치 산업으 로 발전하고 있다. 초창기 임베디드 S/W는 간단한 제어 프로그램만으로 산업용 기기를 제어하는 데 그쳤으나, 최근에는 멀티미디어 처리와 같은 점차 복잡한 기능을 위해 멀티태스크 및 네트워 크 기능을 제공하는 임베디드 OS를 이용하고 있다. 임베디드 S/W의 특징을 간략히 정리하면 다음과 같다. 시간 처리 지원 : 실시간 처리가 지원되지 않으면 큰 손실이나 위험을 초래할 수 있는 비행 제어 시스템 및 항법 시스템 등에서 실시간 처리를 지원하여야 한다 고신뢰성 : 원자력 발전, 항공기 및 미사일 제어 등과 같은 S/W 오작동이나 불시의 작동 중 지 등으로 심각한 결과를 초래할 수 있는 시스템에서 고도의 신뢰성이 요구된다. 최적화 기술지원 : 임베디드 시스템은 크기, 가격 및 발열 등을 이유로 제공된 H/W 자원으 로 구성되기 때문에 임베디드 S/W는 경량화, 저전력 지원 자원의 효율적 관리 등의 측면에서 H/W에 최적화되는 기술을 지원하여야 한다. 특정 시스템 전용 : 범용 데스크탑 또는 서버에서 실행되는 패키지 소프트웨어와 달리 특정 시스템의 실행을 목적으로 개발되는 S/W이다. 네트워크 및 멀티미디어 처리기능 지원 : 임베디드 시스템들이 단독형 시스템뿐만 아니라 유 무선 네트워크를 통해 연결될 수 있어야 하고, 멀티미디어 정보를 처리하는 기술이 필요한 디지 털 TV, PDA 및 스마트 폰 등과 같은 임베디드 시스템을 지원해야 한다. 다양한 솔루션과 개발도구 필요 : 다양한 기종과 규격의 마이크로프로세서에 최적화된 별도 의 솔루션이 동시에 제공되어야 하며, 고난도의 임베디드 S/W application을 빠르고 안정되게 개발하기 위해 사용하기 쉬운 개발 도구가 필요하다

66 2.2 디바이스 드라이버 디바이스(Device)란 LCD, USB, Ethernet, PCMCIA, CF, AUDIO, Keypad 등과 같이 컴퓨터 시 스템(Flash Memory, SDRAM 등의) 이외의 주변장치를 말하고, 드라이버란 이러한 하드웨어 장 치를 제어하고 관리하는 방법을 컴퓨터 시스템에게 알려주는 조그만 크기의 응용 프로그램을 말 한다. 보통 이 드라이버를 디바이스 드라이버라고 부르는데, 디바이스를 구동시키기 위해서는 반 드시 필요한 프로그램이라고 생각하면 된다. 리눅스 커널에서 지원하는 드라이버도 있지만(예를 들면 마우스, 키보드, 플로피 등) 그렇지 않은 경우에는 해당 드라이버를 찾아 설치하거나 만들 어 줘야한다. 이런 디바이스 드라이버의 기능을 간단하게 요약하면, 물리적인 하드웨어 장치를 다루고 관리라 는 소프트웨어로 커널의 일부분이며, Major number(주 번호)와 Minor number(부 번호)를 이용 하여 각 디바이스를 구분하여 사용한다. 응용 프로그램이 하드웨어(디바이스)를 제어할 수 있도 록 인터페이스를 제공해주는 코드로 프로그래머로 하여금 하드웨어에 독립적인 프로그램을 작성 하도록 도와준다, 표준화된 call을 이용하여 디바이스와 정보를 주고 받을 수 있도록 하는 역할 을 하며 유닉스의 기본적인 특징 중 하나인 추상화 장치를 다루는 데 사용한다는 것이다, 모든 하드웨어 장치들은 보통 파일처럼 보이며, 파일을 다루는 데 쓰이는 표준 System call 과 같이 open, read, write, close를 사용한다

67 3. S/W 설계 3.1 기능 스톱워치의 기능은 다음과 같다. 1/100초 단위의 카운트 키를 이용하여 시작, 정지, 계속, 리셋, 클리어, 종료를 수행할 수 있다. 8개의 FND를 활용하여 최대 99시간 까지 표기가 가능하다. 3.1 구성 스톱워치의 시스템 구성은 다음과 같다. 스톱워치는 KEY Matrix를 통해 제어하고, 제어 상태를 CLCD에 디스플레이한다. 스톱워치가 동 작하게 되면 FND 상에 숫자가 표시되며 카운팅 되는 것을 확인할 수 있다. 3.3 동작 방법 다음과 같은 키를 입력하여 해당 기능을 수행할 수 있다

68 START : 1번 키를 클릭하면 1/100초 단위로 카운트를 시작 하게 된다. STOP : 2번 키를 클릭하면 카운트를 일시 정지한다. (내부적으로는 카운트를 계속 함) CONTINUE : 3번 키를 클릭하면 일시 정지 상태에서 다시 카운트를 수행하게 된다. 이 때 내부적으로 카운트 된 값으로 갱신된다. RESET : 4번 키를 클릭하면 카운트를 0으로 초기화 시키고 다시 카운트를 수행한다. CLEAR : 5번 키를 클릭하면 카운트 자체를 완전히 초기화 시킨 상태에서 정지한다. EXIT : 6번 키를 클릭하면 프로그램을 완전 종료하게 된다. 4. S/W 구현 stopwatch.c의 주요 소스코드 unsigned char key_get(int tmo) // 키 버튼 입력을 읽어오는 함수 { unsigned char b; if (tmo){ if (tmo < 0) tmo = ~tmo * 1000; else tmo *= ; while (tmo > 0){ usleep(10000); ioctl(keyfd, FIONREAD, &b); if (b) return(b); tmo -= 10000; return(-1); else { read(keyfd, &b, sizeof(b)); return(b); void printlcd(int row, char* data) // CLCD에 스트링을 출력하는 함수 { memset(buffer, ' ', sizeof(buffer)); strcommand.rows = row; strcpy(buffer, data); memcpy(strcommand.buf, buffer, sizeof(buffer)); write(clcdfd, &strcommand, sizeof(strcommand)); void clearlcd() // CLCD의 스트링을 클리어 하는 함수 { ioctl(clcdfd, IOM_LCD_CLEAR, &strcommand, 32);

69 void ten_ms_time() { int i; struct timeval now, now2; long elpsec, elpusec; // 타이밍 계산을 위한 연산시간측정 함수 gettimeofday(&now, NULL); for(i=0; i < ; i++); gettimeofday(&now2, NULL); elpsec = now2.tv_sec - now.tv_sec; elpusec = now2.tv_usec - now.tv_usec; printf("elapse : %ld sec %ld usec n", elpsec, elpusec); ten_ms_time() 함수의 경우 실질적으로 프로그램 동작에는 관여하지 않는다. 단지 스톱워치 구현과정에서 카운트 딜레이 타이밍을 계산하기위해 만들어 졌다. 원하는 시간을 얻기 위해 for 문안에 값을 입력하고 측정된 값이 원하는 시간과 대략 일치 할 때 까지 시행착오를 반복할 수 있다. 이 프로그램에서 입력된 으로 대략 10ms의 타이밍 값을 얻을 수가 있었다. 정확한 시간을 측정하기 위해서는 커널에서 OS 타이머를 이용해야 되겠 지만, 설계된 FND 디바이스 드라이버에서는 OS 타이머를 사용하지 않기 때문에 사용이 불가능 하다. 소프트웨어 상에서 해결을 위한 가장 좋은 방법은 이와 같이 연산측정을 통한 for 문 딜레 이를 사용하는 것이다. API 중에 usleep()이 있기는 하나 실제로 측정을 해보면 오차가 대략 40% 발생한다. 그렇기에 직접 for 문을 이용한 방법을 선택하였음을 이해하기 바란다

70 void *cnt_timer(void *argv) { struct timeval tp1, tp2; int i; // 쓰레드로 동작하는 카운트 증가 함수 while(1) { switch (command) { case KEY_NUM1: case KEY_NUM3: case KEY_NUM4: write(fndfd, fnd_count, sizeof(fndcnt)); // FND에 현재 카운트 표시 break; case KEY_NUM2: break; case KEY_NUM5: case KEY_NUM6: pthread_exit((void *)NULL); // 프로그램 종료 시 쓰레드를 탈출 break; for(i=0; i < ; i++); // 10ms fnd_count[7]++; // 내부 카운트 증가 if(fnd_count[7] > 9) { fnd_count[7] = 0; fnd_count[6]++; if(fnd_count[6] > 9) { fnd_count[6] = 0; fnd_count[5]++; if(fnd_count[5] > 9) { fnd_count[5] = 0; fnd_count[4]++; if(fnd_count[4] > 5) { fnd_count[4] = 0; fnd_count[3]++; if(fnd_count[3] > 9) { fnd_count[3] = 0; fnd_count[2]++; if(fnd_count[2] > 5) { fnd_count[2] = 0; fnd_count[1]++; if(fnd_count[1] > 9) { fnd_count[1] = 0; fnd_count[0]++;

71 cnt_timer() 함수는 쓰레드로 등록되고 호출되는 핵심 기능의 함수이다. 10ms 마다 1/100초 단위로 카운트를 증가시키고 FND에 표시하게 된다. 중간에 사용된 for 문은 이 전에 언급했던 측정시간함수에 의해 얻어진 결과 값을 딜레이로 사용 한 것이다. // 메인함수의 일부 if ((clcdfd = open(clcddev, O_WRONLY O_NDELAY)) < 0) { perror("cannot open /dev/clcd!"); exit(-1); // CLCD open if ((fndfd = open(fnddev, O_WRONLY)) < 0) { perror("cannot open /dev/fnd!"); exit(-1); // FND open if ((keyfd = open(keydev, O_RDONLY)) < 0) { perror("cannot open /dev/key!"); exit(-1); // KEY open memset(fnd_count, 0, sizeof(fnd_count)); write(fndfd, fnd_count, sizeof(fnd_count)); ioctl(fndfd, 2, 0x80); clearlcd(); // FND 초기화 // CLCD 클리어 printlcd(0, "IEB Stopwatch "); printf(" n"); printf(" [7Seg Stopwatch] n"); printf(" n"); printf(" KEY1 -> Start n"); printf(" KEY2 -> Stop n"); printf(" KEY3 -> Continue n"); printf(" KEY4 -> Reset n"); printf(" KEY5 -> Clear n"); printf(" KEY6 -> Exit n"); printf(" n"); sleep(1);

72 do { keyvalue = key_get(10); // 입력된 키 값을 읽어 옴 switch(keyvalue) { case KEY_NUM1: // 1번키 : 시작 if (flag == 0) { printlcd(1, "Start "); pthread_create(&thread_t, NULL, cnt_timer, NULL); command = KEY_NUM1; flag = 1; break; case KEY_NUM2: // 2번키 : 정지 printlcd(1, "Stop "); command = KEY_NUM2; break; case KEY_NUM3: // 3번키 : 계속 printlcd(1, "Continue "); command = KEY_NUM3; break; case KEY_NUM4: // 4번키 : 리셋 printlcd(1, "Reset "); memset(fnd_count, 0, sizeof(fnd_count)); command = KEY_NUM3; sleep(1); break; case KEY_NUM5: // 5번키 : 클리어 printlcd(1, "Clear "); command = KEY_NUM5; pthread_join(thread_t, (void **)status); memset(fnd_count, 0, sizeof(fnd_count)); write(fndfd, fnd_count, sizeof(fnd_count)); flag = 0; break; case KEY_NUM6: // 6번키 : 프로그램 종료 printlcd(1, "Exit Program..."); sleep(3); command = KEY_NUM6; pthread_join(thread_t, (void **)status); default: break; while(keyvalue!= KEY_NUM6);

73 1번 키를 클릭하게 되면 cnt_timer() 함수가 쓰레드로 수행이 된다. 내부 카운트를 증가시키게 된다. 여기서 flag를 하나 둬서 1번 키를 클릭했을 경우 5번 키(리셋) 가 클릭되지 않는 한 실행 중에는 중복으로 쓰레드가 생성되지 않게 처리를 하였다. 6번 키를 클릭하면 쓰레드 탈출과 오픈 된 디바이스를 해제시키고 프로그램을 종료 시킨다. 5. 수행 방법 및 결과 5.1 수행 방법 교재와 함께 제공된CD를 이용하여 호스트 PC의 루트 디렉토리에 320app 라는 임시폴더를 만든다. ]# mkdir /320app '320app'라는 폴더가 생성이 되면 그곳에 CD-ROM을 마운트 하여 CD의 내용을 모두 복사한 다. ]# mount /dev/cdrom /mnt/cdrom --CD롬마운트하기 ]# cd /mnt/cdrom -- 마운트한 CD롬으로 이동 ]# cp -a./ /320app/ -- cdrom의 내용을 320app디렉토리에 복사 320app디렉토리를 복사하여 살펴보면 아래그림과 같은 디렉토리들이 존재한다. Application디렉토리로 이동하여 Application.tgz 파일을 압축을 해제한다. ]# cd Application -- Application디렉토리로 이동 ]# tar zxvf Application.tgz -- Application.tgz 파일 압축풀기 ]# ls -- 압축푼 파일 확인 압축을 해제하면 다음과 같이 본 교재에서 사용될 각종 어플리케이션 프로그램 소스디렉토리 가 존재한다. Stopwatch 디렉토리로 이동하면 이미 생성된 어플리케이션 이미지들이 보인다. ]# cd Stopwatch -- Stopwatch 디렉토리 이동 ]# ls -- 디렉토리 내용보기 ]# make clean -- 이미 생성된 이미지 삭제

74 make clean 을 실행하지 않고 make 를 실행하면 stopwatch 는 이미 갱신되었습니다. 라 는 메시지가 출력될 것이다. make 명령어를 입력하여 컴파일을 진행해보자 ]# make -- 이미지 생성 ]# ls -- 생성된 이미지 확인 생성된 실행파일을 타겟보드로 다운로드한다. 다운로드 방법에는 Z-MODEM을 이용한 시리얼 다운로드, NFS 마운트를 이용한 다운로드, FTP를 이용한 다운로드등 여러 가지가 있다. 어플리 케이션의 용량에 따라 적합한 방법을 선택하여 사용하면 된다. Stopwatch 어플리케이션은 리눅스의 minicom의 Z-MODEM을 이용하여 다운로드 해 보도록 한다. 기타 방법에 익숙한 사용자는 자신이 주로 사용하는 방법을 이용해도 무방하다 5.2 Z-MODEM을 이용한 다운로드 방법 Z-MODEM을 이용하여 이미지를 다운로드 하기위해 리눅스의 시리얼 모니터링 프로그램인 minicom을 이용해 보도록 한다. ]# minicom -- 미니컴 실행 minicom을 실행하고 타겟보드를 재부팅 하면 타겟보드의 파일시스템을 볼 수 있다. 'test_app' 디렉토리로 이동하여 zmodem을 실행시켜 보자 minicom이 실행되면 'Cntr + A ' => 'S' 를 눌러 Z-MODEM을 실행한다. 320TKU]# Cntr + A 320TKU]# S -- 미니컴 옵션 -- Z-MODEM선택

75 호스트 PC의 어플리케이션이 있는 경로로 이동하여 파일을 다운로드 한다. 경로이동시에는 스페이스바를 두 번 눌러 이동하고 파일선택 후 다운로드 할 때에는 엔터를 친다. 파일이 다운로드되면 타겟보드의 test_app 디렉토리 안에 다운로드가 되게 된다. 디렉토리를 확인해 보면 stopwatch 실행파일이 다운로드 된 것을 확인 할 수 있다. 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./stopwatch 앞에서 동작설명을 한 대로 동작 테스트를 해본다

76 5.3 수행 결과 실행화면 콘솔 상에서 프로그램을 실행하면 다음과 같은 화면이 나타난다. 설명대로 해당 키 버튼을 누르게 되면 동작을 하게 된다

77 시작화면 초기상태이다. 동작화면 1/100초 단위로 카운트 된다

78 Chapter 2. MP3 Player 1. 개요 본 장에서는 MP3 플레이어의 주요 기능을 X-HYPER320 TKU의 IEB 보드를 통해 구현해 보았 다. KEY Matrix를 이용하여 Play, Stop, 선곡, 볼륨 조절을 할 수 있으며 일시정지 기능이 없는 것만 빼고 나머지 기능은 거의 흡사하다. 현재 디렉토리에 있는 파일들을 리스트로 관리하며 곡 을 재생시키고 곡명을 Character LCD에 디스플레이 한다. 2. 관련기술 2.1 오디오 압축기술 (MPEG Audio Layer-3) 우리가 듣는 CD의 경우 대역폭이 44.1 khz이다. 이를 디지털 신호로 샘플링 한다고 할 때 1초 동안의 CD 음질의 스테레오 사운드에 해당하는 데이터의 양은 무려 1,400 KB이며, 이는 1.44M 용량의 고밀도 플로피 디스크 한 장을 완전히 채워야 할 정도의 데이터양에 해당한다. 정리하자 면 압축되지 않은 일반 디지털 신호를 그대로 저장한다고 하면, 3분짜리 음악 파일을 위해 250MB의 여유 공간이 필요하다는 것이다. MPEG 오디오 압축 기술을 적용함으로써, CD의 오디오 사운드 정보를 1/12까지 줄일 수 있다. 다시 말해 MP3 파일로 CD를 제작할 경우, CD 한 장에 오디오 CD 12 장 분량을 담을 수 있다 는 말이다. 이런 이유로 인터넷에서 리얼타임 오디오 서비스를 하기 위해서는 원래의 오디오 음 질을 그대로 유지하면서도 실시간으로 복원할 수 있는 오디오 압축기술이 필요하다. Layer3 오 디오 압축 기술은 이러한 요구를 충족할 수 있는 최적의 솔루션이 라고 할 수 있다 Mbps의 대역폭을 갖는 T1급의 LAN을 통해 인터넷에 접속한다면 Layer3로 압축된 CD 음 질의 파일을 모두 받는데 걸리는 시간은 불과 13초 정도에 불과 하다. 이 음악을 연주하는데 걸 리는 시간은 3분(180초)이므로, 사용자는 처음 1 비트의 사운드 파일을 전송 받자마자 압축 복 원을 하면서 연주를 한다고 해도 중간에 나머지 데이터가 전송되기를 기다릴 필요가 없다, 즉 실시간 오디오 연주가 가능한 것이다. 2.2 AC97 (Audio Codec) AC97은 1997년 인텔의 아키텍처 랩에서 개발한 오디오 코덱 표준으로 그 기능이 인텔 칩셋들에 통합되어 인터페이스를 지원하고 있다. AC97은 DC97과 ICH 두 개의 컴포넌트로 구성되어 있으 며 주로 데스크탑 플랫폼에서 고품질 서라운드 사운드 지원을 위해 사용된다. AC-Link는 DC97을 연결하는 디지털 링크이다 MHz의 클럭, 싱크, 리셋, 2개의 데이터 라인으로 총 5개의 Wire로 구성되어 있다. AC-Link는 하나의 컨트롤러와 여러 개의 오디오 코덱 들 사이에 양방향, Mbit의 고정된 Bitrate, 시리얼 디지털 스트림을 제공한다. 데이터 스트 림은 254bit 프레임으로 분할된다. 이것은 TDM 방식으로 이루어진다. 모든 프레임은 13개의 슬 롯으로 세부적으로 구성되어 있으며 슬롯0 (16bit)은 오디오 코덱이 컨트롤러와 통신하는데 특정 하게 사용된다. 나머지 240bit는 20bit 씩 12개의 슬롯으로 나눠지며 데이터 슬롯으로 사용된다

79 데이터 슬롯 (48KHz, 20bits/sample)은 PCM 오디오 신호(960Kbit/s)를 전송하는데 사용된다. 같은 프레임 내의 여러 데이터 슬롯들은 하나의 고품질 신호로 결합시킬 수 있다. (최대 4개 슬 롯, 96KHz, 20bit/sample, 스테레오 신호) 3. S/W 설계 3.1 기능 MP3 플레이어의 기능은 다음과 같이 요약할 수 있다. Play, Stop, 선곡의 기본 기능을 갖추고 있다. ALSA Mixer (amixer)를 이용하여 볼륨 조절이 가능하다. 재생 시 곡명을 Character LCD에 상에 보여준다. 재생 중 언제든지 다른 곡을 재생할 수 있다. 자동으로 연속 재생이 가능하다. 3.2 구성 MP3 플레이어의 시스템 구성은 다음과 같다. MP3 플레이어는 IEB 보드의 KEY Matrix를 통해 제어를 한다. CPU가 제어 신호를 입력 받으면 해당 기능을 수행하게 되는데 음악파일을 재생할 경우 파일시스템으로부터 현재 디렉토리에 있 는 음악들 중 최상위 리스트에 있는 음악을 mpg123 프로그램에서 호출하여 재생하게 된다. 이 때 WM9712는 음악파일을 디코딩 후 아날로그 신호로 변환하여 스피커로 출력시키게 된다. 재 생 중에는 리스트에 저장되어 있는 음악파일명을 CLCD로 전송하여 디스플레이하게 된다

80 3.3 동작 방법 MP3 플레이어는 다음과 같이 키를 입력하여 제어할 수 있다. POWER ON/OFF : MP3 플레이어를 켜고 끌 수 있다. MODE Selection : 선곡 리스트 모드를 켜고 끌 수 있다. Play, Stop : 플레이어의 기본 제어를 할 수 있다. Volume UP/DOWN : amixer 프로그램 제어를 통해 볼륨 조절을 할 수 있다. Post, Prev : 다음 곡이나 이 전 곡을 선곡 및 재생할 수 있다. 4. S/W 구현 mp3p.c 주요 코드 #define MDIR "MUSIC/" // 음악파일 저장 디렉토리 struct strcommand_varible { // Character LCD 제어 명령어 구조체 char rows; char nfonts; char display_enable; char cursor_enable; char nblink; char set_screen; char set_rightshit; char increase; char nshift; char pos; char command; char strlength; char buf[16]; strcommand; 음악파일들이 저장될 디렉토리를 지정하였다. 아래의 makelist() 함수를 통해 디렉토리를 오픈할

81 때 사용된다. int makelist() { DIR *dp; struct dirent *dep; // mp3 파일 디렉토리를 오픈한다. if((dp = opendir("music")) == NULL){ perror("opendir"); exit(0); // 해당 디렉토리 내 파일이름을 읽어와 playlist에 저장 while(dep=readdir(dp)){ if(strcmp(dep->d_name, ".") ==0) { // "." 저장하지 않는다. // printf(". doesn't save in playlist n"); else if(strcmp(dep->d_name, "..") == 0) { // ".." 저장하지 않는다. // printf(".. doesn't save in playlist n"); // "MUSIC" 디렉토리는 저장하지 않는다. else if(strcmp(dep->d_name, "MUSIC") == 0) { // printf("music doesn't save in playlist n"); else{ strcpy(playlist[count], dep->d_name); printf("playlist[%d]: %s n", count, playlist[count]); count++; max = count; // 파일 수를 max에 저장 count = 0; return 0; MUSIC 디렉토리를 오픈하여 포함되어 있는 확장자가 mp3로 끝나는 모든 음악파일들을 검색하 여 playlist에 저장시킨다

82 int middleplay() //연속 재생 { int pid_p, stat_val; char *tmp = NULL; if((pid_p=fork())==0){ signal(sigint, SigMidlleHandler); //정지 signal(sigalrm, SigMidlleHandler); //재생 while(1){ strcpy(music, playlist[count]); pid_c=play(music); pid_c=wait(&stat_val); //부모가 자식프로세스 종료를 기다리게 함 strcpy(dir, MDIR); findindex(music); if(count == (max-1)){ count = 0; else if(count < (max-1)){ count++; else return pid_p; int play(char *string) // 재생 { int pid; char *argv[] = {"mpg123", strcat(dir, string), (char *)0; if((pid=fork())==0){ signal(sigint, SigHandler); //정지 if(execv("/usr/bin/mpg123", argv) <0 ) { // mpg123 외부 프로그램 실행 perror("execv"); return 0; else { return pid;

83 // 재생중인 곡이 playlist의 몇 번째에 저장되어 있는지 찾는다. int findindex(char* string) { int i; for(i=0; i<max; i++){ val = strcmp(string, playlist[i]); if(val == 0){ count = i; break; return 0; void *shift_clcd(void *argv) // 쉬프트된 스트링을 CLCD에 출력한다. { int i; memset(tmp_row, 0, sizeof(tmp_row)); strncpy(tmp_row, row_one, 16); while (1) { if (sht_disable == 1) pthread_exit((void *)NULL); else { strcommand.pos=0; ioctl(dev, IOM_LCD_DD_ADDRESS, &strcommand, sizeof(strcommand)); for(i=0; i<16; i++){ if(tmp_row[i] == ' 0') tmp_row[i] = ' '; memcpy(&strcommand.buf[0], &tmp_row[i], 1); ioctl(dev, IOM_LCD_WRITE_BYTE, &strcommand, sizeof(strcommand)); shift_buff_string(tmp_row); usleep(500000); void shift_buff_string(char *tmp_row) // 스트링을 왼쪽으로 쉬프트 시켜서 저장한다. { int i; char tmp; tmp = tmp_row[0]; for (i=0; i<15; i++) tmp_row[i] = tmp_row[i+1]; tmp_row[15] = tmp;

84 int main(void) { ~ 중략 ~ while(1) { strcpy(dir, MDIR); pressvalue = key_get(100); // 입력된 키 버튼 정보를 읽어온다. // printf("pressed key value %x n", pressvalue); switch(pressvalue) { case 0x1: // Power On/Off Character LCD if(status == 0) { // Power on printf("power on n"); if(system("amixer cset numid=2 21") == -1){ printf("error : amixer vol "); if(system("amixer cset numid=16 21") == -1){ printf("error : amixer pcm"); status = 4; if(dev!= -1){ write(dev, &strcommand, 8); sleep(1); memset(row_one, 0, 16); memset(row_two, 0, 16); printf("memset execute n"); showlcd(); else { // Power off printf("power off n"); if(pid!=0) { kill(pid,sigint); sht_disable = 1; pthread_join(thread_t, (void **)0); ioctl(dev, IOM_LCD_CLEAR, &strcommand, sizeof(strcommand)); sleep(1); memcpy(&strcommand.buf[0], end, sizeof(strcommand.buf)); write(dev, &strcommand, 8); sleep(1); exit(1);

85 무한루프 상에서 키를 입력 받고 입력 받은 키 버튼의 정보에 따라서 각각의 주어진 역할을 수 행하도록 되어 있다. case 0x2: // Mode 선택 if(list == 0) list = 1; else list = 0; break; case 0x3: // 음악 재생 if (thread_enable == 1) { sht_disable = 0; pthread_create(&thread_t, NULL, shift_clcd, NULL); thread_enable = 0; if(list==1 && status == 4) { // 재생 중인 음악이 없을 때 if((pid = middleplay()) == 0) printf("play error!"); else status = 3; // 재생 중이고 리스트 보기일 때 else if(list == 1 && status == 3) { printf("replay n"); kill(pid,sigalrm); kill(pid,sigint); sleep(1); strcpy(music, row_one); pid = play(music); break; case 0x4: // 정지 if (thread_enable == 0) { sht_disable = 1; pthread_join(thread_t, (void **)0); thread_enable = 1; if(pid!=0) { kill(pid,sigalrm); if(kill(pid,sigint) == -1) { perror("sigint error"); exit(1); pid=0; status=4; break;

86 재생이 시작되면 CLCD 쉬프트를 위한 쓰레드가 생성이 된다. 곡이 재생 중에 항상 쉬프트 되면 서 CLCD 상에 디스플레이 할 것이다. 쓰레드의 중복실행을 방지하기위한 처리도 하였다. 정지 버튼을 누르게 되면 kill() 함수를 이용하여 SIGALRM을 시스템으로 전달하여 해당 PID를 가진 프로그램 즉, mpg123이 종료되게끔 구현하였다. case 0x5: //volume up volume=volume+2; if(volume > 31) volume = 31; sprintf(strvol, "%d", volume); strcat(vol,strvol); strcat(pcm,strvol); system(vol); system(pcm); vol[21]=pcm[21]=' 0'; break; case 0x6: //volume down volume=volume-2; if(volume < 0) volume = 0; sprintf(strvol, "%d", volume); strcat(vol,strvol); strcat(pcm,strvol); system(vol); system(pcm); vol[21]=pcm[21]=' 0'; break; case 0x7: if (thread_enable == 0) { sht_disable = 1; pthread_join(thread_t, (void **)0); thread_enable = 1; if(list == 0 && pid!=0 ) { // 다음 곡 재생 findindex(music); if(count == (max-1)){ // 재생 중인 곡이 재생 목록의 마지막일 경우 count = 0; // 다음 곡은 재생 목록의 첫 번째 곡으로 해준다. else if(count < (max-1)){ count++;

87 볼륨 조절은 system() 함수를 이용한 간접적 amixer 제어를 통해 이루어지도록 되어 있다. now = count; strcpy(music, playlist[now]); showlcd(); pthread_create(&thread_t, NULL, shift_clcd, NULL); thread_enable = 0; sht_disable = 0; kill(pid,sigalrm); kill(pid, SIGINT); sleep(1); pid=play(music); else { // CLCD 상에서 다음 곡만 선곡 (재생은 하지 않는다.) findindex(music); if(count == (max-1)){ count = 0; else if(count < (max-1)){ count++; now = count; strcpy(music, playlist[now]); showlcd(); break; case 0x8: // 이 전 곡을 선택 if (thread_enable == 0) { sht_disable = 1; pthread_join(thread_t, (void **)0); thread_enable = 1; if(list==0 && pid!=0) { // 이 전 곡 재생 findindex(music); if(count == 0){ // 재생중인 곡이 재생 목록의 처음일 때 count = max-1; // 이 전 곡은 재생 목록의 마지막곡이 된다. else if(count > 0){ count--;

88 now = count; strcpy(music, playlist[now]); showlcd(); pthread_create(&thread_t, NULL, shift_clcd, NULL); thread_enable = 0; sht_disable = 0; kill(pid,sigalrm); kill(pid,sigint); sleep(1); pid=play(music); else { // CLCD 상에서 이 전 곡만 선곡 (재생은 하지 않는다.) findindex(music); if(count == 0){ count = max-1; else if(count > 0){ count--; now = count; strcpy(music, playlist[now]); showlcd(); break; close(key_fd); return 0; MODE가 0이면 다음 곡 또는 이 전 곡을 바로 재생할 수 있지만 1일 경우에는 선곡 기능이 활 성화 되어 다음에 재생할 곡만 미리 선택할 수 있다

89 int showlcd() { int i; // CLCD 상에 재생 목록을 디스플레이 하는 함수 strcpy(row_one, playlist[count]); if(count < (max-1)){ strcpy(row_two, playlist[count+1]); else if(count == (max-1)){ // 재생 곡이 playlist의 마지막일 경우 strcpy(row_two, playlist[0]); // 다음 곡을 playlist의 처음으로 ioctl(dev, IOM_LCD_CLEAR, &strcommand, sizeof(strcommand)); sleep(1); // CLCD의 첫 번째 라인에 출력 strcommand.pos=0; ioctl(dev, IOM_LCD_DD_ADDRESS, &strcommand, sizeof(strcommand)); for(i=0; i<16; i++){ if(row_one[i] == ' 0') break; memcpy(&strcommand.buf[0], &row_one[i], 1); ioctl(dev, IOM_LCD_WRITE_BYTE, &strcommand, sizeof(strcommand)); printf("c : %s n", row_one); // CLCD의 두 번째 라인에 출력 strcommand.pos=40; ioctl(dev, IOM_LCD_DD_ADDRESS, &strcommand, sizeof(strcommand)); for(i=0; i<16; i++){ if(row_two[i] == ' 0') break; memcpy(&strcommand.buf[0], &row_two[i], 1); ioctl(dev, IOM_LCD_WRITE_BYTE, &strcommand, sizeof(strcommand)); return 0; ioctl() 함수를 통해 CLCD를 제어하여 CLCD 상에 스트링(곡명)을 디스플레이 한다

90 5. 수행 방법 및 결과 5.1 수행 방법 어플리케이션 컴파일 방법과 다운로드 및 실행방법은 앞서 해보았던 Stopwatch와 크게 다르지 않다. 호스트 PC에서 /root/320app/application/mp3_player로 이동한다. ]# cd /320app/Application/MP3_Player --mp3 어플리케이션 경로로 이동 make 명령어를 입력한다. ]# make --mp3 어플리케이션 컴파일 아래의 그림은 일련의 과정이다. 생성된 실행파일을 타겟보드로 다운로드한다. 앞선 실습에서와 같이 minocom 의 zmodem 을 이용하여 다운로드 한다. 자세한 내용은 앞의 stopwatch 다운로드 방법을 참고한다. 타겟보드에서 zmodem 을 이용하여 다운로드 할 때 다운로드 파일은 zmodem 을 실행시킨 디렉토리 경로에 다운로드 되게 되어있다. tset_app 디렉토리에서 다운로드를 해보자. 다운로드가 완료되면 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./mp3p

91 바로 실행 되진 않을 것이다. MP3파일이 MUSIC디렉토리에 들어있어야 하기 때문이다. 타겟보드에서 test_app 디렉토리안에 MUSIC 디렉토리를 생성하자 320TKU]# mkdir MUSIC -- MUSIC 디렉토리 생성 타겟보드의 /root/mp3 디렉토리내에 용량이 적은 mp3파일이 들어있다. 이파일을 test_app 디렉토리의 MUSIC 디렉토리로 이동시켜 놓는다. 320TKU]# cp /root/mp3/* /root/tset_app/music -- MP3디렉토리파일의 내용을 MUSIC 디렉토리로 복사 mp3파일을 재생할 준비가 되었다면 어플리케이션을 실행하여 음악을 들어보도록 하자 320TKU]#./mp3p 앞에서 설명한 동작 방법대로 테스트를 해본다. 5.2 수행 결과 제일먼저 KEY1을 클릭해서 전원을 켠다. 시작화면 MUSIC 디렉토리 밑에 있는 음악 파일 이름들이 CLCD 상으로 보인다

92 재생화면 KEY3을 클릭하면 음악 파일이 재생되면서 스피커를 통해 음악을 들을 수 있다. CLCD의 첫 번째 라인이 재생 중인 음악의 곡명이다. 좋아하는 곡을 플래시 메모리등을 이용하여 MUSIC' 디렉토리에 추가하여서 재생시켜보자

93 Chapter 3. 산성비 게임 1. 개요 본 장에서는 간단한 게임 하나를 만들어 보겠다. X-HYPER320 TKU의 IEB보드를 조작하여 타자 연습용 게임과 비슷하게 구현해 보았다. 비록 4자릿수의 숫자 조합을 입력하여 제거하는 단순한 프로그램이지만 키보드가 아닌 키 버튼을 클릭하여 해당 숫자를 입력하는 것이기 때문에 의외로 순발력이 필요하다 난이도가 총 10단계로 설정되어 있고 고급 난이도로 갈수록 속도가 빨라지게 된다. 숫자를 맞추게 되면 화면상에서 해당 숫자는 사라지게 되고 각각의 단계에 따른 구분된 점수를 획득하게 된다. 개인적인으로는 의도와는 다르게 최종적으로 가장 많은 점수를 획득한 사람이 순발력이 가장 뛰어난 사람이 아닐까라는 생각도 해본다. 2. 관련기술 2.1 TFT-LCD 화면에 정보를 표시하는 메커니즘은 전자계산기 등의 숫자 표시에 사용되는 LCD와 같다. 투명 유리 혹은 필름에 코팅된 액정에 전압이 가해지면 분자구조가 변하면서 생시는 편광 현상을 이 용해 뒷면에서 올라오는 빛을 통과시키거나 차단해 정보를 표시하게 되는데, 본 시스템에 내장 된 컬러 TFT-LCD는 화소 하나를 표시하는데 이러한 단위 액정이 세 개 필요하다. 이는 빛의 3 원색인 적색, 녹색, 청색을 각각 제어하기 위함이다. 이 TFT-LCD에 데이터를 표시하기 위해서는 이를 위한 특별한 메모리 영역(Framebuffer)에 데이 터를 써 주기만 하면 된다. 그러면 LCD 컨트롤러에 데이터를 가져다가 화면에 뿌려주는데, 이를 위해서 프로그램은 OS가 제공하는 프레임버퍼 디바이스를 열고 적절한 위치에 데이터를 write 하기만 하면 된다. 2.2 프레임버퍼 디스플레이 장치에 화상신호를 출력하는 부분으로 리프레시 메모리라고도 한다. 화소 표현으로 변환된 한 프레임씩을 임시로 저장하였다가. 신호에 따라 메모리에 저장된 내용을 비트열로 디 스플레이 장치에 출력하게 된다. 프레임버퍼의 크기는 프레임버퍼 드라이버에서 결정되며 드라이버에서 요구된 크기만큼 메모리 영역의 일부를 프레임버퍼로 할당하게 된다. 프레임버퍼 드라이버는 요구된 크기만큼의 메모리영역을 할당하는 것 이외에도 픽셀클럭, BPP,

94 H/V 싱크, 프레임버퍼의 길이, LCD 제어 레지스터 설정 및 LCD 및 백라이트 파워 제어 까지도 관여한다. 3. S/W 설계 3.1 기능 산성비 게임의 기능은 다음과 같이 요약할 수 있다. - 프레임버퍼를 이용하여 TFT-LCD 상에 게임의 전체 폼을 표현하게 된다. - 해당 숫자와 맵핑되는 키 버튼을 클릭하여 숫자를 TFT-LCD 상에 표시하게 된다. - 총 10단계의 난이도로 구성되어 있고 단계가 증가 할 때마다 진행 속도가 빨라진다. - 난이도에 따른 점수가 구분되어 있고 해당 숫자를 제거할 때마다 점수를 획득하게 된다. - 기본 적으로 한 게임당 8번의 기회가 주어지며 기회를 모두 소진 시 게임은 종료된다. - DOT Matrix 상에 난이도가 표시된다. - FND 상에 획득한 점수가 표시된다. - 8개의 라인 LED는 현재 남아있는 기회 즉 생명의 개수를 나타내준다. 3.2 구성 산성비 게임을 위한 시스템 구성은 다음과 같다. TFT-LCD를 통해 게임 화면을 디스플레이하며 KEY 버튼을 이용하여 숫자를 입력 또는 삭제를 할 수 있다. FND 상에는 점수를 표시, DOT 상에는 단계를 표시, 8-LEDs은 남은 생명의 횟수를 표시한다

95 3.3 동작 방법 산성비 게임은 다음과 같이 키를 입력하여 게임을 진행할 수 있다. 0부터 9까지의 숫자와 맵핑된 키 버튼을 클릭하여 4자리 숫자를 입력한다. 잘못 입력 시 Delete와 맵핑된 키 버튼을 클릭하여 이 전에 입력된 숫자를 지울 수 있다. 4자리 숫자를 모두 입력하면 Enter와 맵핑된 키 버튼을 클릭하여 입력 값을 전달한다. 생명을 모두 소진 시 자동으로 게임 종료되며 아무키나 클릭하면 프로그램이 종료된다. 4. S/W 구현 본 프로그램은 총 3개의 소스파일로 구성되어 있다. ssb.c, list.c, driverpack.c ssb.c 파일은 게임의 주요 폼을 그리며, 쓰레드를 사용하여 원활하게 게임이 진행되도록 처리하 는 메인 기능을 가지고 있다. list.c 파일은 Linked List를 활용하여 리스트의 생성 및 추가, 삭제과 같은 주로 리스트 관리 기 능을 가지고 있다. driverpack.c 파일에는 산성비 게임에서 사용되는 물리적인 디바이스들을 시스템 콜 함수들을 이 용하여 쉽게 제어할 수 있는 함수들이 작성되어 있다. ssb.c의 주요 소스코드 typedef struct tagraindrop { char text[5]; // 4개의 숫자조합으로 이루어진 스트링 int x, y; // LCD 화면에 뿌려질 스트링의 X/Y 좌표 int fspecial; // 특별한 레인드롭인지를 구분 RAINDROP; // 레인드롭 구조체

96 // Global variables int IntervalTable[10] = { // 스트링의 단계별 뿌려지는 시간간격 , , , , , , , 75000, 50000, ; int ScoreTable[10] = { // 단계별 적용되는 점수단위 10, 12, 15, 20, 30, 45, 70, 100, 150, 200 ; int rdcounttable[10] = { // 단계별 뿌려질 스트링의 개수 10, 30, 30, 30, 30, 30, 30, 30, 30, 30 ; RAINDROP *GenerateRaindrop() { RAINDROP *rd; int i; // 산성비를 생성시키는 함수 rd = (RAINDROP *) malloc(sizeof(raindrop)); if (!rd) { puts("not enough memory!! n"); exit(1); for (i = 0; i < 4; i++) rd->text[i] = rand() % x30; rd->text[4] = 0; rd->x = rand() % ; rd->y = 3; return rd; // 0에서 9까지의 숫자를 랜덤하게 생성 // 마지막에 Null 값 삽입 // X좌표를 랜덤하게 선택 // Y좌표를 3으로 고정으로 지정 떨어뜨릴 숫자조합 스트링(산성비라고 지칭한다.)을 새롭게 생성한다. 메모리 할당된 RAINDROP 구조체 변수에 랜덤하게 생성된 4자리 숫자조합 스트링과 랜덤하게 선택된 산성비가 시작될 X와 Y의 좌표 값을 저장하고 반환한다

97 int ScrollRaindrop(int LineCount) { RAINDROP *rd; int i, ret = 1; // 산성비를 떨어뜨리는 함수 lcd_savecursorpos(); lcd_settextcolor(white); for (i = 0; i < ListGetCount(rdList); i++) { // Get a raindrop object from raindrop list rd = ListGetItem(rdList, i); // 산성비에 대한 레인드롭 정보를 if (!rd) 가져온다. break; if (LineCount) { // First, remove raindrops from current position lcd_gotoxy(rd->x, rd->y); lcd_putstring(" "); // Now increase Y coordinate of the raindrop and display it rd->y += LineCount; if (rd->y < 27) { lcd_gotoxy(rd->x, rd->y); lcd_putstring(rd->text); else { // If the raindrop landed, remove it free(rd); ListDeleteItem(rdList, i); Life--; i--; ret = 0; RestoreCursorPos(); lcd_restorecursorpos(); return ret; 단계별 정해진 Interval 값에 의해 한 줄씩 산성비가 떨어지게 된다. 산성비가 바닥에 떨어질 때까지 입력을 놓치게 되면 산성비는 제거되고 Life 개수가 하나 줄어들 게 된다. 그 전에 입력을 해서 맞추게되면 산성비는 제거되고 점수는 상승한다

98 void Rain(void *arg) { int i, rdcount = 0; char buff[8]; while(!fthreadenable); // Trigger if (rdlist) DeleteList(rdList); rdlist = CreateList(); while(life) { while(!fthreadenable); // Synchronization if (rand() % 100 < 75 && rdcount < rdcounttable[level - 1]) { ListAddItem(rdList, GenerateRaindrop()); rdcount++; if (!ScrollRaindrop(1)) DispStatus(); if (ListGetCount(rdList) == 0 && rdcount == rdcounttable[level - 1]) { lcd_settextcolor(white); sprintf(buff, "%d", Level); lcd_gotoxy(58, 10); lcd_putstring(" "); lcd_gotoxy(58, 11); lcd_putstring(" LEVEL : "); lcd_gotoxy(69, 11); lcd_putstring(buff); lcd_gotoxy(58, 12); lcd_putstring(" COMPLETE! "); lcd_gotoxy(58, 13); lcd_putstring(" "); Level++; if (Level == 11) Level = 1; sleep(5); for (i = 0; i < 4; i++) { lcd_gotoxy(58, 10 + i); lcd_putstring(" "); lcd_gotoxy(9, 6); sprintf(buff, "%d", Level); lcd_putstring(buff); dot_putchar(level); usleep(intervaltable[level - 1]); if (key_val == 13) break;

99 lcd_settextcolor(white); lcd_gotoxy(57, 10); lcd_putstring(" "); lcd_gotoxy(57, 11); lcd_putstring(" GAME OVER "); lcd_gotoxy(57, 12); lcd_putstring(" PRESS ANY KEY "); lcd_gotoxy(57, 13); lcd_putstring(" "); exitsig = 1; fflush(stdin); DeleteList(rdList); rdlist = NULL; pthread_exit((void *)NULL); while()문 내에서 쓰레드에 의해 산성비를 생성하고 한줄 씩 떨어뜨리게 된다. 각 단계를 클리어 하면 다음 단계로 넘어가게 되며 종료될 경우 while()문을 탈출하여 "GAME OVER" 메시지와 더 불어 게임을 종료시키게 된다. int main() { // Variables declaration pthread_t tid; int status = 0; char buff[80] = " "; int tail = 0; char fndcnt[8]; init_drivers(); lcd_clrscr(); // Variables initialization Level = 1; Life = 8; Score = 0; memset(fndcnt, 0, sizeof(fndcnt)); fnd_putstring(fndcnt); DrawBackground(); Wait5sec(); srand(time(null));

100 main() 문에서 사용될 변수를 선언하고 값들을 초기화 한 후 시작 전 5초를 기다린다. lcd_gotoxy(2, 29); lcd_putstring("enter ===> "); fthreadenable = 1; pthread_create(&tid, NULL, (void *)Rain, NULL); // Rain 함수에 대한 쓰레드 생성 while(1) { while (1) { key_val = key_getkey(); // 입력된 KEY 값을 읽어온다. if (exitsig) { pthread_join(tid, (void **)&status); goto EXIT; if (key_val == 11) { // If backspace pressed if (tail!= 0) tail--; buff[tail] = 32; // Fill white space else if (key_val == 12) { // If enter pressed break; else if (tail < 4) { buff[tail++] = key_val + 0x2F; buff[4] = 0; lcd_settextcolor(white); lcd_gotoxy(13, 29); lcd_putstring(buff); Intercept(buff); // 해당 산성비를 맞출 경우 리스트에서 삭제 memset(buff, 32, 4); 점수가 상승한다. buff[4] = 0; lcd_gotoxy(13, 29); lcd_putstring(buff); tail = 0; EXIT: // 프로그램 종료 절차 fflush(stdout); // To flush output stream lcd_clrscr(); cleanup_drivers(); printf("exit Program... n"); return 0;

101 driverpack.c의 주요 소스코드 void fnd_putstring(unsigned char *str) { write(fnd, str, 8); void led_putvalue(unsigned char val) { int led; unsigned long buff; // FND 디스플레이 함수 // LED 디스플레이 함수 led = open("/dev/led", O_WRONLY); if (led < 0) { puts("fatal error: /dev/led open failed!! n"); exit(1); write(led, &val, 1); close(led); void led_lifecount(int lc) { // Life Count를 계산하는 함수 unsigned char val; unsigned char ledtable[9] = { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00 ; switch (lc) { case 8: case 7: case 6: case 5: case 4: case 3: case 2: case 1: case 0: val = ledtable[lc]; break; default: val = ledtable[0]; break; led_putvalue(val);

102 static void dot_thread(void *dummy) { // DOT 디스플레이 함수 unsigned char data[5] = { 0x0, 0x0, 0x0, 0x0, 0x0; int i; while(fthreadenabled) { for ( i = 0 ; i < 5 ; i++) data[i] = (unsigned char)(dot_low_table[(int)dotdata][i]); write(dot, data, 5); pthread_exit((void *)NULL); void lcd_putstring(char *str) { // TFT-LCD 스트링 디스플레이 함수 int b, x, y, X, Y, offset, len; unsigned char i; unsigned short *rasterbuff; len = strlen(str); rasterbuff = malloc(sizeof(short) * len * 8); if (!rasterbuff) { puts("not enough memory!! n"); exit(1); X = lcd_x * 8; Y = lcd_y * 16; for (y = 0; y < 16; y++) { offset = OFFSET(X, (Y + y)); for (x = 0; x < len; x++) { i = 128; for (b = 0; b < 8; b++) { i = i >> b; rasterbuff[x * 8 + b] = font[str[x] - 0x20][y] & i? lcd_textcolor : 0; lseek(fbfd, offset, SEEK_SET); write(fbfd, rasterbuff, len * 8 * 2); free(rasterbuff); lcd_y = lcd_y + (lcd_x + len) / 30; lcd_x = (lcd_x + len) % 30;

103 list.c 주요 소스코드 LIST *CreateList() { LIST *list; // List 생성 함수 list = (LIST *) malloc(sizeof(list)); if (!list) { puts("not enough memory!! n"); exit(1); list->start = NULL; list->itemcount = 0; return list; ListAddItem(LIST *list, void *item) { NODE *node, *current; // 생성된 리스트에 함수를 추가 if (!list) return 0; while(lock) Beep(); lock = 1; node = (NODE *) malloc(sizeof(node)); if (!node) { puts("not enough memory!! n"); exit(1); node->data = item; node->next = NULL; current = (NODE *) list; while(current->next) current = current->next; current->next = node; list->itemcount++; lock = 0; return 1; 산성비 한 개당 하나의 GenerateRaindrop() 함수를 수행하면서 생성되므로 여러 개의 산성비를 생성시키기 위해 리스트를 생성해서 관리할 수 있도록 구현하였다

104 void ListDeleteItem(LIST *list, int pos) { // 리스트에서 함수를 삭제 NODE *prev, *current; int c; if (!list!list->start) return; while(lock) Beep(); lock = 1; current = list->start; if (!pos) { list->start = current->next; free(current); list->itemcount--; lock = 0; return; else for (c = 0; c < pos; c++) { prev = current; current = current->next; if (!current) { lock = 0; return; prev->next = current->next; free(current); list->itemcount--; lock = 0; void *ListGetItem(LIST *list, int pos) { // 해당 산성비에 대한 레인드롭 정보를 가져옴 NODE *current; int i; if (!list!list->start) return NULL; while(lock) Beep(); lock = 1; current = list->start; for (i = 0; i < pos; i++) { current = current->next; if (!current) { lock = 0; return NULL; lock = 0; return current->data;

105 5. 수행 방법 및 결과 5.1 수행 방법 호스트 PC에서 CD에 있는 어플리케이션을 복사해 놓은 디렉토리로 이동한다. (320app/Application/Acid_Rain로 이동한다.) ]# cd /320app/Application/Acid_Rain make 명령어를 입력하여 어플리케이션을 컴파일 한다. ]# make 아래의 그림은 일련의 과정이다. 앞의 실습과 동일하게 zmodem을 이용하여 생성된 ssd' 실행파일을 타겟보드의'test_app' 디 렉토리에로 다운로드한다. 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./ssb 위에서 설명한 동작 방법대로 테스트를 해본다

106 5.2 수행 결과 시작 화면 게임 프로그램을 실행하면 전체 폼이 나타나고 5초 카운트다운 박스가 보인다. 게임 화면 카운트다운이 끝나면 Go! 메시지와 함께 4자리 숫자로 조합된 산성비가 나타나기 시작한다. 시간이 경과할수록 산성비는 점점 아래로 내려온다. 이것들이 바닥에 닿기 전에 키 버튼으로 입 력하여 맞추어야한다. 다음 단계 1단계를 클리어하게 되면 다음 2단계로 넘어가게 된다. 난이도가 높아질수록 산성비가 내려오는 속도는 점점 빨라지게 된다. (총 10단계로 구성) 아래 그림은 1단계를 클리어 했을 때 나타나는 화면이다

107 게임 종료 처음 게임을 시작할 때 주어지는 Life 수는 8개이다. 아래 그림은 Life 수를 모두 소진했을 때 게임종료가 된 화면이다

108 Chapter 4. DC 모터 제어 프로그램 1. 개요 이 장에서는 X-HYPER320 TKU의 IEB 보드에 부착되어 있는 두 개의 DC 모터 포트를 제어해보 는 실습시간을 같도록 하겠다. 2. 관련기술 2.1 DC 모터 IEB에 부탁된 DC 모터 포트는 L298 IC 칩을 통해 제어를 할 수 있다. A, B 두 개의 포트를 제어할 수 있으며, 한 포트를 제어하는데 3개의 핀이 필요하다. 아래는 IEB 보드의 DC 모터 구동회로 부분이다. L1 포트를 제어하기 위해서는 DCMOTOR1, 2, DCMOTORN_A 핀이 필요하며, R1 포트를 제어 하기 위해서는 DCMOTOR3, 4 DCMOTOR_B 핀이 필요하다. DCMOTOR1 ~ 4 핀은 각 모터의 방향을 정하는데 사용되며 DCMOTOR_A와 B는 각 모터의 ON/OFF 기능을 담당하는 핀이다. 일반적으로 DC 모터의 속도를 제어하기 위해 DCMOTOR_A와 B를 CPU의 PWM 출력을 연결하여 사용하는데 IEB 보드에서는 CS3번 어드레스의 데이터 버스 에 하위 6bit에 DCMOTOR1 ~ 4핀과 DCMOTOR_A, B가 순서대로 연결되어 있고 비트 제어로 구동시키기 때문에 고정된 속도로만 동작하게 된다. 3. S/W 설계 3.1 기능 본 프로그램의 기능은 다음과 같다. 전/후진 가능 두 개의 DC 모터를 동시에 제어하여 좌/우회전 가능 실제 데모 탱크와 같은 DC 모터를 응용한 하드웨어 제작 시 연결하여 제어하기가 쉽다

109 3.2 구성 DC Motor 제어를 위한 시스템 구성은 다음과 같다. 3.3 동작 방법 DC 모터 제어 프로그램은 다음과 같은 키 버튼 조작을 통해 제어를 할 수 있다. FORWARD : 전진 기능 BACKWARD : 후진 기능 RIGHT : 왼쪽 모터를 전진시키고 오른쪽 모터를 정지시켜 실제로 우회전이 가능하다. LEFT : 오른쪽 모터를 전진시키고 왼쪽 모터를 정지시켜 실제로 좌회전이 가능하다. STOP : 정지 기능

110 4. S/W 구현 dc_control.c의 주요 소스코드 #define DCMDEVICE #define LCDDEVICE #define KEYDEVICE "/dev/dc_motor" "/dev/clcd" "/dev/key" int dcm_fd, key_fd, lcd_fd; struct strcommand_variable { char rows; char nfonts; char display_enable; char cursor_enable; char nblink; char set_screen; char set_rightshit; char increase; char nshift; char pos; char command; char strlength; char buf[20]; ; 장치노드의 경로 및 FD변수와 CLCD 디바이스 제어에 사용되는 구조체를 선언하였다

111 while(pressed_value!= 0x0D) { // KEY로부터 입력을 받는다. pressed_value = key_getkey(); printf("input Key : %x n", pressed_value); switch (pressed_value) { case 0x02: // 직전버튼 dcmotor_value = 9; strcpy(clcd_buffer, "Go Forward"); break; case 0x05: // 좌회전버튼 dcmotor_value = 12; strcpy(clcd_buffer, "Turn Left"); break; case 0x06: // 정지버튼 dcmotor_value = 11; strcpy(clcd_buffer, "Stop"); break; case 0x07: // 우회전버튼 dcmotor_value = 13; strcpy(clcd_buffer, "Turn Right"); break; case 0x0A: // 후진버튼 dcmotor_value = 10; strcpy(clcd_buffer, "Go Backward"); break; case 0x0D: strcpy(clcd_buffer, "Program End"); break; default: strcpy(clcd_buffer, "Not Invalid Key"); break; 키 버튼 입력 값을 읽어서 해당되는 키 값에 대칭되는 기능을 수행하게 된다. 키 값은 DC 모터 제어를 위한 커맨드로서 고유의 dcmotor_value를 지정하게 된다

112 // 눌러진 키에 따른 명령을 모터로 전송. ioctl(dcm_fd, dcmotor_value, flag); // 눌려진 버튼의 정보를 CLCD에 출력한다. ioctl(lcd_fd, IOM_LCD_CLEAR, &strcommand, 32); ioctl(lcd_fd, IOM_LCD_DD_ADDRESS, &strcommand, 32); for(i = 0; i < 16; ++i) { if(clcd_buffer[i] == ' 0') break; memcpy(&strcommand.buf[0], &clcd_buffer[i], 1); ioctl(lcd_fd, IOM_LCD_WRITE_BYTE, &strcommand, 32); sleep(1); if(pressed_value == 0xd ) goto out; out: puts("exit Program..."); close(lcd_fd); close(key_fd); close(dcm_fd); return 0; dcmotor_value는 DC 모터 제어의 ioctl() 함수의 커맨드로 전달된다. DC 모터의 제어와 더불어 CLCD도 키 버튼 입력에 따른 제어 상태를 CLCD에 디스플레이 한다. 13번 키 버튼을 입력 받으면 while() 문을 탈출하게 되고 디바이스 클로즈와 함께 프로그램은 종 료된다

113 5. 수행 방법 5.1 수행 방법 호스트 PC에서 CD에 있는 어플리케이션을 복사해 놓은 디렉토리로 이동한다. (320app/Application/DC_Motor로 이동한다.) ]# cd /320app/Application/DC_Motor make 명령어를 입력하여 어플리케이션을 컴파일 한다. ]# make -- 어플리케이션 컴파일 아래의 그림은 일련의 과정이다 생성된 실행파일인 dc_control'을 minicom의 Zmodem을 이용하여 타겟보드로 다운로드한 다. 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./dc_control 위에서 설명한 동작 방법대로 테스트를 해본다

114 Chapter 5. CGI를 이용한 DC 모터 원격 제어 1. 개요 본 장에서는 이전 장에서 소개했던 IEB 상의 DC 모터 제어 프로그램을 좀 더 응용하여 원격으 로 제어할 수 있는 프로그램이다. 기능은 이전의 DC 모터 제어 프로그램과 동일하나 웹서버를 이용하여 원격으로 제어한다는 점에서 차이가 있다. 타겟보드 상에서 웹 서버를 포팅하는 방법 과, CGI 프로그래밍의 간단한 방법을 본 프로그램을 통해 익혀보도록 하자. 2. 관련기술 2.1 웹서버 인터넷 익스플로러 혹은 네스케이프 등의 웹브라우저를 이용하여 특정 사이트에 접속하였을 때 웹 페이지를 전송하는 프로그램과 호스트를 웹서버라고 한다. 웹 브라우저는 이러한 웹서버에 접속하여 웹 페이지를 읽어오는 클라이언트를 말한다. 이 그림과 같이 클라이언트가 HTTP를 사용해서 웹 서버에게 문서 파일을 요청하면, 웹 서버는 브라우저가 요청한 문서 파일을 찾아 브라우저에게 문서를 보내고 접속을 끊는다. 웹 브라우저 에서는 요청 헤더를 만들어서, 웹서버에 전달한다. 그러면 웹서버는 요청헤더를 분석해서 응답 헤더를 만든 다음 데이터를 웹 브라우저에게 HTTP 프로토콜을 이용하여 전송한다. 웹 서버의 문서는 HTML(Hypertext Mark-up Language)파일로 저장된다. HTML파일이란 문서 중간 필요한 곳에 미리 정의된 기호(tag)을 붙임으로써 문서의 형태를 규정하는 언어 규약에 의해 작성된 ASCII코드의 일반 텍스트 형식의 문서파일이다. 2.2 CGI(Common gateway interface) CGI란 무엇인가? HTML을 이용하여 텍스트 위주의 정보를 제공하던 인터넷 초기에는 일방적인 정보전달로 인한 웹서비스는 한계가 있었다. 정보를 제공하는 측에서는 웹사이트에 필요한 정보를 올려두면 그 정보를 원하는 측에서는 받아가거나 참조하는 단방향의 정보전달만을 했었기 때문에 서로으 l의 사교환이나 정보교환은 이루어지질 않았다

115 CGI(Common Gateway Interface)란 웹서버와 클라이언트간에 필요한 정보교환을 가능하게 해 주는 일종의 웹 인터페이스이며 다양한 종류의 웹 프로그래밍 언어로 구현된다. 즉 CGI란 어떤 특정한 프로그램 언어를 지칭하는 것이 아니라 일종의 통신표준이라고 할 수 있다. 즉, 응용 프 로그램에서 실행된 결과를 웹에 전달하는 등의 작업을 하기 위해서는 미리 정해진 일정의 약속 이나 표준화된 전달 방법이 필요한데, 이러한 전달방법을 우리는 통상 CGI로 일컫는다. CGI를 이용하게 됨으로써 정보를 제공하는 웹 서버 측 에서는 웹 서버이용자들의 동향이나 의사 및 요 구사항들을 수렴하여 일방적이 아닌 양방향의 정보교환이 가능하게 된다. 즉, CGI는 웹 브라우저와 웹 서버 그리고, 응용 프로그램간의 정보전달의 매체다. 쉽게 말해서 사용자의 브라우저를 통해서 입력된 데이터를 어떻게 서버로 보내고 서버에서 가공된 데이터를 어떻게 웹브라우저로 보낼 것인가 하는 방법을 일컫는다. (1) 웹서버와 클라이언트 사이의 통신 사용자 입장에서 보면 웹은 단순히 멀티미디어 문서를 보여주는 역할을 수행한다. 사용자는 웹 브라우저를 통해서 보고자 하는 정보가 있는 웹 서버에 접속해서 정보를 가져오게 되며, 이렇게 웹 브라우저와 서버간에 정보를 주고받기 위한 특별한 약속이 필요하게 되는데, 이러한 약속을 프로토콜(Protocol)이라고 한다. 웹에서 사용하는 프로토콜은 HTTP(Hyper Text Transmission Protocol)이다. 클라이언트에 해당 하는 웹브라우저(ex, 익스플로러, 넷스케이프)는 서버에 HTML 문서를 전송해 줄 것을 요구 (Request)하고 서버는 클라이언트의 요청에 따라 해당 문서를 클라이언트에게 전송(Response) 한 후 접속을 중단함으로 서버와 클라이언트간에 통신이 이루어지게 된다. 이와 같이 클라이언 트의 요청이 있을 때만 서버에 접속해서 정보를 받아오는 되는 HTTP 프로토콜의 특징 때문에 클라이언트가 서버에 항상 접속되어 있을 때와는 달리 서버의 부담을 줄여주게 된다. 이러한 HTTP 프로토콜은 이미지, 실행 프로그램, HTML 문서 등 다양한 형태의 정보 전송이 가능하다. 이때, 클라이언트가 해당 서버를 찾아갈 수 있도록 하는 것이 URL(Uniform Resource Locator)

116 이다. URL은 웹 브라우저가 찾아갈 서버의 주소(목적지)를 알려주는 인터넷의 주소 체계이다. 그렇다면 웹 브라우저가 HTTP를 이용하여 서버에 접속하게 되는 경로를 간단히 알아보자. 1. 웹브라우저가 URL을 해석하여 서버를 찾는다. 2. 웹브라우저는 DATA를 서버에 전달한다. 3. 서버는 URL을 경로와 파일 이름으로 해석한다. 4. 서버는 해당 문서를 브라우저에 전송한다. 5. 서버와 클라이언트의 연결이 끊긴다. 6. 서버로부터 전송된 데이터를 브라우저를 통해서 보여준다. 이와 같이 서버는 클라이언트가 요구한 한 문서만 전해 주고 접속을 끊는 것을 무상태 연결 (stateless connection)이라고 한다. 웹을 단순한 정보 전달 및 검색 업무에 벗어나서 실제 자신에게 필요한 것으로 만들기 위해서는 클라이언트에서 입력한 데이터를 서버에서 처리 할 수 있어야 하며, 이러한 처리된 데이터를 다 시 자신의 컴퓨터로 가지고 올 수 있어야 하는데, 이런 작업을 가능하게 해주는 방법이 CGI(Common Gateway Interface)이다. (2) CGI의 작동원리 CGI는 서버와 응용 프로그램을 연결시켜주는 "표준"을 의미한다. 웹에서 FORM을 통해서 입력된 자료를 응용프로그램의 입력으로 전달하며, 응용 프로그램에서 실행된 결과를 웹에 전달하는 등 의 작업을 하기 위해서는 미리 정해진 일정의 약속이나 표준화된 전달 방법이 필요한데, 이러한 전달방법을 우리는 통상 CGI로 일컫는다. 클라이언트의 요청 클라이언트는 자신에게 필요한 정보를 서버에 요청하게 된다. 클라이언트가 요청하지 않으며 CGI 프로그램이 서버에서 실행될 필요가 없다. 서버가 클라이언트의 요청을 분석 HTTP(웹서버)는 입력된 요청을 분석하고 다음에 실행할 작업을 결정하게 된다. HTTP요청에 대 해 서버는 요청된 파일을 찾는다. 파일의 유형에 따라 서버는 파일에 대한 작업을 결정하게 된 다. 만일 서버가 파일의 유형을 알지 못하면 텍스트 형태로 클라이언트에 그 내용을 표시한다. 일반적으로 HTML 문서가 클라이언트에 전달된다. 클라이언트에 설치된 웹 브라우저가 HTML 문 서의 태그들을 해독해서 보여주게 된다. 만일 사용자가 요청한 내용이 HTML 이 아닌, 실행 가능한 프로그램(CGI 프로그램)이면 서버는 그 프로그램을 실행시키고 결과값을 웹 브라우저로 보내준다. 서버에서 클라이언트로 정보를 전달 서버에서 실행된 결과는 클라이언트로 보내지게 되는데, 보내줄 결과가 없을 때에는 보내줄 결

117 과가 없다는 사실을 알리는 데이터를 클라이언트로 보내주게 된다. 만일, 클라이언트로 보낼 데 이터가 있는 경우에는 응용 프로그램은 먼저 서버가 인식할 수 있는 헤더를 붙이고, 그 다음으 로 출력 데이터를 덧붙인다. 접속종료 일단, 클라이언트가 모든 에디터를 받게 되면, HTTP 연결은 종료된다. 2.3 CGI 프로그래밍 클라이언트 PC의 브라우저에서 서버로 정보를 전달하는 방법을 정의하는 인터페이스 규격을 CGI(Common Gateway Interface)라고 한다. 브라우저에서 이런 정보를 받아들이는 프로그램을 CGI프로그램이라고 한다. 이것은 정보를 처리하고 나서 다시 브라우저 명령이나 동적인 문서를 전달하기 위해 HTTP 프로토콜을 사용한다. CGI를 구현하기 위해서는 보통 웹 브라우저 쪽에서 form 태그를 통해 사용자의 입력 값들을 웹 서버로 보내고, 서버에서는 해당 값을 CGI 프로그램에게 넘겨주게 된다. 입력 값 전달 방식 웹에서 사용자의 입력 값들을 넘겨주기 위해서는 <form>태그를 사용한다. 많이 사용한 <form> 태그 구성은 다음과 같다. <form action= cgi-bin/led.cgi method=get> <p align= center > <input type= text name= value Maxlenth= 3 size= 3 > <input type= submit name= button value= input ></p></form> <form> 태그의 중요한 속성 중의 하나는 action속성이며, 이것은 폼을 처리하기 위해 호출하는 프로그램의 URL을 지정한다. 이런 프로그램은 대개 일반적인 페이지와 독립적인 HTTP 서버의 디렉터리에 저장되며, 디렉터리는 거의 cgi-bin이라는 이름을 가진다. 즉, 안에 들어갈 프로그램 들은 CGI 프로그램들이고 이것을 이용하여 타겟보드 시스템을 제어할 수 있다. method 속성은 post방식과 get방식이 존재하며, 각각의 방식에 따라 데이터를 전달하는 방법의 차이가 있다. get method <form>태그에 method=get으로 하거나 생략하면 사용자의 입력 값들이 환경변수에 저장되어 넘 겨진다. 즉 각 입력 값들이 기본 URL에 붙은 인수로서 첨가되어 CGI프로그램으로 값을 넘겨주 게 된다. get method를 이용하면 그 입력 값들이 환경변수의 하나인 QUERY_ STRING에 들어 가서 전달되는데 CGI프로그램은 그 QUERY_STRING에 들어 있는 값을 읽는다. 이때 그 값들은 입력된 그대로 넘어가는 것이 아니라 서버에 의해 여러 가지로 변환되어(encoding) 넘어가며 CGI프로그램에서는 값을 getenv()로 읽어 들여 해독(decoding)해야 한다. post method <form> 태그에서 method=post로 하면, get mathod가 환경 변수 중이 하나인 QUERY_STRIING

118 을 통해 전달되는 것이 아니라 stdin(standard input: 표준입력)을 통해서 전달된다. get method 가 인수를 통해서 전달되므로 커맨드라인의 길이에 의한 제한을 받는 반면에 post method에서 는 환경 변수들 또한 stdin과 함께 전달된다. 그리고 post방식과 마찬가지로 입력 값들이 인코딩 되어 넘어옴으로써 CGI에서도 그 값들을 디코딩해야 한다. 다음으로는 form요소 안에서 폼과 같이 사용할 수 있는 태그에 관하여 간략히 알아보자. <input> <input>태그는 입력 형태를 정의한다. 입력의 외형과 동작은 TYPE속성을 통해 제어된다. <select> <select>태그는 사용자가 목록에서 원하는 것을 선택하게 해준다. 이것은 NAME, MULTIPLE, SIZE라는 속성을 가진다. <textarea> <textarea>태그는 여러 줄을 입력하고 서버로 반환하게 해준다. CGI 프로그래밍 CGI 프로그램을 작성하기 위해 사용할 수 있는 언어에는 제한이 없다. 쉘 스크립터, TCL, Perl 등을 이용하여 CGI 프로그램을 작성할 수 있다. 그러나 이 실습에서는 가장 많이 사용하고 있는 C언어를 이용하여 CGI 프로그래밍을 해보자. CGI 프로그램은 출력할 데이터 앞서 적절한 헤더 정보를 보내 웹 서버가 어떤 타입을 출력하는 지 인식하게 한다. 이렇게 해야 웹서버에서 그 헤더를 보고 사용자의 웹브라우저로 데이터를 보 낼 수 있다. 다음에 나오는 문장은 웹서버에게 어떤 타입을 출력하려고 하는지 알 수 있게 한다. printf( Content-type:text/html n n ); C 프로그램에 앞의 내용을 적고 컴파일 하면, CGI 프로그램이 된다. 다음은 아주 간단한 CGI 프로그램의 예이다. #include<stdio.h> void main() { printf( Content-type: text/html n n ); printf( <html> n<head><title>the First CGI program</title> </head> n ); printf( <body> n<center> It is a CGI program test</center> n <body> n</html> ); 앞의 프로그램의 컴파일 방법은 다음과 같다. ]#arm-linux-gcc -o first.cgi first.c 이와 같이하여 에러 없이 컴파일 되면 first.cgi를 타깃보드의 web/cgi-bin 폴더로 다운로드한

119 후, 웹브라우저에서 주소창에서 입력하면, CGI 프로 그램이 동작된다. CGI 프로그램은 이렇게 단순하게 글자를 표시하는 것이 아니라 웹 브라우저의 인자 값을 받아 이것을 처리해서 다시 웹브라우저로 리턴해주는 일을 하기 때문에 대부분의 홈페이지에서 게시 판이나 데이터베이스 프로그램으로 많이 사용되고 있다. 그러나 임베디드 시스템에서는 웹서버를 포팅하여 웹 브라우저를 통해 타깃보드의 I/O를 제어할 수 있는 프로그램을 작성할 수 있다. 이 번 실습에서는 임베디드 시스템 개발이 완료된 후 네트워크 및 각종 디바이스 드라이버를 이용 한 사용자 응용계층에서의 웹 서버와 접속 방법을 이해하고, 포팅된 웹서버에 홈페이지를 생성 하여 웹브라우저를 통해 접속함으로서 웹서버의 기능 및 HTTP와 HTML을 이해한다. 타겟보드에 웹서버를 포팅하게 되면 웹서비스가 가능해진다. 많은 임베디드 웹서버가 있지만, 여 기서는 웹서버로 GoAhead를 사용하도록 한다. 소스는 무료로 다 운로드 받을 수 있다. GoAhead는 임베디드 시스템용으로 디자인되고 있는 모듈이 작고, 적은 양의 RAM으로도 운용이 가능하며, 다양한 기능들을 지원하고 있다. 3. S/W 설계 3.1 기능 본 프로그램은 웹상에서 CGI 프로그램을 통해 다음과 같은 원격으로 제어를 할 수 있다. 전/후진 가능 두 개의 DC 모터를 동시에 제어하여 좌/우회전 가능 실제 데모 탱크와 같은 DC 모터를 응용한 하드웨어 제작 시 연결하여 제어하기가 쉽다. 3.2 구성 DC 모터 원격 제어를 위한 시스템 구성은 다음과 같다. X-HYPER320 TKU 보드가 서버가 되고, 사용자 PC가 클라이언트로 구성된다. 사용자 PC에서 네트워크를 통해 서버로 원격 접속을 하여 DC 모터를 제어할 수 있다

120 3.3 동작 방법 웹브라우저 상에 보이는 다음과 같은 이미지 버튼을 조작하여 DC 모터를 제어를 할 수 있다. FORWARD : 전진 기능 BACKWARD : 후진 기능 LEFT : 왼쪽 모터를 전진시키고 오른쪽 모터를 정지시켜 실제로 좌회전이 가능하다. RIGHT : 오른쪽 모터를 전진시키고 왼쪽 모터를 정지시켜 실제로 우회전이 가능하다. STOP : 정지 기능 4. S/W 구현 4.1 웹서버 포팅 CGI 프로그램을 웹브라우저 상에서 제어하기 위해서는 타겟보드에 웹 서버 데몬이 실행되어야한 다. 여기서는 많이 알려져 있는 GoAhead WebServer를 타겟보드에 포팅할 것이다. GoAhead 다운로드 설치를 하기 위해서는 GoAhead 소스가 필요하다. 다운로드 경로는 아래를 참조한다. 다운로드 파일명은 webs218.tar.gz이며, 제공된 CD내에 Application/CGI DC Motor/ 디렉토리 안에 다운로드 된 파일이 있으니 참고하기 바란다

121 GoAhead 포팅 다운로드한 압축파일을 작업 디렉토리에 압축해제 한다. 그리고 별도의 Configuration 파일이 없 기 때문에 직접 Makefile을 아래와 같이 수정해야 한다. ]# tar zxvf webs218.tar.gz -- 압축풀기 ]# cd ws031202/linux -- ws031202/linux 디렉토리로 이동 ]# vi Makefile -- Makefile 편집 다음과 같이 두 개의 구문을 삽입한다. 컴파일러를 ARM 크로스컴파일러로 지정해준 것이다. all: compile CC = /usr/local/arm-linux-4.1.1/bin/arm-linux-gcc AR = /usr/local/arm-linux-4.1.1/bin/arm-linux-ar ARCH = libwebs.a NAME = webs # User Management switch UMSW = -DUSER_MANAGEMENT_SUPPORT # Digest Access switch DASW = -DDIGEST_ACCESS_SUPPORT ~ 중략 ~ # Transition rules (add -o to put object in right directory) #.c.o: $(CC) -c -o $@ $(DEBUG) $(CFLAGS) $(IFLAGS) $< 수정을 완료하였으면 컴파일을 해보자. ]# make 컴파일이 성공하면 webs라는 실행파일이 생성된다. 생성된 webs 파일을 상위 디렉토리에서 web 디렉토리 안에 복사한다. web 디렉토리에는 테스트용 웹페이지가 들어있다. 아래와 같이 입력하고 web 디렉토리로 이동하여

122 복사된webs파일을 확인한다. ]# cp web../web --상위 디렉토리로 이동 하여 web디렉토리에 복사 ]# cd../web -- web디렉토리로 이동 ]# ls webs파일이 정상적으로 복사가 된 것을 확인하였으면 압축을 하여 타겟보드의 최상위로 복사를 하고 압축을 풀어야 한다. 아래와 같이 호스트 PC에서 web을 압축한다. ]# cd.. --상위 디렉토리로 이동 ]# tar zcvf web.tgz web -- web디렉토리를 web.tgz으로 압축 ]# ls 다음으로는 타겟보드에서 해당 파일을 다운로드 한다. 다운로드는 zmodem 을 이용하여 받도록 하자. 320TKU]# cd / --타겟보드의 최상위 경로로 이동 320TKU]# Cntr +A' => 'Z' => 엔터 -- Zmodem 실행 타겟보드에 파일을 받았으면 압축을 해제한다. 최상위 디렉토리에 web이란 디렉토리가 생성이 될것이다. web 디렉토리로 이동하여 파일을 확인한다. 320TKU]# tar zxvf web.tgz 320TKU]# cd web 320TKU]# ls -- 압축풀기 -- web디렉토리로 이동 -- web디렉토리로 이동 이제 타겟보드에 웹페이지에 사용될 파일이 준비가 되었다. 다음으로는 타겟보드를 웹서버로 만 들기 위한 설정을 할 차례이다. 타겟보드의 네트워크 설정을 확인하고 이에 알맞게 셋팅을 한다. 우리가 사용할 어댑터는 보드에 Ethernet1 으로 마킹된 포트이며 이 포트는 타겟보드에서 eth0 를 사용한다. 먼저 네트워크 어댑터를 확인하여 eth1(즉 보드에 Ethernet2로 마킹된 포트)는 사 용하지 않도록 설정한다. 320TKU]# ifconfi 320TKU]# ifconfig eth1 down 320TKU]# ifconfig -- 네트워크 어댑터 확인 -- eth1사용안함 -- 네트워크 어댑터 확인

123 웹서버는 호스트 PC와 연결하여 테스트 할 것이므로 가상 IP주소를 설정한다. 위 그림에서는 eth0의 IP는 임을 확인할 수 있다. 만약 다른 IP를 사용할 때는 ifocnfig 명령어 로 IP를 재설정 하도록 한다. IP설정을 마쳤으면 다음은 타겟보드에서 사용할 IP를 호스트로 설 정해 주어야 한다. 다음과 같이 /etc/hosts파일을 수정한다. 320TKU]# cd /etc 320TKU]# vi hosts --타겟보드의 /etc 디렉토리로 이동 -- hosts 파일 편집 # Do not remove th following line, or various programs # that require network functionallity will fall localhost. localdomain localhost WENDERS 위의 박스에서 보듯이 아래 한 줄을 추가한 후 저장한다. IP는 앞에서 확인한 자신의 eth0의 IP 를 적으면 되고 뒤에 WENDERS'는 호스트 이름을 적는다. 각각 다를 수 있으므로 각자 자신의 호스트 이름을 적도록한다. 확인한는 방법은 타겟보드의 쉘프롬프트 앞을 보면 된다. 위에 캡쳐 한 그림을 보면 [root@wenders]# 라고 나오는 것을 볼 수 있다 이때 WENDERS 가 호스트 이름이 된다. 다음으로 호스트 PC와 타겟보드를 LAN으로 연결하고 ping 테스트를 하여 통신상태를 확인한다. 이에 앞서 호스트 PC의 IP를 타겟보드의 가상 IP대역과 맞춘다. ]# ifconfig eth 호스트 PC와 타겟보드의 IP대역 맞춤 ]# ping 타겟보드와 의 통신 확인

124 통신이 정상적으로 이루어지면 다음엔 타겟보드에서 /web 디렉토리로 이동하여 webs 를 다음 과 같이 실행한다. 웹 서버 데몬이 실행되는지 확인을 해보자. 프로그램을 백그라운드로 실행시킨다. 320TKU]# cd /web 320TKU]# webs & --타겟보드의 /usr/bin 디렉토리로 이동 -- webs 백그라운드로 실행 다음과 같이 프로세스 목록에 추가되어 있는지 확인을 한다. 320TKU]# ps aux 만약 프로세스가 동작하지 안는다면 다음과 같이 호스트 네임을 직접 입력하여 준다음 다시 위 의 방법대로 프로세스를 확인한다. 320TKU]# hostname WENDERS

125 확인이 되었으면 호스트 PC에서 웹브라우져를 이용해 접속을 시도한다. 웹브라우져의 주소창에 타겟보드에서 설정한 IP를 입력하면 다음과 같은 웹페이지가 뜨는것을 확인 할 수 있다. 웹페이 지가 열였으면 일단 웹서버의 구축은 완료 되었다. 다음은 서버를 이용하여 모터를 제어하는 방 법에 대해 설명한다

126 4. 소스 코드 main.c의 주요 코드 int main() { printf("content-type: text/html n n"); printf("<html> n" "<HEAD><TITLE> DC Motor Tank CGI Control</TITLE></HEAD> n"); printf("<body> n"); printf("</body> n"); printf("</html> n"); tankctl(0); return 0; 프로그램의 제일 처음 진입하는 부분이다. 간단하게 타이틀만 표기해 주고 tankctl() 함수로 분기하게 된다. tankctl.c의 주요 코드 #define DC_MOTOR_ADDR 0x // 물리 어드레스 #define FORWARD 1 #define REVERSE 0 #define DC_MOTOR_SETBIT(x) #define DC_MOTOR_CLEARBIT(x) {motor_port = (1<<x); *vdc = motor_port; {motor_port &= ~(1<<x); *vdc = motor_port; int dcm_fd; volatile unsigned char motor_port; unsigned short *vdc; 물리 어드레스가 0x 이다. 웹상에서 장치들을 제어하기 위해서는 가상 메모리로 접근을 해야 한다. 이것을 위해 가상 메모리로 맵핑될 vdc라는 16비트 포인터를 선언하였다

127 int tankctl(char dcmotor_value) { if ((dcm_fd = open("/dev/mem", O_RDWR O_SYNC)) < 0) { printf("memory opening failed! n"); return -1; // 메모리 오픈 // 가상 메모리 매핑 (물리 어드레스 -> 가상 어드레스) vdc = mmap(null, 4, PROT_WRITE, MAP_SHARED, dcm_fd, DC_MOTOR_ADDR); if((int)vdc < 0) { vdc = NULL; close(dcm_fd); printf("memory mapping failed! n"); return -1; // CGI 메인 폼 printf("<html> n" "<HEAD><TITLE> DC Motor Tank CGI Control</TITLE></HEAD> n"); printf("<body><h2><p ALIGN=CENTER>This is a CGI IEB DC Motor Control Program!</p></H2> n"); printf("<br></br> n"); printf("<hr></hr> n"); printf("<table border= "0 " width= "300 " height= "200 " cellspacing= "5 " align= "center "> n"); // 웹 테이블 설정 printf("<tr><td></td><td> n"); printf("<form action = "../cgi-bin/forward.cgi " method=get> n"); printf("<center><input type= "submit " name= "forward " value= "FORWARD " style='width:100px' /></center></form></td></tr> n"); // FORWARD 버튼 생성 printf("<tr><td> n"); printf("<form action = "../cgi-bin/left.cgi " method=get> n"); printf("<center><input type= "submit " name= "left " value= "LEFT " style='width:100px' /></center></form></td> n"); // LEFT 버튼 생성 printf("<td> n"); printf("<form action = "../cgi-bin/stop.cgi " method=get> n"); printf("<center><input type= "submit " name= "stop " value= "STOP " style='width:100px' /></center></form></td> n"); // STOP 버튼 생성 printf("<td> n"); printf("<form action = "../cgi-bin/right.cgi " method=get> n"); printf("<center><input type= "submit " name= "right " value= "RIGHT " style='width:100px' /></center></form></td></tr> n"); // RIGHT 버튼 생성 printf("<tr><td></td><td> n"); printf("<form action = "../cgi-bin/backward.cgi " method=get> n"); printf("<center><input type= "submit " name= "stop " value= "BACKWARD " style='width:100px' /></center></form></td></tr> n"); // BACKWARD 버튼 생성 웹상에 생성된 기능 버튼을 클릭하게 되면 해당 /web/cgi-bin의 CGI 파일로 연결된다

128 switch (dcmotor_value) { case 0: // Init dc_motor_init(); break; case 1: // FORWARD dc_motor_right(forward); dc_motor_left(forward); break; case 2: // LEFT dc_motor_left(forward); dc_motor_stop(0x01); break; case 3: // STOP & CLOSE dc_motor_stop(0x02); munmap(vdc, 1); close(dcm_fd); break; case 4: // RIGHT dc_motor_right(forward); dc_motor_stop(0x00); break; case 5: // BACKWARD dc_motor_right(reverse); dc_motor_left(reverse); break; default: break; printf("</table> n"); printf("</body> n"); printf("</html> n"); return 0; 해당 버튼을 클릭했을 때 고유의 키 값을 전달 받게 된다. 그 키 값은 dcmotor_value이고 DC 모터를 제어하기위한 명령어라고 할 수 있다. 전체적인 구조를 보면 재귀적 방식으로 구동된다는 것을 알 수 있다

129 void dc_motor_init(void) { // Left DC Motor Init DC_MOTOR_SETBIT(0); DC_MOTOR_SETBIT(1); // DC 모터 초기화 // Right DC Motor Init DC_MOTOR_SETBIT(2); DC_MOTOR_SETBIT(3); // Left DC Motor Enable DC_MOTOR_SETBIT(4); // Right DC Motor Enable DC_MOTOR_SETBIT(5); void dc_motor_stop(unsigned char cmd) // DC 모터 정지 { switch (cmd){ case 0x00: // Left Motor Stop DC_MOTOR_CLEARBIT(0); DC_MOTOR_CLEARBIT(1); DC_MOTOR_CLEARBIT(4); break; case 0x01: // Right Motor Stop DC_MOTOR_CLEARBIT(3); DC_MOTOR_CLEARBIT(2); DC_MOTOR_CLEARBIT(5); break; case 0x02: // All Motor Stop DC_MOTOR_CLEARBIT(0); DC_MOTOR_CLEARBIT(1); DC_MOTOR_CLEARBIT(4); DC_MOTOR_CLEARBIT(3); DC_MOTOR_CLEARBIT(2); DC_MOTOR_CLEARBIT(5); break; DC 모터는 5개의 Pin으로 연결되어 있는데 각 Pin들을 Set/Clear로 설정하여 총 5bit의 명령어 를 DC 모터로 전송하여 제어한다

130 void dc_motor_left(int dir) { if(dir == 1) // Forward { DC_MOTOR_CLEARBIT(1); DC_MOTOR_SETBIT(0); DC_MOTOR_SETBIT(4); else // Reverse { DC_MOTOR_SETBIT(1); DC_MOTOR_CLEARBIT(0); DC_MOTOR_SETBIT(4); // 왼쪽 DC 모터를 전/후진 제어 void dc_motor_right(int dir) { if(dir == 1) // Forward { DC_MOTOR_CLEARBIT(3); DC_MOTOR_SETBIT(2); DC_MOTOR_SETBIT(5); else // Reverse { DC_MOTOR_SETBIT(3); DC_MOTOR_CLEARBIT(2); DC_MOTOR_SETBIT(5); // 오른쪽 DC 모터를 전/후진 제어

131 5. 수행 방법 및 결과 5.1 수행 방법 기본적인 방법은 앞서 웹서버를 구동시킨것과 동일하다. 여기에 모터를 제어하기 위한 파일을 추가하여 실행하면 된다. /320app/Application/CGI_DC_Motor/ 디렉토리로 이동하여 컴파일한다. ]# cd /320app/Application/CGI_DC_Motor/ ]# make 생성된 실행파일을 /ws031202/web/cgi-bin 디렉토리에 복사한다. ]# cp *.cgi../ws031202/web/cgi-bin -- /ws031202/web/cgi-bin 에 파일복사 ]# cd../ws031202/web/cgi-bin -- 복사한 디렉토리로 이동 ]# ls -- 파일확인 파일 확인이 되었으면 아래와 같이 호스트 PC에서 web을 압축한다. ]# cd.. --상위 디렉토리로 이동 ]# tar zcvf web.tgz web -- web디렉토리를 web.tgz으로 압축 ]# ls 다음으로는 타겟보드에서 해당 파일을 다운로드 한다. 다운로드는 zmodem 을 이용하여 받고, 기존의 web.tgz 파일과 web 폴더는 삭제한다.. 320TKU]# cd / --타겟보드의 최상위 경로로 이동 320TKU]# Cntr +A' => 'Z' => 엔터 -- Zmodem 실행 타겟보드에 파일을 받았으면 압축을 해제한다. 최상위 디렉토리에 web이란 디렉토리가 생성이 될것이다. web 디렉토리로 이동하여 파일을 확인한다. 320TKU]# tar zxvf web.tgz 320TKU]# cd web 320TKU]# ls -- 압축풀기 -- web디렉토리로 이동 -- web디렉토리로 이동 이제 타겟보드에 모터를 제어 할 웹페이지가 추가 되었다. 웹서버 설정은 앞에서 수행 하였으므로 별도로 설정하지 않는다. 다음으로 호스트 PC와 타겟보드를 LAN으로 연결하고 ping 테스트를 하여 통신상태를 확인한다. 이에 앞서 호스트 PC의 IP를 타겟보드의 가상 IP대역과 맞춘다. ]# ifconfig eth 호스트 PC와 타겟보드의 IP대역 맞춤 ]# ping 타겟보드와 의 통신 확인

132 통신이 정상적으로 이루어지면 다음엔 타겟보드에서 'ps' 명령어를 이용해 webs프로세스가 동작 중인지 확인한다. 만약 동작하지 않는다면 /web 디렉토리로 이동하여 webs 를 다음과 같이 실 행한다. 웹 서버 데몬이 실행되는지 확인을 해보자. 프로그램을 백그라운드로 실행시킨다. 320TKU]# cd /web 320TKU]# webs & --타겟보드의 /usr/bin 디렉토리로 이동 -- webs 백그라운드로 실행 다음과 같이 프로세스 목록에 추가되어 있는지 확인을 한다. 320TKU]# ps aux 타겟보드에서의 설정이 모두 완료되었으면 이제 호스트 PC에서 웹 서버로 접속을 시도해본 다. 웹브라우저의 주소창에 다음과 같은 형식으로 입력한다

133 5.2 수행 결과 웹브라우저에서 타겟보드의 IP로 접근을 하면 아래와 같이 작성했던 CGI 프로그램의 메인 화면 을 볼 수 있다. IEB 보드의 DC 모터 포트에 실제로 DC 모터를 연결하고 메인화면에서 보이는 각각의 버튼을 클릭하면 DC 모터가 동작함을 확인할 수 있다

134 Chapter 6. Hmote2420 연동 시리얼 모니터링 프로그램 1. 개요 본 장에서는 USN과 연동하는 응용 예를 하나 소개하고자한다. 자사의 Hmote2420 모트와 X-HYPER320 TKU를 연결하여 Hmote2420이 다른 모트로부터 수신 되는 RF 데이터를 시리얼로 전송하여 모니터링 하는 콘솔 프로그램인데, 이 프로그램을 테스트 하기 위해서는 사전에 호스트 PC에 Cygwin과 TinyOS-1.x, 하이버스 센서 패치가 이루어 져야 한다. 그리고 Hmote2420 모트 2개도 준비해야 한다. 2. 관련기술 2.1 TinyOS TinyOS는 센서 네트워크와 같은 임베디드 네트워크 시스템들을 위해 특별히 고안된 아주 간단한 OS 이다. 이는 event 기반의 애플리케이션, 소형의 코어 OS(400 바이트 정도의 코드), 작은 데이터 메모 리를 갖는 초소형 용량의 OS를 만들기 위해 고안되었다. TinyOS는 재사용이 가능한 컴포넌트 기반 의 구조이다. 즉, 애플리케이션들이 구현에 필요한 각각의 컴포넌트들을 Wiring으로 연결한다. 이와 같이 컴포넌트 기반으로 이루어진 구조에서는, 다른 OS 서비스들로 구분된 컴포넌트들을 다른 애플 리케이션에서 반복적으로 사용하지 않아도 되는 장점을 갖는다. 그리고 센서 네트워크 노드들은 무 선 통신 데이터들을 실시간으로 처리해야 하기 때문에 동시성이 지원되어야 하는데, TinyOS는 event 기반의 동시성을 확보하기 위해 task와 event 개념을 사용한다. 이 두 가지 요소들의 차이는 " 선점"에 대한 가능 여부이다. 즉, task들은 서로를 선점하지 않는 반면, event들은 task나 event의 실 행에 대한 선점이 가능한 차이점이 있다. TinyOS는 일반적인 컴퓨터 운영체제와 달리 운영체제와 어플리케이션이 분리되어 설치되지 않는 다. 아래 그림에서 보는 바와 같이 운영체제 부분과 응용 애플리케이션 부분이 함께 컴파일 되어 하 드웨어 플랫폼에 다운로드 된다. 그림에서 Application 부분을 사용자가 직접 만들게 되며, 나머지 부 분은 기존 라이브러리를 재사용할 수 있다. Main 컴포넌트는 플랫폼의 초기화, 사용되는 모듈의 기능 호출, task 스케줄러의 실행을 담당한다. 기능의 실행은 Configuration에 있는 컴포넌트들의 실제 구현 부분에서 확인할 수 있다. M ain(scheduler) A p p lic a tio n A c t u a t in g S e n s in g C o m m u n ic a t io n H a rd w a re A b s tra c tio n s [ TinyOS 어플리케이션 구조] TinyOS에서 센서 노드를 동작시키는 것은 하드웨어 event와 task로 볼 수 있다. 하드웨어 event

135 는 인터럽트를 의미하며, 이런 인터럽트는 타이머, 센서, 통신 디바이스로부터 발생된다. task들 은 일정 시간의 지연을 갖는 프로시저 호출을 의미하고, 하드웨어 event 또는 다른 task를 호출 할 수 있다. task는 큐에 등록된 후 실행되는데, task들이 처리되는 동안에도 하드웨어 인터럽트가 실행될 수 있으며 높은 우선순위를 갖는다. task 큐에 실행되어야 할 task가 존재하지 않을 경우, 시 스템은 새로운 하드웨어 인터럽트가 발생될 때까지 슬립 모드로 전환된다. task 큐를 운영하는 방법 은 task 호출되면 task 큐에 해당 task를 등록하고 task가 실행 될 때 큐에서 해당 task를 삭제한다. task 실행 후 task 큐에 더 이상 실행할 task가 남아 있지 않으면 바로 슬립 모드로 전환된다. 1) TinyOS의 구조 TinyOS의 대략적인 구조는 다음과 같다. 전통적인 OS의 구조에서 큰 규모의 임베디드 시스템의 문제점은 다음과 같다. 대용량 메모리와 저장장치를 요구 우리가 필요한 용량의 불필요한 하고 과분한 기능 (어드레스 공간의 분리, 복잡한 I/O서브 시스템 등) 상대적으로 과분한 시스템(Context Switch 등) 복잡하고 전력소모가 많은 하드웨어 제공을 요구 등이다. 센서 네트워크에서 요구하는 OS(운영체제) 구조는 다음과 같다. 극히 적은 공간 극히 적은 비용의 시스템 극히 적은 전력소모 2) TinyOS의 설계 개념 저 전력 및 Ad-Hoc 센서 네트워크 : 센서 입력에 감응하기 쉬고 Event 중심이고 크기를 할 수 있다. 주요 요소는 센싱, 검출, 네트워킹/통신, 전력 관리 등이다. 한정된 리소스(resource) : 모든 것을 작게 만든다. 즉, 저 전력, 작은 메모리,제한된 싱 등이다. 기술변화에 적응한다(모듈방식과 Reuse). 조정 프로세 3) TinyOS 구현(적은 용량/최대 효과) 전략: 전력소모 최소, 전원 극대화 "Hurry up & Sleep"화 추진, 즉 동작이 신속하고 비동작시 대기모드 상태 프로세스를 신속하게 처리한다

136 (인터럽트 구동방식, polling 방식 배제하고 함수호출 대신 인라인 코드사용과 매크로방식을 채택 한다.) Sleep 모드사용 : 어떤 동작이 발생하였을 때 Sleep 모드 화 한다. (uw 전력소모) 2.2 Hmote2420 Mote는 저 전력 단거리 무선통신을 지향하는 8비트 마이크로 컨트롤러와 RF칩을 기반으로 구성되어 있다. 본 장에서 사용되는 Hmote는 Telos 플랫폼을 채택하여 적용하였고 TI사의 MSP430 CPU와 CC2420 RF칩을 기반으로 구성되어 있다. 다음은 Hmote에 대한 H/W 스펙이다. TI사의 MSP430 Microprocessor Chipcon의 CC2420 RF Transceiver 512 kb EEPROM Power management Embedded system과 연동 다음은 Hmote에 적용되는 Telos 플랫폼의 구성 및 개요에 대한 설명이다. 이는 IEEE Zigbee 표준을 따르고 MSP430 MCU가 탑재되어 있다 A new platform for low power research - Monitoring Applications Long lifetime, low power, low cost Built from application experiences and low duty cycle design principles Robustness - Integrated Antenna - Integrated Sensors Standards Based - IEEE USB IEEE CC kbps GHz ISM Band TI MSP430 - Ultra low power 센서보드 Hmote를 위한 센서보드로는 그림 3에 보인 H-sensor가 있다. 이는 Hmote의 확장 인터페이스를 통 해 연결되며 보드 상의 다양한 센서들을 통하여 온도, 조도, 습도, 초음파 등의 감지가 가능하다

137 [H-sensor 보드] 3. S/W 설계 3.1 기능 Hmote2420이 수신하는 RF 패킷을 시리얼 포트를 통해 모니터링 할 수 있다. 3.2 구조 패킷 모니터링을 위한 시스템 구조는 다음과 같다. 송신 모트에서 임의의 센서 값, 예를들면 조도 센서의 값을 RF 패킷으로 송신하면 수신 모트에 서 RF 패킷을 받게 된다. 받은 패킷은 USB to Serial을 통해 버퍼에 저장되고 보드와 연결된 호 스트 PC의 시리얼 포트를 통해 PC 상에서 수신된 패킷을 실시간으로 확인할 수 있다

138 4. S/W 구현 serial.c 주요 코드 설명 #define BUF_SIZE 255 // 패킷 앞부분에 들어오는 쓰레기 값을 제거하는 함수 int parse_value(char *dst, char *src, int len) { int i, j; if (src[0]!= 0x7e) return 0; if (src[1]!= 0x42) return 0; for (i = 0, j = i + 2; j < len - 2; i++, j++) { if (src[j] == 0x7d) dst[i] = (src[j] & 0xf0) + (src[++j] & 0x0f); else dst[i] = src[j]; return 0; int main() { int serial_fd; struct termios oldtio, newtio; unsigned char buf[buf_size]; unsigned char data[buf_size]; unsigned char c; int i, j; if ((serial_fd = open("/dev/ttyusb0", O_RDWR O_NOCTTY)) < 0) { return 0; // 시리얼 오픈

139 tcgetattr(serial_fd, &oldtio); // 시리얼 초기화 bzero(&newtio, sizeof(newtio)); newtio.c_cflag = B57600 CS8 CLOCAL CREAD; newtio.c_iflag = INPCK; newtio.c_oflag = 0; newtio.c_lflag = 0; tcflush(serial_fd, TCIFLUSH); tcsetattr(serial_fd, TCSANOW, &newtio); // Baudrate 57600bps while (1) { i = 0; if (read(serial_fd, &c, 1) == 1) // 시리얼로부터 패킷의 첫 번째를 읽어 들인다. { buf[i] = c; while (1) { if (read(serial_fd, &c, 1) == 1) // 이 후 패킷의 데이터를 읽어 들인다. { buf[++i] = c; if (c == 0x7e) { break; if (i > 4) { parse_value(data, buf, i); for (j = 0; j < 18; j++) { printf("%02x ", data[j]); printf(" n"); // 패킷 출력

140 5. 수행 방법 및 결과 5.1 수행 방법 어플리케이션이 있는 /320app/Application/Hmote_Serial로 이동한다. ]# cd /320app/Application/Hmote_Serial --경로이동 'make' 명령어를 입력한다. ]# make --어플리케이션 컴파일 생성된 실행파일을 'zmodem'을 이용하여 타겟보드로 다운로드한다. 아래그림은 타겟보드에 다운로드된 파일이미지 이다. 다음으로 Hmote2420 모트 2개를 준비한다. 송신용으로 사용할 모트에 H-Sensor 모듈을 부 착한다. Cygwin의 /opt/tinyos-1.x/apps/hybus_phototestscope로 이동하여 컴파일을 하고 H-Sensor 모듈을 부착한 모트에 업로딩을 한다. Cygwin]# cd /opt/tinyos-1.x/apps/hybus_phototestscope --경로이동

141 이 프로그램은 조도를 센싱하여 RF로 송신하는 역할을 한다. Cygwin]# make hybus Cygwin]# make hybus reinstall.1 또는, Cygwin]# make hybus install -- Cygwin 어플리케이션컴파일 -- 모트에 생성된 이미지 업로딩 -- 컴파일 및 업로드 동시수행 아래그림은 모트에 프로그래밍 되는 과정이다. 정상적으로업로드 되면 적색LED가 켜져있는상태에서 주황색LED가 점멸을 반복한다

142 다른 한 개의 모트에는 Cygwin에서 /opt/tinyos-1.x/apps/tosbase로 이동하여 컴파일을 하 고 업로딩을 한다. 이 프로그램은 같은 채널로 들어오는 RF 패킷을 수신하는 프로그램이다. Cygwin]# cd /opt/tinyos-1.x/apps/tosbase --경로이동 즉 먼저 업로딩한 Hybus_PhotoTestScope 프로그램이 업로딩된 모트에서 센싱값을 TOSBasse 프로그램이 업로딩된 모트에서 받아서 시리얼을 통해 타겟보드에 전달한다. Cygwin]# make hybus -- Cygwin 어플리케이션 컴파일 Cygwin]# make hybus reinstall.0 -- 생성된 이미지 업로드 또는, Cygwin]# make hybus install -- 컴파일 및 업로드 동시수행 TOSBase가 업로딩된 모트를 320TKU와 USB Cable로 연결한다. 모트 두 개가 업로드가 완료되면 센싱하여 데이터를 보내는 모트에 맞추어 입력받는 모트의 파란색 LED가 점멸한다. 모트의 준비가 끝나면, 타겟보드에서 USB Cable로 연결된 시리얼장치를 인식하기 위해

143 ttyusb0 노드를 만들어야 한다. 다음과 같은 명령어로 노드를 생성한다. 320TKU]# mknod ttyusb0 c ttyusb0 노드생성 타겟보드에서 앞서 다운로드 받아놓은 실행파일이 있는 위치'/root/tset_app'에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./serial Cygwin에서 mote업로딩하기 1. Cygwin와 TinyOS1.x를 설치한다. 2. Cygwin에서 'cd /opt/tinyos-1.x/apps/hybus_phototestscope'를 입력하여 해당 경로로 이동한다. 3. mote를 PC와 연결하고 시리얼 드라이버를 설치한다. 4. make hybus install 을 입력하여 mote에 컴파일 및 업로드한다

144 5.2 수행 결과 다음과 같이 RF 패킷을 볼 수 있다. 패킷의 제일 마지막 2바이트가 16진수로 표현된 조도 값이 다. 직접 손으로 조도 센서 부분을 가리면 값이 떨어지고 손을 다시 띄면 값이 올라감을 확인할 수 있다

145 Chapter 7. Berkeley DB 어플리케이션 1. 개요 본 프로그램은 오라클사의 오픈소스 버클리 데이터베이스 라이브러리를 임베디드 보드에 포팅해 보고, API를 기반으로 DB 생성 및 기본기능인 삽입, 삭제, 검색을 수행할 수 있는 간단한 콘솔 용 명함관리 프로그램을 작성해 보겠다. 2. 관련기술 2.1 Berkeley DB 버클리 데이터베이스는 오라클사의 대표적인 임베디드 DB로 트랜잭션을 관리해 주는 오픈소스 라이브러리형 데이터베이스이다. 최적화된 API로 제공되기 때문에 사용에 있어서 확장성과 처리 성능이 뛰어나다. 다음 그림은 버클리 데이터베이스가 일반적인 관계형 데이터베이스와 어떤 구 조적인 차이점이 있는지 잘 설명해 준다. Oracle Berkeley DB는 업계 선두의 임베디드 오픈 소스 개발자용 데이터베이스로, 빠르고 안정 적인 환경을 제공하며, 별도의 관리를 전혀 필요로 하지 않는다. Berkeley DB는 애플리케이션에 직접 연결되는 라이브러리로 제공되며, 애플리케이션은 원격 서버로 메시지를 보내는 대신 간단 한 함수 호출만으로 데이터베이스를 이용하며, 따라서 클라이언트/서버 아키텍처의 성능 오버헤 드를 피할 수 있다. 또 Oracle Berkeley DB는 SQL 쿼리 프로세싱의 오버헤드를 제거할 수 있게 하며, 예측 가능한 접근 패턴을 가진 애플리케이션의 성능 개선이 가능하다

146 Berkeley DB는 ACID 트랜잭션 및 복구 메커니즘, 락킹 메커니즘, 멀티-프로세스, 멀티-쓰레드 를 이용한 동시성 관리, 핫/콜드 백업, 고가용성 애플리케이션을 위한 싱글-마스터 복제 환경 등 고전적인 관계형 데이터베이스에서 제공되는 것과 동일한 수준의 안정적인 데이터 스토리지 환 경을 제공한다. 또한, Berkeley DB는 메모리 또는 디스크 상에 존재하는 데이터베이스를 관리할 수 있으며, 애플리케이션이 프로그램적으로 런타임 관리 기능을 제공하므로 운영자에 의한 수작 업 관리가 전혀 불필요하다. Berkeley DB는 단순하고 빠르고, 작고, 안정적인 데이터베이스로서 설계되었다. 그리고 Berkeley DB는 다양한 시스템에 대한 복제를 지원하므로, 대규모 확장 환경 에서의 응답시간을 보장하고 고가용성 솔루션을 위한 폴트 톨러런스를 구현하는 것이 가능하다. Berkeley DB는 모든 업데이트를 지정된 마스터(master)로 전송하고, 마스터는 다수의 레플리카 (replica)에 변경 사항을 자동으로 배포한다. 워크로드는 여러 대의 레플리카에 분산되며, 시스템 의 확장이 필요한 경우 언제든 새로운 레플리카를 추가로 배치할 수 있다. 레플리카 중 하나가 실패한 경우, 나머지 레플리카가 작업을 수행하며, 마스터에 장애가 발생한 경우, 애플리케이션 이 마스터 선정(election)을 요청함으로써 새로운 마스터를 지정할 수 있다. 새로운 마스터가 선 정되면, 모든 레플리카가 새로운 마스터와 동기화되며, 서비스의 중단 없이 정상적인 프로세싱 작업을 계속할 수 있게된다. Berkeley DB는 매우 유연한 구조를 가지므로, 개발자가 그 동작을 자유롭게 컨트롤할 수 있다. 따라서 다양한 애플리케이션에 적용이 가능하며 기업 내부적으로 개발한 커스텀 솔루션을 대체 하는 용도로 활용될 수도 있는데, 예를 들어, 개발자는 리소스의 할당 방식, 레코드 캐싱을 위해 사용되는 메모리의 양, 개별 테이블을 위해 사용되는 디스크 스토리지 구조, 내구성(durability)와 격리성(isolation)의 보장 방법, 복제 정책 등을 직접 컨트롤할 수 있다. 또 포팅, 통합, 디버깅, 최적화를 위한 모든 소스 코드가 제공된다. Berkeley DB는 데이터를 로컬에 저장하는 애플리케이션을 위해 뛰어난 성능, 안정성, 확장성의 퍼시스턴스 환경을 제공하며, 온라인 상태에서 별도의 관리자 없이도 운영이 가능하고, 또 예측 가능한 방식으로 데이터 접근이 가능하다는 장점이 있다 데이터 저장 Berkeley DB는 다른 데이터베이스와 달리 추가적인 오버헤드를 수반하지 않고도 데이터에 쉽고 빠르게 접속할 수 있는 환경을 제공한다. Berkeley DB는 애플리케이션 내부에서 실행 가능한 C 라이브러리의 형태로 구현되므로, 원격 데이터베이스 서버와의 인터프로세스 커뮤니케이션에 수 반되는 지연 요소를 제거할 수 있다. 또 공유 캐시를 이용하여 대부분의 액티브 데이터를 메모 리에 보관하므로, 디스크 I/O 또한 최소화한다. 로컬, 인-프로세스 데이터 스토리지 스키마 중립적, 애플리케이션 네이티브 데이터 포맷 인덱스 기반/순차적 데이터 인출 지원(Btree, Queue, Recno, Hash) 멀티-프로세스 및 멀티-쓰레드 지원 높은 동시성을 요구하는 시스템을 위한 정교하고 유연한 락킹 메커니즘 멀티-버전 동시성 컨트롤 (MVCC) 2차 인덱스의 지원

147 인-메모리 방식과, 디스크 방식을 동시 지원 온라인 Btree 압축 지원 온라인 Btree 디스크 용량 재확보 지원 온라인 상태에서 사용되지 않는 락을 제거 디스크 데이터 암호화(AES) 최대 4 GB의 레코드, 최대 256 TB의 테이블 지원 트랜잭션 Berkeley DB는 다른 데이터베이스와 마찬가지로 데이터를 안정적으로 저장하고 데이터 무결성을 보장한다. Berkeley DB는 데이터베이스 작업을 그룹화하고 전체 작업이 성공하지 않는 경우 전 체 작업의 커밋을 취소하는 기능을 제공한다. 시스템에 장애가 발생한 경우에는 자동으로 복구 가 수행되며, 부분적으로 완료된 트랜잭션을 롤백하여 시스템의 일관성을 보장한다. ACID 원칙의 완벽한 지원 격리 레벨(isolation level) 선택 및 내구성(durability) 보장 (트랜잭션 단위로 설정 가능) 네스티드 트랜잭션(nested transaction) 지원 분산 트랜잭션 (XA) 재해 복구 및 일반 장애 복구 모드 복구 작업의 자동 순차화 유연한 데드락 감지 기능 (커스터마이즈 가능) 애플리케이션 별 로그 파일 저장 및 복구 지원 핫/콜드 백업, 로그 파일 아카이브, 풀 데이터베이스 덤프 복제 높은 시스템 확장성과 가용성이 요구되는 경우를 위해, Berkeley DB는 최신 복제 기능을 제공하 고 여러 대의 시스템에 워크로드를 분산할 수 있다. 동일한 샤시 내에 존재하는 다른 보드로, 데 이터 센터 내의 여러 서버로, 또는 지리적으로 분산된 위치로 데이터를 복제할 수 있다. 복제 시 스템의 모든 속성(데이터 무결성, 트랜잭션 보장, 처리 속도, 네트워크 전송 등)이 커스터마이즈 가능하며 애플리케이션 요구사항에 따른 튜닝이 가능하다. 싱글 마스터, 멀티 레플리카 모델 자동 페일오버/마스터 재선정(re-election) Paxos 호환 마스터 선정 알고리즘 새로운 레플리카를 언제든 그룹에 추가 가능 핫 스탠바이 지원 무중단 업그레이드 노드의 지리적 분산 가능 인-메모리 복제 옵션 클라이언트 간 복제 클라이언트 동기화를 위한 지연 시간 설정 가능 동기화 성능 조절

148 네트워크 전송 방식과 무관 수천 대의 레플리카 노드를 지원하는 검증된 확장성 신속한 개발을 위한 복제 프레임워크 지원 구축 Berkeley DB는 매우 유연하고 구축 및 통합이 용이하다. Berkeley DB는 C 라이브러리 형태로 제공되어 애플리케이션과 함께 설치, 구성되고, 별도 관리자 없이 완벽한 운영이 가능하도록 설 계되었으며, 따라서 모든 관리 기능은 프로그램에 의해 컨트롤된다. Berkeley DB는 매우 다양한 프로그램 언어와 운영체제 플랫폼을 지원하며, 초대규모 미션 크리티컬 애플리케이션에서 데스크 탑/모바일 디바이스 애플리케이션에 이르는 수백만 고객 환경에서 검증되었다. 프로그램에 의한 관리 및 운영 운영자가 전혀 불필요 언어 지원 (C, C++, Java, Perl, Python, PHP, Tcl, Ruby 등) 운영체제 지원 (Linux, Windows, BSD UNIX, Solaris, Mac OS/X, VxWorks 및 POSIX 호환 운영체제) Microsoft Windows 인스톨러 지원 Apache 통합 기능 제공 RPC 기반 API 제한된 메모리 용량을 갖는 디바이스의 지원 (최소 400 KB의 메모리 공간 사용) 테라바이트 급 데이터, 수십억 개의 레코드를 지원하는 확장성 소스 코드 및 테스트 제품 포함 Berkeley DB의 사용시 다양한 장점과 기능에 대해서 설명하였다 간단하게 요약하면 일반 관계형 데이터베이스는 독립된 프로그램으로 구성되어 애플리케이션과 따로 동작하면서 애플리케이션과 네트워크가 Inter process communication 을 통해 자료를 주고받는다. 하지만 버클리 데이터베 이스는 컴파일 시 애플리케이션에 링크되어 애플리케이션의 메모리 어드레스를 함께 사용한다. Locking, 로그 관리, 메모리 관리 등과 같은 기본적인 모든 데이터베이스의 작동이 라이브러리 내에서 수행되고, 멀티 프로세스 또는 프로세스에 있는 멀티 쓰레드는 동시에 데이터베이스를 사용할 수 있다. 결과적으로 프로세스 간 통신이 사라지게 되어 시스템의 전체적인 구조가 간단해진다. 당연히 버클리 데이터베이스는 일반적으로 널리 사용되고 있는 언어인 Java, C, C++, Perl, Tcl, Phthon 그리고 PHP의 API를 제공해 준다. 또한 버클리 데이터베이스는 많은 플랫폼을 지원한다. 모든 유닉스와 리눅스 플랫폼, MS-Windows 플랫폼, 32bit, 64bit 플랫폼, 하이엔드 인터넷 서버 (High-end Internet Server) 나, 데스크톱 시스템, 노트북 등 모든 곳에서 운용이 가능하다고 볼 수 있다. 버클리 데이터베이스는 다음과 같은 기본적인 기능을 수행한다

149 Page cache management 불필요한 I/O를 줄임으로써 빠른 데이터 접근을 지원한다. Transaction and logging 데이터베이스 복구를 보장한다. Locking 여러 사용자에 의한 다중 읽기 및 쓰기(multiple read/write)를 보장한다. 특히, 일반적인 관계형 데이터베이스와 차별화된 내용은 다음과 같다. SQL 개념의 질의문은 지원되지 않는다. 객체 지향적(Object Oriented)으로 설계되어 있지 않다. 즉 C로 코딩되어 있다. Network 기능이 없다. 데이터베이스 서버가 아니다. 2.2 레코드 데이터 관리 버클리 데이터베이스는 데이터를 어떻게 관리할까? 먼저 데이터의 구조는 무척이나 간단하다. 예를 들어 데이터 파일에 저장되는 레코드의 구조는 다음과 같다. Key Value color blue size 10 name Web item SQL의 테이블, 칼럼 구조에 익숙한 개발자라면 위 표에서 Key, Value 구조의 막막함이 느껴질 것이다. 하지만 잘 코딩된 데이터 구조가 바탕에 있다면 Key, Value의 간단, 명료함은 그 가치를 나타낼 것이다. 위의 구조는 Java 객체 중 Properties 객체와 유사하다. 이 구조를 바탕으로 데이터베이스는 레 코드 삽입, 삭제, 수정, 그리고 찾기 기능을 수행한다. 여기서 알아두어야 할 중요한 사항은 Value 부분에 대해서는 전혀 오퍼레이션을 하지 않는다는 것이다. Value는 Key로 구분되는 데이터일 뿐이다. 이는 Value 부분에 대한 찾기 기능이 없다는 뜻으로 특정 Value를 찾고자 한다면 그 Key 값이 무엇인지를 먼저 알아야 한다. Key와 Value에 대한 특징은 다음과 같다. 1. Byte 형태의 값을 갖는다. 2. 길이는 고정적이거나 가변적이다. 3. Key나 Value에 대한 형태는 프로그래머에 의해 결정된다. 4. 최대크기는 4GB 네 가지 주요 특징 가운데 세 번째 특징은 프로그래머에게는 부담이 될 수도 있다. 버클리 데이 터베이스는 Key와 Value를 의미가 없는 단순한 byte string 으로 인식하고 그에 대한 정보를 하 나도 갖고 있지 않기 때문이다. 따라서 Key와 Value가 의미를 갖기 위해서는 프로그래머가 미리

150 구조를 설계한 후 그 구조에 맞게 Key와Value 값을 가공하여 사용해야 한다. Key와 Value 구조 를 모른다면 그 데이터베이스는 의미 없는 Byte 덩어리일 뿐이다. C나 C++로 개발하는 프로그래머일 경우에는 Struct 문장을 사용하여 Key와 Value 구조를 정의 하여 사용할 수 있다. 개발 언어가 Java일 경우에는 Object Serialization을 통해 손쉽게 객체를 처리할 수 있다. 3. S/W 설계 버클리 DB API를 토대로 아주 간단한 명함관리 프로그램을 작성해 보았다. 3.1 기능 명함관리 프로그램의 기능은 다음과 같다. DB 생성 및 삭제 BTree 구조 DB의 삽입, 삭제 기능 인덱스를 이용한 검색 기능 DB의 동일 데이터 중복 방지 3.2 구조 명함관리 프로그램의 S/W 구조는 다음과 같다. 프로그램이 실행되면 제일 먼저 정해진 페이지사이즈와 캐시사이즈를 토대로 데이터베이스가 생 성된다. 콘솔 상에서 원하는 데이터를 삽입, 삭제, 검색 명령을 내리게 되며 해당 명령에 따라 DB 라이브러리에서 제공되는 API에 의해 DB 파일과 통신을 하게 된다

151 4. S/W 설계 4.1 Berkeley DB 포팅 Berkeley DB API (이하 BDB)를 호출해서 사용하기 위해서는 먼저 오픈소스를 ARM용으로 크로 스 컴파일을 수행해서 사용하고자 하는 컴파일러의 라이브러리 위치에 설치해야하며 BDB 기반 으로 작성된 어플리케이션을 타겟 보드에서 실행하기 위해서도 타겟보드의 파일시스템 내의 라 이브러리 디렉토리에 설치되어 있어야 한다. BDB 다운로드 BDB 설치를 하기 위해서는 설치파일을 다운로드 받아야한다. 아래의 오라클 사이트에 방문서 다운로드 페이지에서 받을 수 있고 자사에서 제공하는 CD 내에도 포함되어 있으니 을 복사해서 사용해도 된다. 파일이름은 db tar.gz이다. BDB 환경 구축 [ARM 컴파일러 상에 설치] 다운로드한 파일을 작업 디렉토리에 압축해제를 한다. 그리고 작업의 편의를 위해 설치 환경 설 정 파일을 생성한다. ]# cd db /build_unix -- 해당경로로 이동 ]# vi config-arm -- config-arm 파일을 vi 편집기로 만들기 압축해제 후 아래의 옵션에 맞추어 설치 환경을 설정한다. VI 편집기를 이용해서 아래와 같이 입력하고 저장한다

152 #!/bin/sh export CC=/usr/local/arm-linux-4.1.1/bin/arm-linux-gcc export STRIP=/usr/local/arm-linux-4.1.1/bin/arm-linux-strip export RANLIB=/usr/local/arm-linux-4.1.1/bin/arm-linux-ranlib export CXX=/usr/local/arm-linux-4.1.1/bin/arm-linux-g++ export AR=/usr/local/arm-linux-4.1.1/bin/arm-linux-ar :q!../dist/configure --build=i686-pc-linux-gnu --host=arm-linux --prefix=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi 컴파일러의 라이브러리 위치가 /usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi 밑에 존 재하므로 Prefix를 여기로 설정 하였다. 아래의 순서대로 명령어를 입력하여 설치를 진행한다 #./config-arm # make # make install # cd /usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi 설치까지 완료하였다. 마지막으로 /usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi으로 이동하여 정 확히 인스톨 되었는지 확인을 하도록 한다. [타겟보드 파일시스템 상에 설치] 이제 타겟보드의 파일시스템 상에 설치를 하도록 하자. 설치 방법은 위에서와 동일하다. 다만 Prefix를 변경해줘야 한다. 'config-arm' 파일을 VI편집기 로 오픈해서 Prefix 부분을 변경한다. Prefix의 디폴트 설정인 /usr/local/ 로 되어 있기는 하지만 확실히 하기위해서 적어주는 것이 좋 다. ]# vi config-arm --prefix=/usr/local/ <-- 이렇게 변경 수정이 끝났으면 다시 설치를 진행하도록 하자

153 ]# make distclean ]#./config-arm ]# make ]# make install DESTDIR=$PWD/Bdb ]# cd Bdb 설치까지 완료하였다. 마지막으로 Bdb로 이동하여 정확히 인스톨 되었는지 확인을 하도록 한다. 설치 DESTDIR을 설정한 이유는 그대로 make install을 해버리면 Prefix 위치가 X86에서 사용되 는 라이브러리 디렉토리이기 때문에 만약 기존의 X86용으로 컴파일된 BDB 라이브러리들이 이 미 설치되어 있다면 ARtarM용으로 덮어씌워져서 설치가 되어버린다. 그렇게 되면 기존의 X86용 BDB 라이브러리들은 사라지게 되어버린다. 이것을 방지하기 위해 별도의 DESTDIR 옵션을 사용 하여 지정한 위치에 설치되도록 한 것이다. 위와 같이 DESTDIR을 설정하게 되면 현재 디렉토리 밑의 Bdb 디렉토리를 생성시켜서 설치를 진행하게 된다. 설치를 확인하였으면 lib 디렉토리를 제외한 나머지 디렉토리를 삭제한 후 압축을 한다. ]# tar cvfz Bdb.tgz * Bdb.tgz 라는 압축파일이 생성될 것이다. 이 파일을 타겟보드의 최상위 위치로 다운로드한다. 다 운로드를 완료하였으면 압축을 해제한다. 320TKU]# tar xzf Bdb.tgz 이것으로 환경 구축은 모두 완료되었다

154 4.2 소스 코드 recd.c 주요 코드 #define DB_NAME "MYDB" typedef struct my_struct { int id; char name[15]; char phonenum[15]; MY_STRUCT; MY_STRUCT mydb; void db_open(db **, char *, int); int main() { DB *dbp; DBC *dbcp; DBT key, data; db_recno_t index; int ret = 0, i; char keyvalue, idxnum; // Open the DB db_open(&dbp, DB_NAME, 0); DB의 구조체를 정의하고 mydb로 선언하였다. DB 프로세서 및 DB 커서 프로세서를 포인터로 선언하였다. DB 테이블로 key와 data를 선언하였고 레코드 넘버로 index를 선언하였다

155 // Main text form printf("******************* n"); printf("* NMS Program * n"); printf("* * n"); printf("* 1. Registration * n"); printf("* 2. Search * n"); printf("* 3. Delete * n"); printf("* 4. Exit * n"); printf("******************* n"); do { printf("=>"); keyvalue = getc(stdin); getc(stdin); // 키보드의 키 값을 읽어온다. switch (keyvalue) { case '1': // Registration printf("input the registration ID :"); idxnum = getc(stdin); getc(stdin); mydb.id = index = atoi(&idxnum); printf("insert the name :"); // 입력한 이름을 DB에 저장한다. fgets(mydb.name, sizeof(mydb.name), stdin); for (i = 0; i < 15; i++) { if (mydb.name[i] == ' n') { mydb.name[i] = ' 0'; break; printf("insert the phone number :"); // 입력한 폰 번호를 DB에 저장한다. fgets(mydb.phonenum, sizeof(mydb.phonenum), stdin); for (i = 0; i < 15; i++) { if (mydb.phonenum[i] == ' n') { mydb.phonenum[i] = ' 0'; break;

156 키보드로 숫자를 입력하여 메뉴를 선택한다. 해당 키 값에 의해 등록, 검색, 삭제의 기능으로 구분된다. // zero out the DBTs before using them memset(&key, 0, sizeof(dbt)); memset(&data, 0, sizeof(dbt)); key.data = &(mydb.id); key.size = sizeof(int); data.data = &mydb; data.size = sizeof(my_struct); // DB에 데이터를 저장한다. switch (ret = dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) { case 0: break; default: dbp->err(dbp, ret, "DB->put"); break; break; case '2': // Search memset(&key, 0, sizeof(dbt)); memset(&data, 0, sizeof(dbt)); memset(&mydb, 0, sizeof(my_struct)); mydb.id = index = 1; key.data = &(mydb.id); key.size = sizeof(int); data.data = &mydb; data.ulen = sizeof(my_struct); data.flags = DB_DBT_USERMEM; /* Acquire a cursor for the database. */ if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0))!= 0) { dbp->err(dbp, ret, "DB->cursor"); exit (1);

157 dbp->put() 함수를 이용하여 DB에 저장할 때 DB_NOOVERWRITE 옵션을 지정하여 중복저장이 안되도록 처리하였다. printf("<registration Name List> n"); /* Walk through the database and print out the key/data pairs. */ // DB에 저장된 모든 Key와 데이터 정보를 가져온다. while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) printf("no.%lu : %.*s n", *(u_long *)key.data, (int)data.size, mydb.name); printf("input ID Number =>"); idxnum = getc(stdin); getc(stdin); mydb.id = index = atoi(&idxnum); key.data = &mydb.id; key.size = sizeof(int); // DB에 저장된 정보 중 원하는 key에 대한 데이터를 가져온다. if ((ret = dbcp->c_get(dbcp, &key, &data, DB_SET)) == 0) printf("no.%lu : %.*s's phone number : %s n", *(u_long *)key.data, (int)data.size, mydb.name, mydb.phonenum); else printf("no registration data n"); // if (ret!= DB_NOTFOUND) // dbp->err(dbp, ret, "DBcursor->get"); /* Close the cursor. */ if ((ret = dbcp->c_close(dbcp))!= 0) { dbp->err(dbp, ret, "DBcursor->close"); exit (1); break; DB에 저장된 정보를 가져올 때 반드시 DB 커서를 얻어야만 한다. 이 커서에 의해 정보의 위치 를 찾아서 접근할 수 있다. 커서의 사용이 끝나면 반드시 해제해야한다

158 case '3': // Delete printf("input ID Number =>"); idxnum = getc(stdin); getc(stdin); // 검색할 ID를 입력 받는다. mydb.id = index = atoi(&idxnum); // 검색할 ID를 저장한다. /* Acquire a cursor for the database. */ if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0))!= 0) { dbp->err(dbp, ret, "DB->cursor"); exit (1); key.data = &mydb.id; key.size = sizeof(int); while ((ret = dbcp->c_get(dbcp, &key, &data, DB_SET)) == 0) dbcp->c_del(dbcp, 0); // 해당 Key의 데이터를 삭제한다. /* Close the cursor. */ if ((ret = dbcp->c_close(dbcp))!= 0) { dbp->err(dbp, ret, "DBcursor->close"); exit (1); break; case '4': // Exit printf("exit Program... n"); default: break; while (keyvalue!= '4'); // 4 를 입력하면 프로그램이 종료된다. /* Close the DB */ if (dbp!= NULL) dbp->close(dbp, 0); return 0;

159 void db_open(db **dbp, char *name, int dups) { DB *db; int ret; /* Create the database handle. */ if ((ret = db_create(&db, NULL, 0))!= 0) { exit (1); // DB 생성 /* Optionally, turn on duplicate data items. */ if (dups && (ret = db->set_flags(db, DB_DUP))!= 0) { db->err(db, ret, "db->set_flags: DB_DUP"); exit (1); db->set_errfile(db, stderr); db->set_pagesize(db, 32 * 1024); db->set_cachesize(db, 0, 32 * 1024 * 1024, 1); // 페이지사이즈를 결정 // 캐쉬사이즈를 결정 /* * Open a database in the environment: * create if it doesn't exist * free-threaded handle * read/write owner only */ if ((ret = db->open(db, NULL, name, NULL, DB_BTREE, DB_CREATE, 0600))!= 0) { // DB를 오픈한다. (void)db->close(db, 0); db->err(db, ret, "db->open : %s", name); exit (1); *dbp = db; // 오픈된 db의 포인터를 전달한다

160 5. 수행 방법 및 결과 5.1 수행 방법 어플리케이션 소스파일이 위치한 320app/Application/BerkeleyDB/bdb_app로 이동한다. # cd /320app/Application/BerkeleyDB/bdb_app make 명령어를 입력하여 어플리케이션을 컴파일 한다. # make 생성된 실행파일을 타겟보드로 다운로드한다. BDB의 라이브러리 경로를 추가해 준다. # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/loca1l//BerkeleyDB.4.5/lib 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. #./recd 키보드로 숫자를 입력하여 1 ~ 3번 까지 각각의 기능을 테스트 해본다. 5.2 결과 시작 화면

161 1번을 선택 (등록) 2번을 선택 (검색)

162 3번 선택 (삭제)

163 Chapter 8. GTK Painter 1. 개요 이번 장에서는 GTK+프로그래밍에 대해 실습해보고자 한다. GTK Painter는 GTK-2.0+기반으로 작성된 아주 간단한 그림 그리기용 프로그램이다. GTK+에서 제공되는 glade-2를 이용하여 기본 틀을 만들었고 그에 따라 생성되는 위젯들을 통해 사용자 인 터페이스를 콜백 함수로써 구현하여 하나의 어플리케이션을 완성하였다. 소개되는 GTK Painter 를 통해 Glade 사용법과 GTK+ 프로그래밍의 기초를 익히는데 어느 정도 도움이 될 것이다. 2. 관련기술 2.1 김프 툴킷(GTK) 초기에 GIMP를 위해서 만들어졌던 김프 툴킷(GIMP Toolkit), 줄여서 GTK+라고도 하는 툴킷은 X 윈도우 시스템을 위한 위젯 툴킷 중 하나이다. GTK+와 Qt는 모티프에 대한 좋은 대안이 되어 주었다. GTK+는 1997년 Spencer Kimball, Peter Mattis, Josh MacDonald에 의해서 만들어졌다. 그들은 모두 UC Berkeley에 있는 experimental Computing Facility (XCF) 소속이었다. LGPL로 라이선스되었기 때문에, GTK+는 자유 소프트웨어이자 오픈 소 스 소프트웨어이고, GNU 프로젝트의 일부분이다. (1) 프로그래밍 언어 GTK+는 C (프로그래밍 언어)를 사용한다. 그렇지만 그들의 제작자들은 객체지향 구조를 사용하였다. 그놈 플랫폼은 C++, 펄, 루비, 자바, 파이썬으로의 바인딩을 제공하였다.많은 사람들이 Ada, D, 하스켈, 파스칼, PHP, 닷넷 프레임워크로의 바인딩을 작성하였다. 다른 많은 위짓 툴킷들과 달리, 하지만 Qt와 마찬가지로 GTK+는 Xt에 기반하지 않는다. 그래서 GTK+를 많은 다른 환경으로 이식할 수 있었다. 하지만 전통적인 X11 애플리케이션 의 사용자 설정 방식인 X 리소스 데이터베이스에 접근할 수 없다는 단점이 있다. (2) 모양 사용자는 디스플레이 엔진으로 툴킷의 모양을 설정할 수 있다. 엔진들은 윈도, 모티프, Qt, 넥스트스텝등의 모양으로 그려줄 수 있었다. (3) GTK+를 사용하는 환경 Screenshot of the GIMP 2.0 on Xfce4그놈 환경은 GTK+를 기반으로 사용한다. Xfce 환경도 GTK+를 기반으로 사용한다. 하지만 Xfce용 프로그램은 많은 것에 의존하지 않는다. (이것은 그놈 프로그램과 GTK+ 프로그램을 구분한다) GPE, Maemo (노키아의 인터넷 태블릿 프레임워크), 액세스 리눅스 플랫폼 (새로운 팜 OS 호환 PDA 플랫폼) 도 GTK+를 기반으로 한다. GTK+ 프로그램은 KDE 같은 다른 데스크탑 환경에서 돌아간다. GTK+는 마이크로소프트 윈도에서도 돌아간다. DirectFB와 ncurses 기반 포팅도 있다

164 (4) 그래픽과 관련되지 않은 코드 GTK+는 초기에 그래픽과 관련되지 않은 코드를 포함했다. 이들은 링크드 리스트 및 바이 너리 트리를 제공했다. GObject와 함께 오는 이러한 유틸리티 시스템은 Glib라는 별도의 라 이브러리로 쪼개졌고, 이는 그래픽 인터페이스가 필요 없는 프로그래머에게 도움을 준다. (5) GTK+ 2 GTK+ 2는 GTK+를 계승하였다. 이것의 새로운 기능은 Pango를 사용하는 새로운 텍스트 렌더링 엔진, 새로운 테마 엔진, 향상된 접근성, 유니코드로의 완전한 전환이 있다. 하지만 GTK+ 2는 GTK+ 1과 호환성이 없으므로 프로그래머들이 소스를 새로 짜야 한다. 몇몇 프 로그램들은 GTK+ 1을 그대로 사용한다. GTK+ 1은 GTK+ 2보다 빠르고 덜 복잡하고 임베 디드 환경에 더 적합하다. (6) 차후 개발 Project Ridley는 GTK+가 현재 포함하지 않는 각종의 라이브러리를 포함하려고 하는 시 도이다. 이들은 libgnome, libgnomeui, libgnomeprint22, libgnomeprintui22, libglade, libgnomecanvas, libegg, libeel,gtkglext를 포함한다. 2.2 GTK+의 소개 GTK+는 버튼, 스크롤바, 메뉴와 같은 그래픽 객체와 이것들을 구현하는데 필요한 함수들의 모음 이다. 이는 간단하지만 정확한 정의이다. 그래픽 객체는 위젯(Widget)이라고도 하고, GTK+를 구 성하는 위젯들의 집합을 GTK+ widget Set이라고 한다. 여기에 대응되는 함수들을 더한 것을 툴 킷(Toolkit)이라고 한다. GTK+는 GNU Image Manipulation Program (GIMP)을 개발하는 도중에 만들어졌다. GIMP는 Spencer Kimball과 Peter Mattis에 의해 만들어진, 리눅스와 UNIX 운영체제를 위한 인기 있는 오픈소스의 이미지 처리 프로그램이다. 원래 GIMP는 X윈도우 시스템에 기반을 둔 상용 툴킷인 모티프(Motif)를 이용하여 개발되었다. 그러나 모티프는 그들이 원했던 만큼의 융통성을 제공하지 못했기 때문에, GIMP의 개발자들은 GIMP Toolkit(GTK)을 만들었다. GTK+는 원래의 GIMP Toolkit을 확장한 것이다. 2.3 GTK+ 프로그래밍 절차 일반적으로 GTK+ 프로그래밍을 위한 절차는 다음과 같다. 1. GTK+프로그래밍 환경 구성 2. 위젯 생성 및 속성 설정 3. 콜백 함수 정의 4. 시그널과 이벤트 처리 5. 컴파일 6. 프로그램 실행 테스트

165 GTK Painter 또한 상기 절차대로 작성을 하였다. 여기서 환경 구성 부분은 X86의 경우 사용자 PC에 리눅스를 설치하게 되면 기본적으로 설치되기 때문에 신경 쓸 필요가 없고 임베디드 타겟 보드에서 프로그램이 실행될 수 있도록 ARM용 컴파일러에 GTK+-2.0 라이브러리를 설치해야 한다. 이러한 작업들은 일일이 다 하기에는 시간이 많이 걸리고 복잡하기 때문에 자세히 기술하 지 않는다. 다만 일련의 작업들은 이미 다 갖추어져 있기 때문에 GTK+프로그램밍 부터 시작하 면 된다. 위젯 생성과 콜백 함수 정의는 일반적으로 glade-2를 이용하여 작성하게 된다. glade-2란 윈도우즈의 MFC 툴처럼 일종의 사용자 툴이라고 이해하면 된다. Glade-2 유틸리티 리눅스에서 glade-2라는 명령어를 실행하면 다음과 같이 Glade-2 유틸리티가 나타난다. 여기서 간단하게 GTK+ 프로그래밍을 하기위한 방법과 기본적으로 윈도우 위젯을 만드는 방법만 소개하도록 하겠다. 제일 먼저 프로젝트를 생성해야 한다. 새 프로젝트 만들기 단축 아이콘을 클릭하면 다음과 같은 창이 뜬다. 여기서 [New GTK+Project]를 클릭한 후 저장 아이콘을 클릭한다. 다음과 같이 프로젝트 옵션 창이 뜰 것이다

166 원하는 프로젝트 디렉토리와 프로젝트명, 프로그램명 그리고 생성할 Glade 파일을 지정하고 C 옵션 탭으로 이동한다. 일반 옵션에서 [Gettext 지원] 체크를 해제한다. 마지막으로 [확인]을 클릭하면 초기 설정한 프로젝트 명으로 프로젝트가 생성된다. 이제 GTK Painter의 기본 틀과 더불어 위젯들을 생성시켜 보자. 먼저 프로그램의 메인 윈도우를 생성해야 한다. 팔레트에서 윈도우 아이콘을 선택하면 아래와 같이 윈도우 창이 생성된다

167 윈도우 창 자체가 하나의 위젯이 되는 것이다. 생성을 했으니 이제 꾸며 보자. 그 전에 오브젝트 창에서 위젯의 속성을 확인하고 수정할 부분은 수정해야 한다. 오브젝트 창(소유물)은 다음과 같다. [Common] 탭으로 이동을 해보자. 다음과 같이 너비와 높이, 이벤트 등을 설정할 수 있다

168 이벤트의 [...]를 클릭하게 되면 X이벤트 선택 창이 뜨게 된다. 다음은 X이벤트를 선택하는 장면이다. X이벤트 선택 창에서 필요한 이벤트들을 선택한다. [Ctrl] 키를 누르고 마우스 클릭하면 복수 선택이 가능하다. 자세한 X이벤트의 내용들은 GTK+ 레퍼런스 문서를 참조하기 바란다. 위에서 선택한 이벤트 들은 일반적으로 선택이 되는 이벤트 들이다. 보통 마우스 또는 터치로 이벤트를 발생시키기 때문에 거의 필수로 선택된다고 해도 과언이 아니다. 선택된 X이벤트 들은 시그널을 통해 콜백함수를 호출하게 될 것이다

169 다음 [시그널] 탭으로 이동해 본다. 시그널 탭의 모습은 다음과 같다. 시그널 오른쪽의 [...]을 클릭하면 시그널 선택 창이 뜨게 된다. 다음은 시그널 선택 창이다. 시그널은 어떠한 해당 이벤트가 발생했을 시 GTK+에서 해당 함수가 실행되게끔 하는 하나의 전 달 매개체라고 보면 된다. 다음과 같이 등록 창에 선택한 시그널이 등록되었다. 아래 화면은 destroy 시그널을 등록한 하나의 예시이다. destroy 시그널은 해당 위젯이 종료될 때 발생하는 시그널이다

170 마지막으로 팔레트 창에서 [고정된 구역] 아이콘을 클릭한 후 윈도우 창에 클릭한다. 윈도우 창이 활성화된 것을 확인할 수 있다. 이제 윈도우 창 위에 버튼이나 그림구역, 라벨, 콤보박스 등을 올릴 수 있는 상태가 된 것이다. 빌드 버튼을 클릭하고 저장을 하고 프로그램을 종료시킨다. 저장한 장소로 이동을 하면 프로젝트명으로 된 디렉토리에 환경설정 파일과 src 디렉토리가 생 성되어 있는 것을 확인할 수 있다. 이것으로 Glade-2 유틸리티를 이용한 GTK+ 프로그래밍의 기본 방법을 알아보았다. 이 후부터는 자기 입맛에 맞게 폼을 구성하고 GUI를 작성하면 된다. GTK Painter 어플리케이션 또한 Glade-2 유틸리티를 이용해서 기본 인터페이스를 작성을 하였 다. 3. S/W 설계 GTK Painter에 대해 소개하도록 하겠다. 3.1 GTK Painter 특징 기능 - 팬 브러쉬 기능 - 색상 선택 기능 - 팬 굵기 선택 기능 - 그림판 리셋 기능 사용된 위젯 - 윈도우 스크린 - 그리기 영역 - 가로 분리선

171 - 일반 버튼 - 스핀버튼 - 칼라버튼 - 라벨 사용된 이벤트 - GDK_BUTTON1_MOTION_MASK : 마우스 1버튼(왼쪽 버튼)의 클릭상태에서 움직일 때 - GDK_BUTTON_PRESS_MASK : 마우스 버튼이 눌러졌을 때 - GDK_BUTTON_RELEASE_MASK : 마우스 버튼이 때어졌을 때 사용된 시그널 - 윈도우 위젯 => destroy - 그리기 영역 위젯 button_press_event : 버튼이 눌러졌을 때 발생 button_release_event : 버튼이 때어졌을 때 motion_notify_event : 마우스를 움직였을 때 expose_event : 화면이 보여질 때 configure_event : 위젯이 화면에 뜨기 전 clicked : 버튼을 클릭했을 때 value_changed : 스핀버튼에서 선택 값이 변경되었을 때 color_set : 색상을 선택했을 때 3.2 구조 GTK+로 작성된 프로그램들은 X윈도우 기반에서 실행이 된다

172 GTK Painter는 터치를 이용하여 조작하게 되며, 입력된 터치 신호는 X윈도우를 거처 어플리케이 션으로 전달되며 처리된 결과는 X윈도우에서 다시 프레임버퍼 영역으로 결과를 디스플레이 하게 된다. 즉 터치를 이용하여 드레그하면 드fp그되는 영역이 선으로 그려지게 되는 것이다. 3.3 동작 방법 Color 버튼 : 16K의 색상을 선택할 수 있는 Color Map이 창으로 뜨며 원하는 선 색을 선택 할 수 있다. Pitch 스핀버튼 : 1부터 10까지 선의 굵기를 정할 수 있다. RESET 버튼 : 현재까지 그려진 그림을 지우고자 할 때 클릭을 하면 그림영역이 초기화된다. 4. S/W 구현 GTK Painter 소스 코드 Glade-2를 이용하여 프로젝트를 생성하고 빌드하게 되면 src 디렉토리에 4개의 소스파일이 생 성된다. 4개의 소스파일은 다음과 같다. - main.c : 메인함수로 GTK 초기화 밑 최상의 윈도우 위젯을 생성하고 GTK 프로그램의 시작 을 알린다. - interface.c : 위젯 생성 및 시그널 연결을 설정한다. - support.c : 위젯 호출 및 픽스맵 생성 함수의 정의가 작성되어 있다. - callback.c : 이벤트가 발생했을 때 호출되는 해당 함수가 비어있는 상태로 정의되어 있다. 이 부분이 사용자가 직접 코딩하고 기능을 구현해야할 핵심 부분이다. main.h 전역변수로 GC(PEN 설정 구조체) 포인터와 임시로 사용할 위젯을 선언하였다. GdkGC *g_pen; GtkWidget *drawing_handle;

173 main.c #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <gtk/gtk.h> #include "interface.h" #include "support.h" #include "main.h" // main.h 헤더 선언 int main (int argc, char *argv[]) { GtkWidget *window1; gtk_set_locale (); gtk_init (&argc, &argv); // locale 설정 // GTK 초기화 add_pixmap_directory (PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); /* * The following code was added by Glade to create one of each component * (except popup menus), just so that you see something after building * the project. Delete any components that you don't want shown initially. */ window1 = create_window1 (); // window 위젯 생성 gtk_widget_show (window1); // window 창을 스크린에 보여줌 // window 위젯에 대한 임시 핸들러를 생성 drawing_handle = lookup_widget(gtk_widget(window1), "drawingarea1"); gtk_widget_set_uposition (window1, 1, 0); gtk_main (); return 0; // GTK 어플리케이션 시작 Glade-2로 위젯을 생성하고 빌드하게 되면 기본적으로 위와 같은 코드가 생성된다. 밑줄 친 부 분은 직접 추가한 부분이다

174 interface.c 주요 코드 GtkWidget* create_window1 (void) // window 위젯과 하위 위젯들을 생성하기 위한 함수 { // 위젯 선언 GtkWidget *window1; GtkWidget *fixed1; GtkWidget *drawingarea1; GtkWidget *hseparator1; GtkWidget *label1; GtkWidget *label2; GtkWidget *button1; GtkWidget *button2; GtkObject *spinbutton1_adj; GtkWidget *spinbutton1; GtkWidget *colorbutton1; GdkColor white = {0, 0xFFFF, 0xFFFF, 0xFFFF; window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL); // window 위젯 생성 gtk_widget_set_size_request (window1, 800, 480); gtk_window_set_title (GTK_WINDOW (window1), "GTK_Painter"); gtk_window_set_position (GTK_WINDOW (window1), GTK_WIN_POS_CENTER_ALWAYS); gtk_window_set_resizable (GTK_WINDOW (window1), FALSE); gtk_window_set_type_hint (GTK_WINDOW (window1), GDK_WINDOW_TYPE_HINT_UTILITY); fixed1 = gtk_fixed_new (); // 고정영역 위젯 생성 gtk_widget_show (fixed1); gtk_container_add (GTK_CONTAINER (window1), fixed1); drawingarea1 = gtk_drawing_area_new (); // 그리기 영역 위젯 생성 gtk_widget_show (drawingarea1); gtk_fixed_put (GTK_FIXED (fixed1), drawingarea1, 0, 56); gtk_widget_set_size_request (drawingarea1, 800, 424); // 그리기 영역 위젯에서 발생할 이벤트 설정 gtk_widget_set_events (drawingarea1, GDK_BUTTON1_MOTION_MASK GDK_BUTTON_PRESS_MASK GDK_BUTTON_RELEASE_MASK); hseparator1 = gtk_hseparator_new (); // 가로 분리선 위젯 생성 gtk_widget_show (hseparator1); gtk_fixed_put (GTK_FIXED (fixed1), hseparator1, 0, 40); gtk_widget_set_size_request (hseparator1, 800, 16);

175 label1 = gtk_label_new ("Color :"); // 라벨 위젯 생성 gtk_widget_show (label1); gtk_fixed_put (GTK_FIXED (fixed1), label1, 0, 8); gtk_widget_set_size_request (label1, 50, 30); label2 = gtk_label_new ("Pitch :"); // 라벨 위젯 생성 gtk_widget_show (label2); gtk_fixed_put (GTK_FIXED (fixed1), label2, 96, 8); gtk_widget_set_size_request (label2, 50, 30); button1 = gtk_button_new_with_mnemonic ("RESET"); // 일반 버튼 위젯 생성 gtk_widget_show (button1); gtk_fixed_put (GTK_FIXED (fixed1), button1, 744, 8); gtk_widget_set_size_request (button1, 50, 30); button2 = gtk_button_new_with_mnemonic ("QUIT"); gtk_widget_show (button2); gtk_fixed_put (GTK_FIXED (fixed1), button2, 680, 8); gtk_widget_set_size_request (button2, 50, 30); // 일반 버튼 위젯 생성 // 스핀 버튼 위젯 생성 spinbutton1_adj = gtk_adjustment_new (1, 1, 10, 1, 10, 10); spinbutton1 = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton1_adj), 1, 0); gtk_widget_show (spinbutton1); gtk_fixed_put (GTK_FIXED (fixed1), spinbutton1, 144, 8); gtk_widget_set_size_request (spinbutton1, 40, 30); // 칼라 버튼 위젯 생성 colorbutton1 = gtk_color_button_new_with_color (&white); // 초기 칼라 설정 gtk_widget_show (colorbutton1); gtk_fixed_put (GTK_FIXED (fixed1), colorbutton1, 48, 8); gtk_widget_set_size_request (colorbutton1, 40, 30); gtk_color_button_set_title (GTK_COLOR_BUTTON (colorbutton1), "Select the color"); gtk_fixed_put() 함수는 위젯의 이름과 고정된 영역에 위젯을 위치시킬 오프셋을 설정하는 함수 이다. gtk_widget_set_size_request() 함수는 해당 위젯의 사이즈를 설정하는 함수이다. 칼라 버튼 위젯 생성에서 초기 상태로 흰색이 선택되도록 API를 변경하였다

176 g_signal_connect ((gpointer) window1, "destroy", G_CALLBACK (on_window1_destroy), NULL); g_signal_connect ((gpointer) drawingarea1, "button_press_event", G_CALLBACK (on_drawingarea1_button_press_event), NULL); g_signal_connect ((gpointer) drawingarea1, "button_release_event", G_CALLBACK (on_drawingarea1_button_release_event), NULL); g_signal_connect ((gpointer) drawingarea1, "motion_notify_event", G_CALLBACK (on_drawingarea1_motion_notify_event), NULL); g_signal_connect ((gpointer) drawingarea1, "expose_event", G_CALLBACK (on_drawingarea1_expose_event), NULL); g_signal_connect ((gpointer) drawingarea1, "configure_event", G_CALLBACK (on_drawingarea1_configure_event), NULL); g_signal_connect ((gpointer) button1, "clicked", G_CALLBACK (on_button1_clicked), NULL); g_signal_connect ((gpointer) spinbutton1, "value_changed", G_CALLBACK (on_spinbutton1_value_changed), NULL); g_signal_connect ((gpointer) colorbutton1, "color_set", G_CALLBACK (on_colorbutton1_color_set), NULL); g_signal_connect ((gpointer) button2, "clicked", G_CALLBACK (on_button2_clicked), NULL); /* Store pointers to all widgets, for use by lookup_widget(). */ GLADE_HOOKUP_OBJECT_NO_REF (window1, window1, "window1"); GLADE_HOOKUP_OBJECT (window1, fixed1, "fixed1"); GLADE_HOOKUP_OBJECT (window1, drawingarea1, "drawingarea1"); GLADE_HOOKUP_OBJECT (window1, hseparator1, "hseparator1"); GLADE_HOOKUP_OBJECT (window1, label1, "label1"); GLADE_HOOKUP_OBJECT (window1, label2, "label2"); GLADE_HOOKUP_OBJECT (window1, button1, "button1"); GLADE_HOOKUP_OBJECT (window1, spinbutton1, "spinbutton1"); GLADE_HOOKUP_OBJECT (window1, colorbutton1, "colorbutton1"); GLADE_HOOKUP_OBJECT (window1, button2, "button2"); return window1; g_signal_connect() 함수는 시그널 발생 시 해당 콜백함수로 연결되도록 설정하는 함수이다

177 callback.c #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <gtk/gtk.h> #include "callbacks.h" #include "interface.h" #include "support.h" #include "main.h" // main.h 헤더파일 선언 GdkPixmap *pixmap = NULL; // Pixmap 구조체 포인터 선언 GdkColor white = {0, 0xffff, 0xffff, 0xffff; int prex = 0; int prey = 0; void // 메인 window 종료시 호출되는 함수 on_window1_destroy (GtkObject *object, gpointer user_data) { // 할당했던 color 및 pen의 메모리 해제 gdk_colormap_free_colors(gdk_colormap_get_system(), &white, sizeof(white)); gdk_gc_unref(g_pen); exit(0); gboolean // 버튼을 눌렀을 때 호출되는 함수 on_drawingarea1_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if(prex == 0 prey == 0 ){ // 최초 버튼을 눌렀을 때 prex = event->x; // 현재의 X 좌표를 저장 prey = event->y; // 현재의 Y 좌표를 저장 gdk_draw_line (widget->window, g_pen, prex, prey, event->x, event->y); gdk_draw_line (pixmap, g_pen, prex, prey, event->x, event->y); gtk_object_set_data(gtk_object(widget), "pixmap", pixmap); return FALSE;

178 gdk_draw_line() 함수를 이용하여 현재 좌표의 위치에 점을 찍는다. gdk_draw_line() 함수 두 개를 호출하였는데 전자는 widget->window에 그려서 실제 window 창 에 보이게 하는 것이고, 후자는 pixmap에 그리는 것이다. pixmap에 그리는 이유는 그리기 영역 을 다른 창이 가리거나 했을 때 핸들을 잃어버리게 되는데 이 때 다시 복구시키기 위해 pixmap 에 임시로 그리고 gtk_object_set_data()를 통해 저장하는 것이다. gboolean // 버튼을 땠을 때 호출되는 함수 on_drawingarea1_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { prex = 0; prex = 0; // 좌표 초기화 return FALSE; gboolean // 마우스 클릭 상태에서 드레그 했을 때 호출되는 함수 on_drawingarea1_motion_notify_event (GtkWidget *widget, GdkEventMotion *event, gpointer user_data) { // 이전 좌표에서 현재 좌표까지 선을 그린다. gdk_draw_line (widget->window, g_pen, prex, prey, event->x, event->y); // pixmap에 선을 그린다. gdk_draw_line (pixmap, g_pen, prex, prey, event->x, event->y); gtk_object_set_data(gtk_object(widget), "pixmap", pixmap); prex = event->x; // 현재 X좌표를 이전 X좌표에 저장 prey = event->y; // 현재 Y좌표를 이전 Y좌표에 저장 return FALSE; gboolean // 윈도우에 항상 보여질 때 마다 호출되는 함수 on_drawingarea1_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { gdk_draw_rectangle(widget->window, widget->style->black_gc, TRUE, 0, 0, 800, 424); // 그리기 영역을 검정색으로 초기화 한다. // pixmap에 저장되어 있던 그림을 window에 그린다. gdk_draw_pixmap(widget->window, g_pen, pixmap, 0, 0, 0, 0, 800, 424); return FALSE;

179 on_drawingarea1_expose_event() 콜백함수 처럼 pixmap에 저장되어 있던 그림들을 window에 나타냄으로써 핸들을 잃어버려도 바로 복구되도록 처리하였다. gboolean // 윈도우 창이 뜨기 전 호출되는 함수 (최초의 한번만 호출) on_drawingarea1_configure_event (GtkWidget *widget, GdkEventConfigure *event, gpointer user_data) { gint x_size, y_size; x_size = widget->allocation.width; y_size = widget->allocation.height; // pixmap 생성 pixmap = gdk_pixmap_new (widget->window, x_size, y_size, -1); g_pen = gdk_gc_new(widget->window); // GC 생성 gdk_colormap_alloc_color(gdk_colormap_get_system(), &white, FALSE, TRUE); gdk_gc_set_foreground(g_pen, &white); gdk_gc_set_line_attributes(g_pen, 1, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); return FALSE; void // 칼라 버튼에서 색상을 지정할 때 호출되는 함수 on_colorbutton1_color_set (GtkColorButton *colorbutton, gpointer user_data) { GdkColor *color = g_malloc(sizeof(gdkcolor)); memset(color, 0, sizeof(gdkcolor)); gtk_color_button_get_color(colorbutton, color); gdk_colormap_alloc_color(gdk_colormap_get_system(), color, FALSE, TRUE); gdk_gc_set_foreground(g_pen, color); void // 버튼 클릭 시 호출되는 함수 on_button1_clicked (GtkButton *button, gpointer user_data) { gdk_draw_rectangle(pixmap, drawing_handle->style->black_gc, TRUE, 0, 0, 800, 424); gdk_draw_pixmap(drawing_handle->window, g_pen, pixmap, 0, 0, 0, 0, 800, 424);

180 on_drawingarea1_configure_event() 콜백함수에서 처음 윈도우가 뜨기 전에 한 번 호출되는 함 수로 다음과 같은 초기화 관련 내용들이 작성되어 있다. - Pixmap을 생성 - GC 핸들을 생성 - 초기에 사용할 색상 설정 (팬 브러쉬 색상) - GC 속성 설정 생성한 위젯 버튼인 RESET 버튼을 클릭하게 되면 on_button1_clicked() 콜백함수가 호출되는데 이 때 배경색을 검정색으로 초기화 하게 된다. void // 스핀 버튼의 값이 변경될 시 호출되는 함수 on_spinbutton1_value_changed (GtkSpinButton *spinbutton, gpointer user_data) { gint value; value = gtk_spin_button_get_value_as_int(spinbutton); // 스핀 버튼의 값을 저장 gdk_gc_set_line_attributes(g_pen, value, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND); // 스핀 버튼의 값을 GC의 라인 굵기에 반영한다. void on_button2_clicked (GtkButton *button, gpointer user_data) { gdk_colormap_free_colors(gdk_colormap_get_system(), &white, sizeof(white)); gdk_gc_unref(g_pen); exit(0); 스핀 버튼을 이용하여 1부터 10까지 값을 조절할 수 있는데 이 때 값이 변경될 때마다 호출되는 함수이다. 값이 변경되었을 때 변경된 값을 value 변수에 저장하여 GC의 라인 속성 설정에서 변경되도록 반영을 한다. 마지막으로 종료 버튼을 클릭 시 프로그램은 종료된다

181 5. 수행 방법 및 결과 5.1 수행 방법 직접 프로젝트를 리눅스가 설치된 사용자 PC에서 생성하였다면 생성시킨 프로젝트 디렉토리 로 이동하여 autogen.sh 쉘 스크립트 파일을 실행한 후 ARM용 컴파일을 구축하기위해 configure 파일을 실행하고, make 명령어를 입력하여 컴파일을 한다. 과정이 어렵고 이해가 안된다면 미리 만들어 놓은 config-arm 쉘 스크립트 파일을 참조하도록 한다. 만일 CD에서 제공하는 완성된 GTK_Painter 를 그대로 사용하길 원한다면 /root/320app/application/gtk_painter로 이동한다. ]# cd /root/320app/application/gtk_painter 미리 만들어 놓은 config-arm 쉘 스크립트 파일을 실행한다. ]#./config-arm make 명령어를 입력한다. ]# make 하위 src 디렉토리로 이동한다. ]# cd src/ gtk_painter 실행파일을 타겟보드로 다운로드한다. 다운로드 방법은 Z-MODEM 을 이용한 시 리얼 다운로드, NFS 마운트를 이용한 다운로드, FTP를 이용한 다운로드가 있는데, 사용자가 익 숙한 방법을 사용하면 된다. 타겟보드에서 startx 명령어를 입력한 후 gtk_painter 파일을 실행한다. 320TKU]# startx 320TKU]#./gtk_painter 터치를 이용하여 직접 그림을 그려보고 칼라버튼을 클릭하면 나타나는 색상선택 창에서 마음 에 드는 색을 선택해서 그려보기도 하고 스핀버튼을 이용하여 Pitch를 변경한 후 그림을 그려본 다. RESET 버튼을 클릭했을 시 그림영역이 초기화 되는지 확인한다

182 5.2 수행 결과 시작 화면 그리기 화면

183 색상 변경 화면 16K의 색상을 지정할 수 있다. 색상 변경 후 그리기 화면

184 Pitch 변경 후 그리기 화면

185 Chapter 9. PXA Camera 1. 개요 본 프로그램은 X-HYPER320TKU 보드에 Hybus CMOS Camera 모듈을 부착하여 Camera에서 영상을 인식하여 TFT-LCD에 스크린해주는 프로그램이다. 이 프로그램은 Marvell사에서 제공해 준 Camera 제어용 프로그램으로 기본적으로 CMOS Camera 제어를 위해서 어떻게 구성되어 있 고 구현되어 있는지를 잘 보여주는 좋은 예제라고 할 수 있다. 2. 관련기술 2.1 V4L2 인터페이스 V4L은 리눅스를 위한 비디오 캡처 어플리케이션 프로그래밍 인터페이스이다. 아날로그 라디오와 비디오 캡처, 출력 드라이버들을 위한 커널 인터페이스라고 할 수 있다. V4L은 리눅스 커널에 포함되어있으며, 여러 가지의 USB 웹캠, TV 튜너, 그 밖에 다른 비디오 장치들을 지원한다. V4L2는 V4L의 그 두 번째 버전으로 기존의 V4L과 호환성을 가지며 V4L과는 다르게 Multiple 오 픈을 지원한다. V4L2 디바이스 프로그래밍 단계 - 디바이스 오픈 - 디바이스 속성 변경 및 비디오와 오디오 입력, 비디오 표준, 명도, 채도 등을 선택 - 데이터 포맷 결정 - 입출력 방식 결정 - 실제 입출력 루프 코딩 - 디바이스 클로즈 V4L2 IOCTL 커맨드 V4L2 디바이스를 제어하기 위해서는 ioctl API를 이용해야하며 V4L2의 ioctl 커맨드들은 다음과 같다. 커맨드에 대한 정의는 리눅스 커널의 include/linux/videodev2.h에서 찾아볼 수 있다. 커맨드의 자세한 설명들은 V4L2 API 명세서를 참조하기 바란다. 문서의 위치는 다음과 같다

186 #define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) #define VIDIOC_RESERVED _IO ('V', 1) #define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) #define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) #define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) #define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression) #define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression)

187 #define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) #define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) #define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) #define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) #define VIDIOC_OVERLAY _IOW ('V', 14, int) #define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) #define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) #define VIDIOC_STREAMON _IOW ('V', 18, int) #define VIDIOC_STREAMOFF _IOW ('V', 19, int) #define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) #define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) #define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) #define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) #define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) #define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) #define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) #define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) #define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) #define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) #define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) #define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) #define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) #define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) #define VIDIOC_G_INPUT _IOR ('V', 38, int) #define VIDIOC_S_INPUT _IOWR ('V', 39, int) #define VIDIOC_G_OUTPUT _IOR ('V', 46, int) #define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) #define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) #define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) #define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) #define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) #define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) #define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency) #define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency) #define VIDIOC_CROPCAP _IOWR ('V', 58, struct v4l2_cropcap) #define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop) #define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) #define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) #define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) #define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) #define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format)

188 #define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) #define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) #define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority) #define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority) #if 1 #define VIDIOC_G_SLICED_VBI_CAP _IOR ('V', 69, struct v4l2_sliced_vbi_cap) #endif ioctl을 이용한 비디오 디바이스를 제어하는 여러 예제들을 살펴보도록 하겠다. Video Inputs and Outputs 다음은 현재 비디오의 입력에 대한 정보를 가져오는 예문이다. struct v4l2_input input; int index; if (-1 == ioctl (fd, VIDIOC_G_INPUT, &index)) { perror ("VIDIOC_G_INPUT"); exit (EXIT_FAILURE); memset (&input, 0, sizeof (input)); input.index = index; if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) { perror ("VIDIOC_ENUMINPUT"); exit (EXIT_FAILURE); printf ("Current input: %s n", input.name); 다음은 첫 번째 비디오 입력을 스위칭하는 예문이다. int index; index = 0; if (-1 == ioctl (fd, VIDIOC_S_INPUT, &index)) { perror ("VIDIOC_S_INPUT"); exit (EXIT_FAILURE);

189 Audio Inputs and Outputs 이번에는 현재 오디오 입력에 대한 정보를 가져오는 예문이다. struct v4l2_audio audio; memset (&audio, 0, sizeof (audio)); if (-1 == ioctl (fd, VIDIOC_G_AUDIO, &audio)) { perror ("VIDIOC_G_AUDIO"); exit (EXIT_FAILURE); printf ("Current input: %s n", audio.name); 마찬가지로 첫 번째 오디오 입력을 스위칭 하는 예문이다. struct v4l2_audio audio; memset (&audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */ audio.index = 0; if (-1 == ioctl (fd, VIDIOC_S_AUDIO, &audio)) { perror ("VIDIOC_S_AUDIO"); exit (EXIT_FAILURE); Video Standards 다음은 현재 비디오 표준에 대한 정보를 가져오는 예문이다. v4l2_std_id std_id; struct v4l2_standard standard; if (-1 == ioctl (fd, VIDIOC_G_STD, &std_id)) { /* Note when VIDIOC_ENUMSTD always returns EINVAL this is no video device or it falls under the USB exception, and VIDIOC_G_STD returning EINVAL is no error. */ perror ("VIDIOC_G_STD"); exit (EXIT_FAILURE); memset (&standard, 0, sizeof (standard)); standard.index = 0; while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) { if (standard.id & std_id) { printf ("Current video standard: %s n", standard.name); exit (EXIT_SUCCESS); standard.index++;

190 /* EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception. */ if (errno == EINVAL standard.index == 0) { perror ("VIDIOC_ENUMSTD"); exit (EXIT_FAILURE); 다음은 현재 비디오 입력으로 지원되는 비디오 표준을 나열하는 예문이다. struct v4l2_input input; struct v4l2_standard standard; memset (&input, 0, sizeof (input)); if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) { perror ("VIDIOC_G_INPUT"); exit (EXIT_FAILURE); if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) { perror ("VIDIOC_ENUM_INPUT"); exit (EXIT_FAILURE); printf ("Current input %s supports: n", input.name); memset (&standard, 0, sizeof (standard)); standard.index = 0; while (0 == ioctl (fd, VIDIOC_ENUMSTD, &standard)) { if (standard.id & input.std) printf ("%s n", standard.name); standard.index++; /* EINVAL indicates the end of the enumeration, which cannot be empty unless this device falls under the USB exception. */ if (errno!= EINVAL standard.index == 0) { perror ("VIDIOC_ENUMSTD"); exit (EXIT_FAILURE); 마지막으로 새로운 비디오 표준을 선택하여 설정하는 예문이다. struct v4l2_input input; v4l2_std_id std_id; memset (&input, 0, sizeof (input)); if (-1 == ioctl (fd, VIDIOC_G_INPUT, &input.index)) { perror ("VIDIOC_G_INPUT"); exit (EXIT_FAILURE);

191 if (-1 == ioctl (fd, VIDIOC_ENUMINPUT, &input)) { perror ("VIDIOC_ENUM_INPUT"); exit (EXIT_FAILURE); if (0 == (input.std & V4L2_STD_PAL_BG)) { fprintf (stderr, "Oops. B/G PAL is not supported. n"); exit (EXIT_FAILURE); /* Note this is also supposed to work when only B or G/PAL is supported. */ std_id = V4L2_STD_PAL_BG; if (-1 == ioctl (fd, VIDIOC_S_STD, &std_id)) { perror ("VIDIOC_S_STD"); exit (EXIT_FAILURE); User Controls 비디오 디바이스들은 명도나 채도, 투명도 같은 세부사항들을 설정할 수 있다. 이와 같은 설정을 하기 위해서는 Control ID라는 것들이 필요하다. Control ID들을 ioctl에서 V4L2 제어 커맨드 다 음 인자 값으로 받아들이게 된다. 다음은 Control ID들에 대한 테이블이다. V4L2_CID_BASE V4L2_CID_USER_BASE V4L2_CID_BRIGHTNESS V4L2_CID_CONTRAST V4L2_CID_SATURATION V4L2_CID_HUE V4L2_CID_AUDIO_VOLUME V4L2_CID_AUDIO_BALANCE V4L2_CID_AUDIO_BASS V4L2_CID_AUDIO_TREBLE V4L2_CID_AUDIO_MUTE V4L2_CID_AUDIO_LOUDNESS V4L2_CID_BLACK_LEVEL V4L2_CID_AUTO_WHITE_BALANCE V4L2_CID_DO_WHITE_BALANCE V4L2_CID_RED_BALANCE V4L2_CID_BLUE_BALANCE V4L2_CID_GAMMA V4L2_CID_WHITENESS V4L2_CID_EXPOSURE V4L2_CID_AUTOGAIN V4L2_CID_GAIN integer integer integer integer integer integer integer integer boolean boolean integer boolean button integer integer integer integer integer boolean integer

192 V4L2_CID_HFLIP V4L2_CID_VFLIP V4L2_CID_HCENTER_DEPRECATED V4L2_CID_VCENTER_DEPRECATED V4L2_CID_POWER_LINE_FREQUENCY V4L2_CID_HUE_AUTO V4L2_CID_WHITE_BALANCE_TEMPERTURE V4L2_CID_SHARPNESS V4L2_CID_BACKLIGHT_COMPENSATION V4L2_CID_LASTP1 V4L2_CID_PRIVATE_BASE boolean boolean integer integer integer boolean integer integer integer VIDIOC_QUERYCTRL과 VIDIOC_QUERYMENE ioctl을 이용하여 어플리케이션 레벨에서 해당 비 디오 장치로 제어가 가능한 Control들을 나열할 수 있고, VIDIOC_G_CTRL과 VIDIOC_S_CTRL을 이용하여 비디오 장치의 Control 값을 가져오거나 설정할 수 있다. 다음은 모든 Control들을 열거하는 예문이다. struct v4l2_queryctrl queryctrl; struct v4l2_querymenu querymenu; static void enumerate_menu (void) { printf (" Menu items: n"); memset (&querymenu, 0, sizeof (querymenu)); querymenu.id = queryctrl.id; for (querymenu.index = queryctrl.minimum; querymenu.index <= queryctrl.maximum; querymenu.index++) { if (0 == ioctl (fd, VIDIOC_QUERYMENU, &querymenu)) { printf (" %s n", querymenu.name); else { perror ("VIDIOC_QUERYMENU"); exit (EXIT_FAILURE); memset (&queryctrl, 0, sizeof (queryctrl)); for (queryctrl.id = V4L2_CID_BASE; queryctrl.id < V4L2_CID_LASTP1; queryctrl.id++) { if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; printf ("Control %s n", queryctrl.name); if (queryctrl.type == V4L2_CTRL_TYPE_MENU) enumerate_menu (); else { if (errno == EINVAL) continue; perror ("VIDIOC_QUERYCTRL"); exit (EXIT_FAILURE);

193 for (queryctrl.id = V4L2_CID_PRIVATE_BASE;; queryctrl.id++) { if (0 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) continue; printf ("Control %s n", queryctrl.name); if (queryctrl.type == V4L2_CTRL_TYPE_MENU) enumerate_menu (); else { if (errno == EINVAL) break; perror ("VIDIOC_QUERYCTRL"); exit (EXIT_FAILURE); 다음은 Control들을 변경하는 예문이다. struct v4l2_queryctrl queryctrl; struct v4l2_control control; memset (&queryctrl, 0, sizeof (queryctrl)); queryctrl.id = V4L2_CID_BRIGHTNESS; if (-1 == ioctl (fd, VIDIOC_QUERYCTRL, &queryctrl)) { if (errno!= EINVAL) { perror ("VIDIOC_QUERYCTRL"); exit (EXIT_FAILURE); else { printf ("V4L2_CID_BRIGHTNESS is not supported n"); else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { printf ("V4L2_CID_BRIGHTNESS is not supported n"); else { memset (&control, 0, sizeof (control)); control.id = V4L2_CID_BRIGHTNESS; control.value = queryctrl.default_value; if (-1 == ioctl (fd, VIDIOC_S_CTRL, &control)) { perror ("VIDIOC_S_CTRL"); exit (EXIT_FAILURE); memset (&control, 0, sizeof (control)); control.id = V4L2_CID_CONTRAST; if (0 == ioctl (fd, VIDIOC_G_CTRL, &control)) { control.value += 1; /* The driver may clamp the value or return ERANGE, ignored here */

194 if (-1 == ioctl (fd, VIDIOC_S_CTRL, &control) && errno!= ERANGE) { perror ("VIDIOC_S_CTRL"); exit (EXIT_FAILURE); /* Ignore if V4L2_CID_CONTRAST is unsupported */ else if (errno!= EINVAL) { perror ("VIDIOC_G_CTRL"); exit (EXIT_FAILURE); control.id = V4L2_CID_AUDIO_MUTE; control.value = TRUE; /* silence */ /* Errors ignored */ ioctl (fd, VIDIOC_S_CTRL, &control); 3. S/W 설계 3.1 기능 Camera 프로그램의 기능은 다음과 같이 요약할 수 있다. - V4l2 Video Format 지원 - YCBCR422 Pixel Format 지원 - PXA Overlay-2 사용 - Video Handling - 640x480 Mode 지원 - OV7660 CMOS Sensor 지원 3.2 구조 콘솔기반의 PXA Camera 프로그램은 다음과 같은 구조로 되어 있다

195 하드웨어 인터페이스를 통해 CMOS Camera와 연결되고 어플리케이션 레벨에서 ioctl을 통해 V4L2 인터페이스로 비디오 드라이버에 접근하여 제어할 수 있다. CMOS Camera에서 감지되는 영상 신호들은 비디오 디바이스의 데이터 포맷(YCBCR422)으로 변환되어 오버레이2로 전달되고 TFT-LCD에 디스플레이한다. 4. S/W 구현 PXA Camera 소스 코드 Camera 프로그램은 어플리케이션과 라이브러리 파트로 나눠져 있다. 라이브러리 파트는 Camera와 Overlay-2의 제어를 위한 API로 구성되어 있고 어플리케이션 파트는 만들어진 API들 을 토대로 Camera 프로그램으로 작성되어 있다. 어플리케이션 : camera.c - camera.c 주요 코드 int main(int argc, char* argv[]) { int handle; int handle_overlay2; struct pxa_video_buf* vidbuf; struct pxacam_setting camset; struct pxa_video_buf vidbuf_overlay; int len; handle = camera_open(null, OV7660_SENSOR); // Camera 오픈 함수 memset(&camset,0,sizeof(camset)); camset.mode = CAM_MODE_VIDEO; // CAM Mode camset.format = pxavid_ycbcr422; // YCBCR422 Pixel Format camset.width = 640; camset.height = 480; camera_config(handle,&camset); // Camera 설정 함수 camera_start(handle); // Camera 동작 시작 handle_overlay2 = overlay2_open(null,pxavid_ycbcr422,null, 640, 480, 80, 0);

196 overlay2_getbuf(handle_overlay2,&vidbuf_overlay); len = vidbuf_overlay.width*vidbuf_overlay.height; while(1){ vidbuf = camera_get_frame(handle); // Frame 읽어오기 // TFT-LCD에 Pixel 데이터를 출력 memcpy(vidbuf_overlay.ycbcr.y, vidbuf->ycbcr.y,len); memcpy(vidbuf_overlay.ycbcr.cb, vidbuf->ycbcr.cb,len/2); memcpy(vidbuf_overlay.ycbcr.cr, vidbuf->ycbcr.cr,len/2); camera_release_frame(handle,vidbuf); camera_stop(handle); camera_close(handle); return 0; // Camera 동작 정지 라이브러리 : camera_lib.c, overlay2.c - camera_lib.c // VIDEOBUF_COUNT must be larger than STILLBUF_COUNT #define VIDEOBUF_COUNT 3 #define STILLBUF_COUNT 2 #define CAM_STATUS_INIT 0 #define CAM_STATUS_READY 1 #define CAM_STATUS_BUSY 2 struct pxa_camera{ // PXA Camera 구조체 int handle; // 핸들 int status; // 상태정보 int mode; // 비디오 모드 int sensor; // CMOS 센서 int ref_count; // Video Buffer int width; int height; enum pxavid_format format; // 픽셀 포맷 struct videobuf_dev cambuf[videobuf_count];;

197 int camera_open(char* camname,int sensor) { int handle; struct pxa_camera* camobj = NULL; // Camera 오픈 함수 if(camname==null){ camname="/dev/video0"; // Video 오픈 디바이스명 handle = open(camname, O_RDONLY); // video0 오픈 if (handle<0) { ERRMSG("cann't open camera %s (%d) n",camname,errno); ASSERT(handle>=0); return 0; // CMOS Sensor 설정 - OV7660 if(ioctl(handle, VIDIOC_S_INPUT, &sensor)<0) { ERRMSG("can't set input n"); close(handle); return 0; // Initialize camera object camobj = malloc(sizeof(struct pxa_camera)); memset(camobj,0,sizeof(struct pxa_camera)); ASSERT(camobj); camobj->handle = handle; camobj->status = CAM_STATUS_READY; camobj->width = 0; camobj->height = 0; camobj->sensor = sensor; ASSERT(sizeof(int)==sizeof(struct pxa_camera*)); return (int)camobj;

198 // Camera Configuration int camera_config(int hcam,struct pxacam_setting* setting) { // V4L2 Interface struct v4l2_format vformat; struct v4l2_streamparm streamparm; struct v4l2_requestbuffers requestbuffers; struct v4l2_buffer buffer; struct pxa_camera* camera; void *pmapped = NULL; int count,i; int mode; enum pxavid_format format; int width, height; mode = setting->mode; format = setting->format; width = setting->width; height = setting->height; // set video stream parameter camera = (struct pxa_camera*)hcam; // 디바이스 핸들러 포인터 복사 ASSERT(camera->handle>0 && camera->status!=cam_status_busy); ASSERT(camera->ref_count==0); streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; streamparm.parm.capture.timeperframe.numerator = 0; streamparm.parm.capture.timeperframe.denominator = 0; streamparm.parm.capture.capturemode = mode; streamparm.parm.capture.extendedmode = CI_SSU_SCALE_DISABLE; printf("camera_config : streamparm.type = %d n", streamparm.type); // Video Stream Parameter 설정 if(ioctl(camera->handle, VIDIOC_S_PARM, &streamparm)<0) { ERRMSG("can't set camera parameter n"); return -1; // Set video format : Video Capture Mode, YUV422P vformat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

199 // Only support three pixel formats ASSERT(format==pxavid_rggb10 format==pxavid_ycbcr422 format==pxavid_ycbcr420); switch(format){ // 픽셀 포맷 선택 case pxavid_rggb10: vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_SRGGB10; break; case pxavid_ycbcr422: vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P; break; case pxavid_ycbcr420: vformat.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; break; default: ASSERT(0); break; vformat.fmt.pix.width = width; vformat.fmt.pix.height = height; // 비디오 포맷 설정 if(ioctl(camera->handle, VIDIOC_S_FMT, &vformat)<0) { ERRMSG("can't set camera format n"); goto FAIL_EXIT; // Release previous allocated buffer if it's applicable if(mode==cam_mode_video){ count = VIDEOBUF_COUNT; // 캡처 모드 else{ count = STILLBUF_COUNT; // 스틸 모드 for (i = 0; i < count; ++i) { if(camera->cambuf[i].buf){ munmap(camera->cambuf[i].buf, camera->cambuf[i].length); memset(camera->cambuf,0,sizeof(camera->cambuf));

200 // Request buffers requestbuffers.type requestbuffers.memory requestbuffers.count = V4L2_BUF_TYPE_VIDEO_CAPTURE; = V4L2_MEMORY_MMAP; = count; // Camera Buffer 요청 if(ioctl(camera->handle, VIDIOC_REQBUFS, &requestbuffers)<0) { DBGMSG("can't require camera buffer"); goto FAIL_EXIT; if (requestbuffers.count < (unsigned int)count ) { ERRMSG("Insufficient camera buffer allocated n"); goto FAIL_EXIT; // do memory map for (i = 0; i < (int)requestbuffers.count; i++) { memset (&buffer, 0, sizeof(buffer)); buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; buffer.index = i; if (ioctl (camera->handle, VIDIOC_QUERYBUF, &buffer)<0) { goto FAIL_EXIT; // Video Memory Map 할당 pmapped = mmap (NULL, buffer.length, PROT_READ, MAP_SHARED, camera->handle, buffer.m.offset); if (MAP_FAILED == pmapped) { ERRMSG("can't do mmap of camera buffer n"); goto FAIL_EXIT; ASSERT(camera->cambuf[i].buf==0); camera->cambuf[i].buf = pmapped; camera->cambuf[i].length = buffer.length;

201 // queue buffer for capture for (i = 0; i < (int)requestbuffers.count; i++) { memset (&buffer, 0, sizeof(buffer)); buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer.memory = V4L2_MEMORY_MMAP; buffer.index = i; if (ioctl (camera->handle, VIDIOC_QBUF, &buffer)<0) { ERRMSG("fatal error - fail to queue buffer n"); ASSERT(0); goto FAIL_EXIT; // Save configuration to device object camera->mode = mode; camera->width = width; camera->height = height; camera->format = format; camera->status = CAM_STATUS_READY; return 0; FAIL_EXIT: for (i = 0; i < VIDEOBUF_COUNT; ++i) { if(camera->cambuf[i].buf){ munmap(camera->cambuf[i].buf, camera->cambuf[i].length); memset(camera->cambuf,0,sizeof(camera->cambuf)); camera->width = 0; camera->height = 0; camera->format = pxavid_invalid; camera->status = CAM_STATUS_INIT; return -1;

202 int camera_start(int hcam) // Camera 동작 시작 함수 { int buftype; struct pxa_camera* camera; // set video stream parameter camera = (struct pxa_camera*)hcam; ASSERT(camera->status==CAM_STATUS_READY); buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 비디오 스트리밍 시작 if (ioctl (camera->handle, VIDIOC_STREAMON, &buftype)<0) { ERRMSG("can't start camera streaming n"); return -1; camera->status = CAM_STATUS_BUSY; return 0; int camera_stop(int hcam) // Camera 동작 정지 함수 { struct pxa_camera* camera; enum v4l2_buf_type buftype; // set video stream parameter camera = (struct pxa_camera*)hcam; ASSERT(camera->status==CAM_STATUS_BUSY); ASSERT(camera->ref_count==0); buftype = V4L2_BUF_TYPE_VIDEO_CAPTURE; // 비디오 스트리밍 정지 if (ioctl (camera->handle, VIDIOC_STREAMOFF, &buftype)<0) { DBGMSG("can't stop streaming n"); return -1; camera->status = CAM_STATUS_READY; return 0;

203 struct pxa_video_buf* camera_get_frame(int hcam) { int ret; struct pollfd ufds; struct v4l2_buffer* buffer; struct pxa_camera* camera; struct ext_video_buf* extbuf; struct pxa_video_buf* vidbuf; // Frame 가져오기 함수 // set video stream parameter camera = (struct pxa_camera*)hcam; ASSERT(camera->status==CAM_STATUS_BUSY); ASSERT(camera->ref_count<VIDEOBUF_COUNT); // This function maybe obsolete ufds.fd = camera->handle; ufds.events = POLLIN; do { ret = poll(&ufds, 1, -1); while (!ret); extbuf = (struct ext_video_buf*)malloc(sizeof(struct ext_video_buf)); ASSERT(extbuf); vidbuf = &extbuf->pxabuf; buffer = &extbuf->v4l2buf; memset(buffer, 0, sizeof(struct v4l2_buffer)); buffer->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buffer->memory = V4L2_MEMORY_MMAP; if (ioctl (camera->handle, VIDIOC_DQBUF, buffer)<0) { ERRMSG("can't dequeue camera buffer n"); return NULL; // Return buffer information if(camera->format==pxavid_rggb10){ vidbuf->width = camera->width; vidbuf->height = camera->height; vidbuf->format = pxavid_rggb10; vidbuf->rggb10.buf = (unsigned short*)camera->cambuf[buffer->index].buf; vidbuf->rggb10.len = camera->cambuf[buffer->index].length;

204 else if(camera->format==pxavid_ycbcr422){ cambuf_to_ycbcr422(&camera->cambuf[buffer->index],vidbuf, camera->width,camera->height); else if(camera->format==pxavid_ycbcr420){ cambuf_to_ycbcr420(&camera->cambuf[buffer->index],vidbuf, camera->width,camera->height); else {ASSERT(0); camera->ref_count++; return (struct pxa_video_buf*)extbuf; int camera_release_frame(int hcam,struct pxa_video_buf* vidbuf) { struct pxa_camera* camera; struct ext_video_buf* extbuf; // set video stream parameter camera = (struct pxa_camera*)hcam; ASSERT(camera->status==CAM_STATUS_BUSY); ASSERT(camera->ref_count>0); extbuf = (struct ext_video_buf*)vidbuf; if (ioctl (camera->handle, VIDIOC_QBUF, (void*)&extbuf->v4l2buf)<0) { DBGMSG("can't enqueue buffer n"); return -1; memset(extbuf,0,sizeof(struct ext_video_buf)); free(extbuf); // Video Buffer 해제 camera->ref_count--; return 0;

205 - overlay2.c #define FORMAT_PLANAR_422 0x3 #define FORMAT_PLANAR_420 0x4 #define MIN(x, y) ((x < y)? x : y) // Overlay-2 오브젝트 구조체 struct overlay2_object{ int fd; enum pxavid_format format; struct pxa_rect window; unsigned char* map; int smem_len; struct pxa_video_buf vidbuf; ; // Overlay-2 오픈 함수 int overlay2_open(char* dev, enum pxavid_format format, struct pxa_rect* rect, int w, int h, int w_off, int h_off) { struct overlay2_object* devobj; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; int disformat; int result,mfb; struct pxa_rect window; ASSERT(format==pxavid_ycbcr422 format==pxavid_ycbcr420); // Overlay-2 오브젝트 초기화 devobj = (struct overlay2_object*)malloc(sizeof(struct overlay2_object)); ASSERT(devobj); memset(devobj,0,sizeof(struct overlay2_object)); if(dev==null) dev = "/dev/fb2"; devobj->fd = open(dev, O_RDWR); if(devobj->fd<0) goto ERROR_RETURN; // 프레임버퍼 Overlay-2 오픈

206 if(rect==null){ // Open main framebuffer to know screen resolution mfb = open("/dev/fb", O_RDWR); // 메인 프레인버퍼 오픈 result = ioctl(mfb, FBIOGET_VSCREENINFO, &var); ASSERT(result==0); printf("width=%d, height=%d n",var.xres,var.yres); close(mfb); window.x=w_off; window.y=h_off; // X Res window.width=w; window.height=h; // Y Res else{ memcpy(&window,rect,sizeof(window)); memset(&var,0,sizeof(var)); var.xoffset = window.x; var.yoffset = window.y; var.xres = window.width; var.yres = window.height; switch(format){ case pxavid_ycbcr422: var.bits_per_pixel = 16; // 16bit break; case pxavid_ycbcr420: var.bits_per_pixel = 16; break; default: ASSERT(0); // Convert external format to LCD format. This macro shall be // defined in LCD driver. switch(format){ case pxavid_ycbcr422: disformat = FORMAT_PLANAR_422; break; case pxavid_ycbcr420: disformat = FORMAT_PLANAR_420; break; default: // Other format are not supported ASSERT(0);

207 var.nonstd = (disformat <<20) (window.y<< 10) window.x; // set "var" screeninfo result = ioctl(devobj->fd, FBIOPUT_VSCREENINFO, &var); ASSERT(result==0); // get updated screen information result = ioctl(devobj->fd, FBIOGET_FSCREENINFO, &fix); ASSERT(result==0); result = ioctl(devobj->fd, FBIOGET_VSCREENINFO, &var); ASSERT(result==0); devobj->map = (unsigned char*)mmap(0, fix.smem_len, PROT_READ PROT_WRITE, MAP_SHARED, devobj->fd, 0); ASSERT(devobj->map!= MAP_FAILED); // Save video buffer to overlay object ASSERT(var.xres%2==0); devobj->vidbuf.ycbcr.y = devobj->map+var.red.offset; devobj->vidbuf.ycbcr.ystep = var.xres; devobj->vidbuf.ycbcr.cb = devobj->map+var.green.offset; devobj->vidbuf.ycbcr.cbstep = var.xres/2; devobj->vidbuf.ycbcr.cr = devobj->map+var.blue.offset; devobj->vidbuf.ycbcr.crstep = var.xres/2; devobj->vidbuf.width = window.width; devobj->vidbuf.height = window.height; devobj->vidbuf.format = format; devobj->smem_len = fix.smem_len; memcpy(&devobj->window,&window,sizeof(window)); devobj->format = format; return (int)devobj; ERROR_RETURN: if(devobj->fd>=0) close(devobj->fd); free(devobj); return 0;

208 void overlay2_close(int handle) { int result; struct overlay2_object* devobj; devobj = (struct overlay2_object*)handle; ASSERT(devobj && devobj->map && devobj->smem_len); result = munmap(devobj->map, devobj->smem_len); ASSERT(result==0); close(devobj->fd); memset(devobj,0,sizeof(struct overlay2_object)); free(devobj); return; // Map display buffer to application work space int overlay2_getbuf(int handle, struct pxa_video_buf* vidbuf) { struct overlay2_object* devobj; devobj = (struct overlay2_object*)handle; ASSERT(devobj && devobj->map && devobj->smem_len); ASSERT(vidbuf); memcpy(vidbuf,&devobj->vidbuf,sizeof(devobj->vidbuf)); return 0; 5. 수행 방법 및 결과 5.1 수행 방법 /root/320app/application/pxa_camera로 이동한다. ]# cd /root/320app/application/pxa_camera make 명령어를 입력한다. ]# make

209 하위 디렉토리 bin/로 이동한다. ]# cd bin/ 생성된 실행파일 camera를 타겟보드로 다운로드한다. 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./camera CMOS Camera를 통해 비디오 스트리밍이 정확히 동작되고 있는지 TFT-LCD를 확인하자. 5.2 결과 CMOS Camera를 통해 감지되는 영상들이 TFT-LCD로 디스플레이 되고 있다

210 Chapter 10. SDL 애니메이션 1. 개요 이 장에서는 SDL를 ARM용으로 포팅 하는 방법과 SDL 라이브러리를 이용한 애니메이션 프로그 램을 작성해 보도록 하겠다. 2. 관련기술 SDL 개요 SDL은 Simple DirectMedia Layer의 약자로 다양한 플랫폼에서 그래픽, 사운드 그리고 입력장치 와의 간단한 인터페이스로 표현되는 C로 작성된 오픈소스 기반의 멀티미디어 라이브러리이다. 주로 컴퓨터 게임이나 그밖에 멀티미디어 어플리케이션을 개발하는데 사용되며 리눅스, 윈도우 즈, Mac OS X등 같은 운영체제에 기본적으로 포함되어 있다. SDL을 사용함으로써 개발자들은 비디오, 이벤트 처리, 디지털 오디오, CD-ROM, 사운드, 네트워킹 관리할 수 있고 오브젝트 이 미지 로딩, 타이머, 쓰레드와 같은 기능을 API 형태로 제공받을 수 있다. SDL 기능 비디오 원하는 모든 depth(8-bpp 이상)로 비디오 모드를 세팅한다. 하드웨어에 의해 지원되지 않는다 면 추가적인 변환을 통해 가능하다. 선형 그래픽 프레임버퍼에 쓰기 선형 그래픽 프레임 버퍼에 쓰기 컬러키 또는 알파 블렌딩 속성을 갖는 서페이스(surface) 생성. 컬러키 또는 알파 블렌딩 속성 을 갖는 서페이스 (표면)를 생성한다. 서페이스 블릿(blits)은 최적화된 블리터(blitter)를 통해 자동적으로 변환되고, 가능하다면 하드 웨어 가속된다. x86에서는 MMX는 최적화된 블릿이 지원된다. 하드웨어 가속 블릿(blit)과 칠하기(fill) 기능은 하드웨어에 의해 지원되는 경우에 사용된다. 이벤트 이벤트는 다음을 위해 제공된다 -애플리케이션의 모양이 변할때 애플 리케이션의 모양이 변할때 -키보드 입력 키보드 입력 -마우스 입력 마우스 입력 사용자 요구에 의한 종료 사용자 요구에 의한 종료 각 이벤트는 SDL_EventState() 에 의해 활성화되거나, 비활성화될 수 있다. 이벤트들은 내부 이벤트 큐로 보내지기 전에 사용자-지정의 필터 함수를 거치게 된다. 쓰레드-안전한 이벤트 큐. 쓰레드 - 안전한 이벤트 큐. 오디오 8 비트와 16 비트, 모노 또는 스테레오의 오디오 재생 설정. 하드웨어에 의해 지원되지 않는 포맷이라면 추가적인 변환을 통해 가능하다

211 오디오는 별도의 쓰레드를 사용해 독립적으로 수행되며, 사용자 콜백 메카니즘에 의해 채워진 다. 커스텀 오디오 믹서를 위해 설계되었지만, 예제들을 통해 완전한 오디오/음악 출력 라이브러리 를 제공한다. 타이머 밀리세컨트(millisecond)단위의 경과된 시간을 얻는다. 지정된 밀리세컨드 단위의 시간동안 기다린다. 10ms 단위의 단일 주기 타이머를 설정한다. 엔디안 비의존성(Endian independence) 쓰레드 CD-ROM 오디오 SDL 플랫폼 리눅스 비디오 디스플레이를 위해서는 X11 을 사용한다. XFree86 DGA 익스텐션을 사용하며 풀스크 린 디스플레이를 위해서는 새로운 MTRR 가속을 사용한다. 사운드를 위해서는 OSS API 를 사용한다. 쓰레드는 clone() 시스템 콜과 SysV IPC 또는 glibc-2.1 pthread 를 사용해 구현된다. Win32 는 Win32 두가지 버전이 있는데, 하나는 Win32 API 에 기반해서 모든 시스템에 안정적으로 사용할 수 있는 것이고 또 하나는 DirectX API 에 기반한 빠른 성능을 낼 수 있는 것이다. 안정 버젼은 비디오 디스플레이를 위해 GDI 를 사용한다. 고성능버젼은 비디오 디스플레이를 위해 DirectDraw 를 사용하며, 가능하다면 하드웨어 가속의 도움을 받는다. 안정 버젼은 사운드를 위해 waveout API 를 사용하고, 고성능버젼은 오디오 재생을 위해 DirectSound 를 사용한다. BeOS BeOS 비디오 디스플레이를 위해서는 BDirectWindow가 사용된다. 사운드를 위해서는 BSoundPlayer가 사용된다. MacOS, MacOS X 비디오 디스플레이를 위해서는 Carbon 과 DrawSprockets 이 사용된다. 사운드를 위해서는 SoundManager API 가 사용된다. MacOS X 에서는 자체 비선점형 쓰레드가 지원된다. 비공식적 포팅들, 진행중인 포팅들

212 Solaris, IRIX, FreeBSD, QNX, OSF/True64 SDL 포팅 여기서는 임베디드 시스템 기반의 X-HYPER320TKU 보드를 타겟으로 ARM용 라이브러리를 생성 시키고 포팅하여 타겟보드상에서 SDL 기반으로 작성된 하나의 에니매이션 예제 프로그램을 테 스트 해보고자 한다. 사용된 SDL 버전은 가장 최근 버전은 이고 확장 라이브러리인 SDL Image 버전은 1.2.6을 이용할 것이고 입력장치로 TSLIB를 사용하여 터치기능을 사용할 수 있도 록 할 것이다. SDL 다운로드 설치를 하기 위해서는 SDL 오픈소스가 필요하다. 다운로드 경로는 다음과 같다. SDL SDL_image

213 ARM용 SDL 구축 다운로드한 압축파일을 적당한 위치에서 압축해제 한다. 그리고 작업의 편의를 위해 디렉토리 설치 환경 설정 파일을 생성한다. ]# tar xvfz SDL tar.tar --압축풀기 ]# cd SDL 해당경로이동 먼저 ARM용 크로스컴파일러에 라이브러리 구축을 하도록 하겠다. ]# vi config-arm -- config-arm 파일생성 SDL 예제 프로그램을 컴파일 하기 위해서는 컴파일러에 SDL 라이브러리가 구축이 되어 있어야 한다. 압축해제 후 아래의 옵션에 맞추어 설치 환경을 설정한다. VI 편집기에서 다음과 같이 입력한다. #!/bin/sh export PKG_CONFIG_PATH=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi /lib/pkgconfig export PKG_CONFIG=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/bin/ pkg-config export CC=/usr/local/arm-linux-4.1.1/bin/arm-linux-gcc export STRIP=/usr/local/arm-linux-4.1.1/bin/arm-linux-strip export RANLIB=/usr/local/arm-linux-4.1.1/bin/arm-linux-ranlib export CXX=/usr/local/arm-linux-4.1.1/bin/arm-linux-g++ export AR=/usr/local/arm-linux-4.1.1/bin/arm-linux-ar./configure --build=i686-pc-linux-gnu

214 include --prefix=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi --host=arm-linux --disable-debug --enable-events --disable-joystick --disable-cdrom --disable-diskaudio --disable-mintaudio --disable-esd --disable-nsam --disable-dga --disable-video-x11-dgamouse --disable-video-x11-xv --enable-video-x11-xinerama --disable-video-x11-xme --disable-video-dga --disable-video-photon --disable-video-ps2gs --disable-video-xbios --disable-video-gem --disable-video-opengl --enable-input-event --enable-input-tslib --disable-stdio-redirect --disable-directx --disable-directfb --disable-atari-ldg --disable-video-x11-dpms --disable-video-cocoa --disable-video-svga --disable-video-vgl --disable-video-wscons --disable-video-dummy --disable-ipod --disable-dummyaudio --disable-altivec --disable-esdtest --disable-esd-shared --disable-pulseaudio --disable-pulseaudio-shared --with-x --x-includes=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/ --x-libraries=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/lib 다음으로 include/sdl_stdinc.h 파일을 열어 133번 라인을 아래와 같이 주석 처리한다. ]# vi include/sdl_stdinc.h

215 다음 절차대로 컴파일 및 설치를 진행한다. ]# chmod 755 config-arm --권한설정 변경 ]#./config-arm; make; make install 이제 타겟보드 파일시스템에 포팅할 SDL 라이브러리를 구축하여야한다. 방법은 위와 동일하다. 다만 config_arm 파일을 config_fs 파일이름으로 변경한 후 prefix 경로만 다음과 같이 변경해서 저장한다. ]# cp config-arm config-fs --이름바꿔서 복사 ]# vi config-fs --편집기 열어서 실행 --prefix=/usr <-- 이렇게 변경 다음으로 앞의 config-arm 파일과 동일하게 권한 변경을 한 후에 컴파일을 진행한다. ]# chmod 755 config-fs -- 권한설정 변경 ]# make distclean ]#./config-fs; make 여기서 주의할 점은 make install을 진행할 시 설치 디렉토리를 반드시 지정해야 한다. 그렇지 않으면 X86상의 /usr 밑에 설치되어 기존의 설치된 X86용 SDL 라이브러리와 겹치게 되는 문제 가 발생한다. ]# make install DESTDIR=$PWD/ install-fs 설치를 완료하였으면 다음과 같이 이동해서 확인을 한다. ]# cd install-fs/usr ]# ls 확인 후 lib 디렉토리를 제외한 나머지는 모두 삭제한다. ]# rm -rf include bin share 그리고 lib 디렉토리 밑의 pkgconfig 디렉토리도 삭제한다. ]# cd lib ]# rm -rf pkgconfig

216 정리가 끝났으면 usr 디렉토리를 압축한다. sdl.tgz 파일이 생성될 것이다. ]# cd../../ ]# tar cvfz sdl.tgz usr/ 타겟보드 파일시스템의 최상위 디렉토리에 sdl.tgz 파일을 다운로드한 후 압축해제를 한다. 320TKU]# tar xzf sdl.tgz 이것으로 라이브러리 설치가 완료되었다. 이어서 SDL 확장 라이브러리를 설치하도록 하겠다. 확 장라이브러리의 설치방법은 라이브러리 설치 방법과 동일하다. 마찬가지로 xvfz SDL-image tar.tar압축을 해제하고 설치 환경 설정 파일을 작성한다. ]# tar xvfz SDL-image tar.tar ]# cd SDL_image ]# vi config-arm #!/bin/sh export PKG_CONFIG_PATH=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi /lib/pkgconfig export PKG_CONFIG=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/bin/ pkg-config export CC=/usr/local/arm-linux-4.1.1/bin/arm-linux-gcc export STRIP=/usr/local/arm-linux-4.1.1/bin/arm-linux-strip export RANLIB=/usr/local/arm-linux-4.1.1/bin/arm-linux-ranlib export CXX=/usr/local/arm-linux-4.1.1/bin/arm-linux-g++ export AR=/usr/local/arm-linux-4.1.1/bin/arm-linux-ar./configure --build=i686-pc-linux-gnu --host=arm-linux --prefix=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi --disable-sdltest 다음 절차대로 컴파일 및 설치를 진행한다. ]# chmod 755 config-arm ]#./config-arm; make ]# make install

217 이상 컴파일러에 SDL 확장 라이브러리 구축을 마쳤다. 이제 타겟보드 파일시스템에 포팅할 확장 라이브러리를 구축 하여야한다. 방법은 위와 동일하다. 앞의 라이브러리와 마찬가지로 config_arm 파일을 config_fs 파일이름으로 변경한 후 아래와 같이 변경해서 저장한다. ]# cp config-arm config-fs --이름바꿔서 복사 ]# vi config-fs --편집기 열어서 실행 #!/bin/sh export PKG_CONFIG_PATH=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi /lib/pkgconfig export PKG_CONFIG=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/bin/ pkg-config export CC=/usr/local/arm-linux-4.1.1/bin/arm-linux-gcc export STRIP=/usr/local/arm-linux-4.1.1/bin/arm-linux-strip export RANLIB=/usr/local/arm-linux-4.1.1/bin/arm-linux-ranlib export CXX=/usr/local/arm-linux-4.1.1/bin/arm-linux-g++ export AR=/usr/local/arm-linux-4.1.1/bin/arm-linux-ar export SDL_CONFIG=/usr/local/arm-linux-4.1.1/arm-iwmmxt-linux-gnueabi/bin/sdl -config./configure --build=i686-pc-linux-gnu --host=arm-linux --prefix=/usr --disable-sdltest 다음으로 앞의 config-arm 파일과 동일하게 권한 변경을 한 후에 컴파일을 진행한다. ]# chmod 755 config-fs -- 권한설정 변경 ]# make distclean ]#./config-fs; make 여기서 주의할 점은 make install을 진행할 시 설치 디렉토리를 반드시 지정해야 한다. 그렇지 않으면 X86상의 /usr 밑에 설치되어 기존의 설치된 X86용 SDL 라이브러리와 겹치게 되는 문제 가 발생한다. ]# make install DESTDIR=$PWD/ install-fs 설치를 완료하였으면 다음과 같이 이동해서 확인을 한다. ]# cd install-fs/usr ]# ls

218 확인 후 lib 디렉토리를 제외한 나머지는 모두 삭제한다. ]# rm -rf include 정리가 끝났으면 usr 디렉토리를 압축한다. sdl.tgz 파일이 생성될 것이다. ]# cd.. ]# tar cvfz sdl_imgae.tgz usr/ 타겟보드 파일시스템의 최상위 디렉토리에 sdl_image.tgz 파일을 다운로드한 후 압축해제를 한 다. 320TKU]# tar xzf sdl_image.tgz 이것으로 ARM용 SDL 라이브러리 포팅을 완료하였다. 3. S/W설계 3.1 SDL 애니메이션 기능 PNG 이미지 파일을 로드하여 디스플레이를 한다. TSLIB를 이용하여 터치를 사용할 수 있다. 여러 개의 이미지로 애니메이션 효과를 나타낼 수 있다. 3.2 구조 SDL 애니메이션 프로그램의 구조는 다음과 같다

219 SDL 확장 API인 Image Loader 를 사용하여 파일시스템에 저장되어 있는 특정 PNG 이미지 파 일을 가져오고 SDL 애니메이션 프로그램에서 SDL API를 이용하여 애니메이션 효과를 나타내게 된다. 애니메이션 효과는 TFT-LCD를 통해 디스플레이 되고 이 때 TSLIB 터치를 이용하여 캐릭 터의 방향을 정하여 움직이게 할 수 있다. 아래 그림은 터치에 따라 좌측 또는 우측으로 움직이 는 효과를 나타 내기 위한 foo.png 파일 이다

220 4. S/W 구현 SDL 애니메이션 프로그램의 코드 설명 SDL_animation.cpp 주요 코드 //Screen attributes const int SCREEN_WIDTH = 800; const int SCREEN_HEIGHT = 480; const int SCREEN_BPP = 16; //The dimenstions of the stick figure const int FOO_WIDTH = 64; const int FOO_HEIGHT = 205; //The direction status of the stick figure const int FOO_RIGHT = 0; const int FOO_LEFT = 1; SDL_Surface *foo = NULL; // 전역변수 bool load_files() // 이미지 파일 로딩 함수 { //Load the sprite sheet foo = load_image("foo.png"); // foo.png 파일을 로딩한다. //If there was a problem in loading the sprite if( foo == NULL ) { fprintf(stderr, "Couldn't load image file: %s n", SDL_GetError()); return false; //If everything loaded fine return true;

221 SDL_Surface *load_image(std::string filename) // 이미지 로딩 함수 { //The image that's loaded SDL_Surface* loadedimage = NULL; //The optimized surface that will be used SDL_Surface* optimizedimage = NULL; //Load the image loadedimage = IMG_Load(filename.c_str()); // PNG 이미지 파일을 로딩 //If the image loaded if(loadedimage!= NULL){ //Create an optimized surface optimizedimage = SDL_DisplayFormat(loadedImage); //Free the old surface SDL_FreeSurface(loadedImage); //If the surface was optimized if(optimizedimage!= NULL){ //Color key surface SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedimage->format, 0, 0xFF, 0xFF)); //Return the optimized surface return optimizedimage; void Foo::handle_events() // TSLIB 이벤트 처리 함수 { //If a touch was pressed if(event.type == SDL_MOUSEBUTTONDOWN) { // 터치 펜 다운 if(offset < event.button.x) { velocity += FOO_WIDTH / 4; pointer_status = 1; else { velocity -= FOO_WIDTH / 4; pointer_status = 2;

222 else if(event.type == SDL_MOUSEBUTTONUP) { // 터치 펜 업 if (pointer_status == 1) velocity -= FOO_WIDTH / 4; else if (pointer_status == 2) velocity += FOO_WIDTH / 4; bool init() // SDL 서브시스템 초기화 함수 { //Initialize all SDL subsystems if (SDL_Init(SDL_INIT_VIDEO) < 0) { // SDL 초기화 fprintf(stderr, "Couldn't initialize SDL: %s n", SDL_GetError()); return false; //Set the window caption SDL_WM_SetCaption("Animation Test", "SDL_animation"); // 캡션 설정 //Set up the screen screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); // 비디오 모드 설정 //If there was an error in setting up the screen if( screen == NULL ) { fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s n", SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_GetError()); return false; //If everything initialized fine return true; int main(int argc, char* args[]) // 메인 함수 { //Quit flag bool quit = false; //Initialize if(init() == false) return 1; //Load the files if(load_files() == false) return 1; //Clip the sprite sheet set_clips(); //The frame rate regulator Timer fps;

223 //The stick figure Foo walk; //While the user hasn't quit while(quit == false) { //Start the frame timer fps.start(); //While there's events to handle while(sdl_pollevent(&event)) { // 이벤트 발생을 감시 //Handle events for the stick figure walk.handle_events(); //If the user has Xed out the window if(event.type == SDL_QUIT) { //Quit the program quit = true; //Move the stick figure walk.move(); //Fill the screen white SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xff, 0xff, 0xFF)); //Show the stick figure on the screen walk.show(); //Update the screen if(sdl_flip(screen) == -1) return 1; //Cap the frame rate if(fps.get_ticks() < 1000 / FRAMES_PER_SECOND) SDL_Delay((1000 / FRAMES_PER_SECOND) - fps.get_ticks()); //Clean up clean_up(); return (255);

224 5. 수행 방법 및 결과 5.1 수행 방법 /root/320app/application/sdl_example/sdl_animationdm로 이동한다. ]# cd /root/320app/application/sdl_example/sdl_animationdm make 명령어를 입력한다. ]# make 생성된 실행파일을 타겟보드로 다운로드한다. X환경을 실행한다. 320TKU]# startx TSLIB 사용을 위해 마우스 드라이버를 TSLIB로 지정한다. 320TKU]# export SDL_MOUSEDRV=TSLIB 타겟보드에서 실행파일이 있는 위치에서 다음과 같이 입력하여 실행을 하도록 한다. 320TKU]#./SDL_animation 터치를 입력하여 화면에 보이는 캐릭터를 움직여 본다. 5.2 수행 결과 터치를 이용하여 캐릭터의 오른쪽으로 입력하면 캐릭터가 오른쪽으로 이동하게 되고 왼쪽으로 입력하면 반대방향으로 움직이게 된다. 캐릭터 오른쪽 터치

225 캐릭터 왼쪽 터치

226 Chapter 11. Qtopia Core-4 포팅 실습 1. 개요 이 장에서는 X-HYPER320 TKU를 베이스로 Qtopia Core-4 (이하 QT4)를 포팅하는 방법을 설 명하겠다. QT 버전은 4.3.4를 이용하였다. (이하 QT4) 2. 관련기술 1. Qt란? Qt는 1996년 초에 노르웨이의 Trolltech[1]에서 발표한 크로스 플랫폼(Cross-platform)을 지원 하는 C++ GUI 프로그램 개발용 라이브러리(또는 툴킷-Toolkit)이다. 어플리케이션 개발자는 Qt 의 위젯(Widget)들을 이용하여 GUI(Graphical User Interface)를 구축하는데 필요한 기능을 모두 얻을 수 있다. Qt는 완전 객체지향으로, 용이하게 확장할 수가 있어 진정한 컴포넌트 (Component) 프로그래밍이 가능하다. 리눅스 Desktop의 기본(KDE의 기본 라이브러리)을 구성하는 라이브러리이고 거의 모든 리눅스 배포판에 기본으로 포함되어 있다. 풍부한 양의 위젯[2]을 제공하여 사용하기 쉽고 화려한 인터 페이스를 제공하며 객체지향으로 프로그램의 개발이 쉽고 쉽게 확장할 수 있다. Qt는 푸쉬버튼(PushButton), 메뉴(Menu), 다이얼로그(Dialog)와 같은 그래픽 객체(Graphical Object)와 이것들을 구현하기위해 필요한 함수들의 모임(Library)이다. 그래픽 객체들은 위젯 (Widget) 이라고도 불리며 이 위젯에 대응하는 함수들을 합한 것을 툴킷(Toolkit)이라고 한다

227 (1) GUI Toolkit에 대해서 GUI 툴킷이란 프로그래머가 GUI 프로그래밍을 쉽게하기 위해서 버튼이나 박스, 윈도우 같은 클 래스들을 모아놓은 라이브러리이다. 프로그래머는 버튼이나 박스와 같은 것들을 직접 프로그래밍 으로 구현하지 않고 이미 정의되어 있는 것들을 불러서 사용하면 된다 위젯들은 그것과 관련된 대응하는 함수(메소드)를 가지고 있고, 메소드는 그 객체에 대한 동작을 수행한다. 위젯은 객체지향으로 개발되어 있기 때문에 사용자는 위젯을 상속해서 원하는 위젯을 손쉽게 만들수 있다. Qt는 Unix에서 사용하는 경우 X윈도우 시스템에 기반을 두고 있다. Qt라이브러리의 구조를 보면 Xlib(X 호출하고 있다. 따라서 여러분들이 X윈도우 시스템에 대해서 자세히 알고 있다면 프로그 래밍하는데 많은 도움이 될 것이다. 1 X 윈도우 시스템(Window System) X 윈도우 시스템은 플렛폼 독립적(Platform Indepent)이고 네트워크 투명성(Network Transparent)[3]을 보장하는 그래픽 환경 기반의 시스템 소프트웨어이다. 1984년에 MIT에서 공 개한 X 윈도우 시스템은 미국의 MIT(Massachusetts Institute of Technology)공대에서 DEC(Digital Equipment Corporation)을 지원을 받아서 개발하였다. X 윈도우 시스템은 아데나(Athena) 프로젝트의 일환으로 구체적인 형태는 1986년 X10.4가 공개 되면서 갖추기 시작하였고 1987년 지금과 비슷한 X11이 만들어졌다. X의 기본적인 개념과 이름은 스탠포드대학에서 개발한 W에서 가져왔다. X의 목적은 아데나 프 로젝트(Athena Project)를 수행하는데 필요한 분사적이고 하드웨어 독립적인 사용자 인터페이스 를 제공하는 것이다. 초기의 X는 MIT와 DEC에서 주로 사용되었지만 버젼 1.0이후 많은 업체에 서 사용하게 되었다. X 윈도우 시스템 이름의 유래는 스텐포드 대학에서 시작된 W라고 불리우는 윈도우 프로젝트 에서 비롯되었다. W는 MIT개발 팀의 시작점이 되었는데, 성능이 항상됨에 따라 원래의 프로 젝트와 구분하기 위해서 X로 이름을 바꾸었다. 2 X 윈도우 시스템(Window System)의 구조 X 윈도우 시스템의 구조를 보면 X 윈도우 시스템은 기본 윈도우 시스템(Base Window System) 위에 계층적으로 존재한다. 각 윈도우 시스템의 각 계층에서 제공하는 특정 정책에 대한 메카니 즘을 제공하는데, 예를 들면 그림을 그리거나 폰트를 출력하는 일따위를 말한다. 기본 윈도우 시스템은 X 프로토콜을 사용하여 외부 인터페이스를 구성한다. 네트워크 프로토콜 인터페이스는 하나의 CPU, 여러개의 CPU와 관계없이 동작하도록 설계되었다. 네트워크 프로토콜 형태로 구성됨으로써 X 윈도우에서 네트워크 투명성과 디바이스 독립성을 제 공하게 되었다. X 윈도우 시스템은 클라이언트/서버 형태이며 클라이언트와 서버 사이에 교환되는 정보는 X 프 로토콜을 따르게 된다. 참고로 MS Windows는 클라이언트/서버 개념과는 다르게 하나의 덩어리 로 움직이는 단일체 구성을 갖고 있다

228 X 윈도우 애플리케이션(Application)은 X 프로토콜을 직접 거치지 않고 별도의 API를 통해서 동 작하게 된다. 이러한 별도의 API들의 묶음을 X 라이브러리(X Library ; Xlib라고도 한다.)는 X 프 로토콜에 대한 C언어 서브 루틴 API로, X 프로토콜에 대한 인터페이스 기능과 기본 윈도우 시스 템에 적용되는 기능을 제공한다. 결국 화면에 나타나는 사용자 인터페이스(User Interface)는 기본 윈도우 시스템, X 툴킷(X Toolkit Instrinsics, Xt라고도 불림), 윈도우 매니저, 세션 매니저 그리고 애플리케이션이 결합된 것이다. 간단하게 도식하면 다음과 같다. X윈도우 시스템에서는 Xlib라고 불리우는 수준의 C인터페이스 라이브러리를 제공한다. Xlib를 이 용하여 완전한 X윈도우 프로그램을 작성 할 수 있지만 사용자가 화면의 윈도우와 같은 객체들을 직접 생성해야 한다. 이러한 작업들은 상당한 양의 코드라인과 지루함이 요구되는 작업니다. 이 러한 복잡한 작업을 줄이기 위해서 그래픽 객체 인터페이스를 미리 만들어 놓은 툴킷이라고 불 리우는 라이브러리를 사용한다. 3 GUI 툴킷(Toolkit) X의 특징은 특정장치에 무관하며 어떠한 사용자 인터페이스 스타일을 고집하지 않고 장치와 독 립적인 계층으로서 인터페이스의 기본적인 요소를 구축할 수 있는 기반을 제공한다는 것이다. 사용자 인터페이스를 구축할 수 있는 기반을 제공하며 스크롤바, 메뉴, 대화상자 등의 인터페이 스는 지원하지 않는다. 따라서 X를 기반으로 프로그램을 작성하기 위해서는 프로그래머는 분산 네트워크 환경을 고려한 그래픽 사용자 환경이기 때문에 상당히 어려운 방법으로 프로그래밍을 해야한다. 이러한 문제를 해결하기 위해서 응용프로그램의 인터페이스를 수월하게 구축할 수 있

229 는 고급 라이브러리의 필요성이 증대되었다. X와 함께 배포되는 라이브러리가 Athena라고 한다. Athena 위젝을 사용하기 위한 함수들을 X Toolkit Intrinsics라고 한다. Athena는 2차원적인 간단 한 형태로 되어있다. 아주 간단한 형태이기 때문에 상업적으로 사용하기에는 무리가 있었다. 그 래서 등장한 대표적인 X 라이브러리가 모티브(Motif)이다. 4 리눅스에서의 툴킷(Toolkit) 리눅스에서 자유소프트웨어의 개발하는데 X 툴킷으로 대표적으로 사용되는 모티브의 경우 상용 (지금은 자유(Free) 소프트웨어)이었기 때문에 적합하지 않았고 예전에 개발된 라이브러리이기 때문에 사용자 인터페이스로 사용하기에 모양이나 사용도 면에서 MS Windows에 비해서 많은 차이가 나게 되었다. 그래서 많은 라이브러리들이 만들어지게 되었는데 그중 리눅스에서 대표적 으로 사용되는 라이브러리가 Qt(KDE)와 GTK+(Gnome)이다. 예전에 리눅스에서 사용되던 윈도우 매너지인 Fvwm을 보면 정말 밋밋하고 단순했다. 하지만 리 눅스도 시간이 지나고 발전을 하면서 kde와 Gnome과 같은 MS Windows와 비슷한 예쁘고 사용 자에 친화적인(User Friendly) X Window 환경(Environment)이 등장하였다. Matthias Ettirch는 KDE를 개발하면 노르웨이의 트롤테크 사에서 발표한 Qt를 선택하었다. 하지 만 기존의 Qt 라이센스에 약간의 문제(Qt 버젼 1.XX에서 GNU 라이센스를 사용할 수 없었기 때 문에)가 있었기 때문에 라이센스에 반대하는 사람들이 새로운 툴킷인 GTK를 이용하여 GNOME 프로젝트을 시작되게 되었다. GTK+는 GIMP Toolkit의 약자로 이름 그래로 GIMP개발에 사용하기 위해 제작된 위젯이다. GIMP는 리눅스에서 그림을 편집할 수 있는 소프트웨어로 맥킨토시에 많이 사용되는 포토샵 (Adobe Photoshop)과 같은 프로그램이다. 요즘은 리눅스 뿐만 아니라 맥과 윈도우용으로 포 팅되어 있다. 강력한 데스크탑 환경을 위한 프로젝트 중 하나인 GNOME 프로젝트와 많은 유틸러티들이 GTK+를 이용해서 제작되고 있다. GTK+는 Qt가 OOP기반의 C++인 반면 객체지향적인 C언 어 기반으로 C++을 모르는 사람들도 프로그래밍할 수 있다. C++기반의 GTK를 원하면 GTK--를 이용하면 된다. GTK는 오픈소스 개발방식으로 개발되었고 LGPL라이센스를 채택하여 배포와 사용에 자유롭 다. GTK+는 일찍부터i18n을 기본적으로 지원했으므로, 2바이트 문화권의 개발자들이 편하게 개발할 수 있었다. (2) Qt의 특징 Qt의 기본적인 특징은 다음과 같다. 1 다양한 플렛폼(Platform)을 지원 다른 라이브러리에서 프로그램을 개발하는 것과는 다르게 포팅이 자유롭다. 단지 해당 플렛폼에 서 재컴파일하는 것으로 유닉스 / Mac OS X 및 윈도우 환경에서 실행된다

230 ( Write Once, Compile Anywhere ) MS/Windows : 95, 98, NT 4.0, ME and 2000, Unix/X11 : Linux, Sun Solaris, HP-UX, Digital Unix, IBM AIX, SGI IRIX, 그 외 많은 제품들 Macintosh : MacOS X(Qt 3.0부터 지원) Embedded : 프레임버퍼(framebuffer)를 지원하는 리눅스 플랫폼(Linux Platforms) 2 C++기반의 객체지향 클래스 라이브러리 Qt의 모든 구현이 C++ 클래스로 캡슐화되어 있어 배우기 쉽고 사용하기 쉽다. 그리고 상속을 이용하여 기능을 쉽게 확장할 수 있다. MS Windows의 MFC와 비슷하며 기존의 C에 비해서 개 발이 휠씬 쉽고, 기능확장이 편리해서 생산성이 높다. 3 국제화 기능 지원(2.0부터 i18n기본 제공) Qt 2.0부터 16비트인 유니코드를 완벽하게 지원한다. 또한 다양한 ISO변환 규격과 지역화 (Localization)을 지원한다. 각 나라의 언어로 작성된 메시지 파일만 있으면 해당 언어로 번역된 프로그램을 쉽게 사용할 수 있다. Qt 3.0부터는 메시지의 번역을 쉽게하기 위해서 Qt Linguist라는 유틸러티를 제공하고 아랍어나 희랍어를 위해서 오른쪽에서 왼쪽으로 글을 쓰는 것을 지원한다. 4 Signal/Slot 방식(Signals/Slots mechanism) Qt에서는 QObject라고 불리우는 클래스에 신호(Unix에서 말하는 신호는 아니다.)를 내는 기구와 그 신호를 슬롯(멤버함수)에서 받는 기구가 갖춰져 있다. 객체(Object)의 신호(Signal)을 다른 객 체(Object)의 슬롯(Slot)에 연결함으로써 프로그램의 동작을 결정한다. 기존의 Motif에서 사용하는 Callback방식이 아닌 Signals/Slots Mechanism을 사용한다. 기존의 Event Model도 제공한다.(나중에 따로 자세히 설명하겠다.)

231 5 표준 GUI를 구성할 수 있는 풍부한 양의 위젯(Widget)을 제공한다. 표준 User Interface(Push button, list, menu, check box )를 제공하고 표준 Look과 Feel을 제 공(Theme 기능도 제공)한다. 최초의 OSF Motif 스타일이 가장 아름답고 화려한 GUI 스타일(Style)이라고 생각하는 사람의 거 의 없을 것이다. 그 때문에 Motif와 같은 Look과 Feel을 좀 더 개량하려고 하는 시도가 몇번이 나 이뤄어졌다. 그중의 하나가 CDE스타일로, 이것은 Qt의 버젼 2.0이상부터 지원되고 있다. 2.2 부터는 IRIX워크스타일의 SGI스타일이 지원되고 있다. 이것보다 근사한 3D의 beveling나 마우스 아래를 하이라이트하는 효과등이 있어 매우 매력적이다. 또 리눅스 사용자들을 위하여 Motif 플 러스 스타일도 추가되었다. 그리고 3.0이상부터는 맥킨토시 사용자들을 위하여 아쿠아(Aqua) 스 타일도 추가되었다. (3) QT라이센스 기존의 1.xx대에서는 GPL을 따를 수 없었지만 2.x대에서부터 QPL과 GPL을 선택해서 사용할 수 있게 되었다. Qt의 라이센스는 다음과 같은 3가지의 다른 라이센스가 존재한다. 1 Qt Enterprise Edition과 Qt Professional Edition(Qt Commercial License) 위의 버젼으로 상용 소프트웨어의 개발을 할 수가 있다. 상용으로 소프트웨어를 개발하여 배포 가 가능하고, 무료의 업그레이드와 기술지원(Technical Support) 서비스가 포함된다. Enterprise Edition 에서는 Professional Edition 에는 없는 확장 모듈이 포함된다. 2 Qt Free 자유(Free)롭게 개발되는 Open source 소프트웨어의 개발에만 이용할 수 있는 Qt 의 Unix/X11 버젼이다. 이것은 QPL(Qt Public License)과 GNU GPL(General Public License)에 근거해서 무 료로 이용할 수 있다. 3 Qt/Embedded Free Edition 자유(Free) 소프트웨어의 개발에만 이용할 수 있는 Qt 의 Embedded 버젼이다. 이것은 GNU GPL(General Public License)에 근거해서 무료로 이용할 수 있다. 윈도우의 경우 Qt 2.3대의 비사업용(non commercial) 버전을 제공한다. 맥용의 경우에는 자유 (Free)판은 없고 사용판만이 존재한다. 물론 평가판(Evaluation Version)은 제공된다. Unix의 경우 상용판(Professional Edition)과 자유판(Free Edition)이 모두 존재한다. 자유 소프트 웨어로 라이센스(Open Source로 개발하는 경우)에 따라서 자유판을 사용할 수 있다. 다른 툴킷과는 다르게 Qt자유(Free) 버젼을 이용해서 프로그램을 개발하다가 상업적으로 판매를 하기 위해서는 Qt 상업용 버젼(Qt Enterprise Edition이나 Qt Professional Edition)을 구입하면 되기 때문에 다른 툴킷의 라이센스에 비해서 보다 자유롭다. 프로그램의 실행파일(Binary file)의 배포에는 따로 라이센스가 필요로 하지 않는다

232 (4) 각 플랫폼별 특징들 1 리눅스 리눅스에서는 리눅스를 설치하면 각 배포판에 따라 차이가 있지만 일반적으로 자유판(free Edition)이 설치되어 있다. 다른판 들과는 다르게 라이센스에 보다 자유롭고 다양한 개발툴들이 존재한다. 2 Qt/Windows 리눅스 버젼에서는 소스파일이 제공되는 것과는 달리 윈도우와 맥용 버젼에서는 소스파일이 제 공되지 않는다. 윈도우 버젼의 설치는 인스톨러에 의한 마법사 기능으로 다른 버젼에 비해서 설 치가 쉽다. Visual C++이나 Borland C++ Builder에 의해서 쉽게 프로그래밍 할 수 있다. MFC와 Qt와의 차이점 MFC(Microsoft Foundation Class)는 윈도우 운영체계의 그래픽 툴킷(Graphical Toolkit)이다. Win32 API는 C와 C++을 혼합해서 쓰고 있는 좀 약한 객체지향(Object oriented)이다. 반면에 Qt는 완전객체지향적이다. 3 Mac OS X Mac OS X의 대표적인 개발도구인 Platform Builder나 interface Builder와의 연동은 아직 지원 하지 않는다. Carbon위에 Qt 라이브러리가 위치하고 있기 때문에 프로그램 배포에 따른 라이브 러리의 배포가 따로 필요로 하지 않는다. (5) Qt 버젼별 특징과 차이점 버젼 다른 버젼과의 차이점 비고 1.xxx 2.xxx 3.xxx KDE 프로젝트에 기본 라이브러리로 사용 Netscape Plug-In 자동 레이아웃(Automatic Layout) 최초의 국제화 기능 지원(Unicode 기본 지원) 테마기능의 지원 MDI 기능 지원 Qt Designer 제공(Qt 2.2부터) 멀티 쓰레드(Multi-thread) 기능 2.xx버젼에 대해서 많은 수의 위젯의 추가 및 수정 Mac OS X 지원 데이터베이스에 관련된 API 지원 KDE 1.xxx KDE 2.xxx KDE 3.xxx

233 Qt/Embedded와 Qtopia Qt Embedded와 Qtopia는 임베디드(Embedded) 시장을 위해서 만들어진 Qt 버전으로 기존의 Qt Application이 쉽게 porting 될 수 있기 때문에 예전에 데스크탑으로 개발된 Qt버전을 Embedded Linux Application으로 쉽게 포팅할 수 있다. X윈도우 시스템이 필요없기 때문에 X 윈도우 시스템이 잡는 메모리와 리소스를 절약할 수 있는 Embedded분야에서 유리하다. Sharp 의 자우루스와 같은 PDA용이나 기타 다른 Embedded장비들에서 사용되고 있다 Qt/Embedded Memory와 CPU 등의 resource의 부담이 많은 Embedded system에 탑재되기 위한 개발된 version으로 모든 GUI function을 제공하기 때문에 X11 or Motif 같은 라이브러리가 필요 없다. 현재 Embedded Linux 장비에서 사용된다 Qtopia Qt/Embedded에 기반을 둔 PDA, palmtop computer등의 기기에 탑재되는 Window Management로 데스크탑 Linux에서의 Gnome과 KDE와 같은 기능을 한다

234 2. 실습 QT 포팅 개요 많이 포팅되어 사용되고 있는 QT3를 사용하지 않고 QT4를 선택한 가장 큰 이유는 터치 스크 린 때문이다. 기존의 QT3에서의 터치 스크린은 임베디드 시스템에서 Character 디바이스만 지원 하고 Input 디바이스는 지원되지 않는다. X-HYPER320TKU의 터치 스크린 타입은 Input 디바이 스이기 때문에 임베디드 시스템의 필수 입력장치인 터치 스크린을 지원하기 위해서는 TSLIB의 안정적인 연동을 지원하는 QT4가 필요하다. 물론 QT3에 TSLIB를 연동하여 사용할 수 있게끔 되어 있는 여러 패치 버전이 있기는 하나 아무래도 안정성 측면에서는 신뢰할만한 수준은 되지 못한다. 또 다른 이유는 arm-linux-gcc 버전의 의존성 문제이다. QT3는 arm-linux-gcc 3.4.x 버전에서 적절하게 컴파일 되도록 소스가 구성되어 있다. X-HYPER320TKU에서 사용되는 arm-linux-gcc 버전은 4.1.1로서 가장 최근버전에 가깝다. 이러한 상위 버전을 토대로 QT3를 컴파일 할 경우 미스매치로 인한 오류가 발생하게 된다. 이 부분도 마찬가지로 QT3의 오류가 발 생하는 부분에 대해 업그레이드 소스 패치를 수행해서 문제를 해결할 수도 있기는 하지만, 언젠 가는 문제의 소지가 있을 수 있으므로 차라리 QT4 버전을 사용하는 것이 낫겠다. QT4는 arm-linux-gcc 이후 버전으로 컴파일 하기에 적합하다. 별도의 소스 수정 없이 Configuration과 Make를 수행만 한다면 문제없이 컴파일이 될 것이다. QT 다운로드 설치를 하기 위해서는 임베디드용 QT 소스가 필요하다. 다운로드 경로는 다음과 같다. /qt/source로 들어간 후 qtopia-core-opensource-src tar.gz 파일을 다운로드 한다. 또한, 제공된 CD의 Application/QT4/ 디렉토리내에 제공된다. (ftp://ftp.trolltech.com/qt/source/) FTP 주소 : ftp://ftp.trolltech.com/

235 QT 설치 위치 설치 위치는 아래와 같다. 타겟 보드는 PXA320 CPU가 탑재 된 X-Hyper320 TKU이고 QT4의 버전은 4.3.4이다. 설치 내용 설치 위치 설명 ARM Core를 위한 QT /mnt/nfs/qt4-arm ARM Core 용으로 컴파일 된 QT4 ARM용 QT 설치 다운로드한 압축파일을 적당한 위치에서 압축해제 한다. 그리고 작업의 편의를 위해 디렉토리 이름 변경 및 설치 환경 설정 파일을 생성한다. 제공되는 CD의 Application/QT4 디렉토리 아 래에는 이미 컴파일을 마친 qt4-em 이란 디렉토리가 있다 컴파일이 안되거나 에러를 잡지 못 하는 경우 이 디렉토리를 이용하여 작업해도 무방하다. ]# tar zxvf qtopia-core-opensource-src tar.gz --압축해제 ]# mv qtopia-core-opensource-src qt4-arm -- 디렉토리 이름변경 ]# cd qt4-arm -- 경로이동 ]# vi config-arm -- config-arm 파일생성편집 압축 해제 후 아래의 옵션에 맞추어 설치 환경을 설정한다. VI 편집기에서 아래와 같이 정확히 입력해야 한다. 일부 시스템에서 -prefix 경로 오류가 발생하 는 경우가 있는데 이런 경우 /mnt/nfs/qt4-arm 경로를 다른 임의의 경로로 바꾸어 주고 실행 한다../configure -prefix /mnt/nfs/qt4-arm -embedded arm -little-endian -release -no-largefile -no-accessibilligmaty -no-qt3support -qt-zlib -qt-gif -qt-libpng -no-libmng -qt-libjpeg -qt-mouse-tslib -no-nis -qt-freetype -depths 16,24,

236 ]# export PATH=$PATH:/usr/local/arm-linux-4.1.1/bin ]#./config-arm This is the Qtopia Core Open Source Edition. You are licensed to use this software under the terms of the GNU General Public License (GPL) versions 2 or 3. Type '2' to view the GNU General Public License version 2. Type '3' to view the GNU General Public License version 3. Type 'yes' to accept this license offer. Type 'no' to decline this license offer. Do you accept the terms of the license? yes <-- yes를 입력한다. Choose pixel-depths to suport: 1. 1bpp black/white 4. 4bpp grayscale 8. 8bpp bpp bpp bpp ]# 16 --중략-- --중략-- Qt is now configured for building. Just run 'gmake'. Once everything is built, you must run 'gmake install'. Qt will be installed into /mnt/nfs/qt4-arm To reconfigure, run 'gmake confclean' and 'configure'. ]# gmake --중략-- gmake[2]: Leaving directory `/home/kjlee/320tku/qt4-arm/qtopia-core-opensource-src-4.3.4/demos/undo' gmake[1]: Leaving directory `/home/kjlee/320tku/qt4-arm/qtopia-core-opensource-src-4.3.4/demos' ]# gmake install --중략-- ]# cd /mnt/nfs/qt4-arm 설치까지 완료하였다. 마지막으로 qt로 이동하여 정확히 인스톨 되었는지 확인을 하도록 한다

237 타겟 보드에서 작업 Host에서의 작업은 모두 완료 하였다. 이제 타겟 보드에서 QT4를 포팅하기 위한 작업을 할 것 이다. 포팅방법은 NFS를 이용한 방법과 직접 라이브러리 파일과 데모용 프로그램을 타겟보드의 파일시스템에 직접 다운로드하는 방법이 있다. 여기서는 NFS를 이용하여 다운로드 하도록 하겠 다. 시스템 상황에 따라 NFS설정이 안되거나 불편한 경우 다른 방법들을 이용하여 파일을 타겟 보드에 복사하여도 상관없다. 먼저 타겟보드에서 Host와의 IP 대역을 맞추도록 설정한다. 그리고 Host의 NFS 공유 디렉토리를 마운트 한다. 아래의 설정 IP는 임의로 지정한 것이다. 320TKU]# ifconfig eth netmask TKU]# route add -net default gw TKU]# mount -t nfs -o nolock :/mnt/nfs /mnt/nfs NFS 설정하기 HOST 서버 설정 (가상 ip주소를 사용한 예) HOST PC(NFS서버) IP : 서버 공유할 디렉토리 : /mnt/nfs 클라이언트 IP : 클라이언트 마운트 디렉토리 /mnt/nfs 1. /etc/exports 설정(원래 없는 파일이므로 vi 편집기를 이용해 열어서 저장한다) ]#vi /etc/exports --vi 편집기로 exports라는 이름으로 저장될 빈문서가 열린다. /mnt/nfs (rw) <- 한 줄 추가하고 저장하고 나옴 첫번째 /mnt/nfs는 외부에 마운트를 허용할 디렉토리를 뜻하고 네트워크 주소는 접근을 허용할 호스트 번호를 의미한다. 2. 데몬 실행 다음과 같이 데몬을 실행한다. ]# service portmap start ]# service nfs start ]# service nfslock start 3.다음의 명령어로 데몬이 제대로 실행중인지 확인한다. ]# rpcinfo -p

238 클라이언트 설정 다음과 같은 명령어로 마운트 한다. 320TKU]#mount -t nfs -o nolock :/mnt/nfs /mnt/nfs :/mnt/nfs는 마운트를 할 원격지 서버IP와 디렉토리를 정의한다. 마지막 /mnt/nfs는 마운트를 할 로컬 디렉토리이다. 호스트 PC의 /mnt/nfs를 타rpt보드 의 /mnt/nfs에 마운트를 하겠다는 뜻이다. 마운트 디렉토리로 이동하여 확인해 보면 문서파일 과 데모파일 인클루드 파일등도 같이 있는 것을 알 수 있는데 실제 QT4용 프로그램을 실행하는데 필요한 것은 라이브러리와 데모할 프로 그램의 바이너리뿐이다. 그리고 라이브러리 디렉토리 밑에 fonts 디렉토리가 있는데 중국어 폰트는 용량만 차지하고 불 필요하므로 삭제 한다. 중국어 폰트의 파일명은 wenquanyi로 시작하는 파일들이다. 라이브러리 파일들을 /lib 밑으로 복사를 한다. 데모용 프로그램은 examples/tutorial/t14로 이동하면 t14라는 실행파일이 있을 것이다. 기타 디렉토리에도 실행파일들이 들어있다. 타겟보드의 파일시-스템 상에 /root/test_app 디렉토 리에 t14를 복사한다. 그 다음 TSLIB Device를 QT4에서 사용하도록 export를 해야 한다. 320TKU]# export QWS_MOUSE_PROTO=tslib:$TSLIB_TSDEVICE 마지막으로 폰트 경로를 설정해준다. 320TKU]# export QT_QWS_FONTDIR=/lib/fonts

239 QT 데모 프로그램 실행 아래와 같은 방법으로 어플리케이션이 있는 디렉토리로 이동한 다음 실행파일을 실행해 보다 예 제로 t14를 실행해본다. 정상적으로 동작되면 호스트 PC의 examples/tutorial/디렉토리 내에 있 는 다른 디렉토리의 실행파일을 복사하여 실행하여 보자 320TKU]# cd /root/test_app 320TKU]#./t14 -qws

240 Chapter 12. 리눅스 기반의 무선 NAT 라우터 구축 1. 개요 이 장에서는 리눅스 기반의 X-HYPER320 TKU를 타겟으로 무선 NAT 라우터 구축에 대한 방법 을 실습해보도록 하겠다. 방법에 있어서는 무선 랜 네트워크 설정만 빼고 유선 랜을 사용하여 라우터를 구축하는 방법과 거의 비슷하다. 2. 실습 NAT 개요 NAT란 Nework Address Translation의 약자로 내부의 네트워크 망의 IP대역과 외부 네트워크 망 의 IP대역을 연결시키기 위해 내부 IP를 공인 IP로 또는 공인 IP를 내부 IP대역으로 상호 변환시 키는 기능을 일컫는다. 이러한 주소 변환과정에서 요구제한이나 인증과 같은 보안문제를 확실하 게 하는데 도움이 된다. NAT는 라우터 기능의 일부로서 포함되며, 방화벽의 일부가 되기도 한 다. NAT의 주요 기능을 정리하면 다음과 같다. - 사설 IP를 정적인 하나의 공인 IP주소로 변환 - 사설 IP를 회사가 가질 수 있는 공인 IP주소들 중 하나와 맵핑 - 사설 IP주소에 특정 TCP 포트를 더한 것을 하나의 공인 IP주소로 변환 - 공인 IP주소를 사설 IP주소들 중 하나로 변환 NAT 구축에 필요한 준비사항 - 320TKU Linux Kernel v iptables arm.tgz (CD에 포함) NAT를 위한 커널 설정 제공되는 CD의 커널 이미지를 올렸다면 아래의 커널 컴파일은 별도로 진행하지 않아도 된다. 만일 다른 커널을 사용하고 있다면 아래와 같은 방법으로 커널을 재 컴파일 해서 타겟보드에 올 린다. 가장 먼저 해야 할 부분은 커널의 Re-configuration이다. Networking support 부분에서 Packet Filtering이나 FULL NAT와 같은 기능이 커널에서 기본적으로 지원이 되어야 한다. 320TKU 커널 소스에서 Configuration을 수행한다. ]# make xhyper320tku_defconfig make menuconfig을 실행하여 Configuration 모드로 진입한다. ]# make menuconfig

241 처음 화면에서 [Networking support]를 선택한다

242 [Networking support]를 체크하고 [Networking options]를 선택한다

243 다음과 같이 해당 옵션들을 확인 후 [Network packet filtering]을 선택한다

244 다음 화면같이 해당 항목을 체크하고 [IP: Netfilter Configuration]를 선택한다

245 다음과 같은 옵션들을 체크한다. <*> Connection tracking (required for masq/nat) <*> IP tables support (required for filtering/masq/nat) <*> Packet filtering <*> Full NAT <*> MASQUERADE target support

246 상기 항목들을 선택함으로써 NAT를 지원하게 되었다. 변경된 커널 설정사항을 저장하고 새로운 커널 이미지를 생성하여 타겟보드에 포팅한다. 이로서 커널관련 NAT 설정은 모두 마쳤으며 타겟보드의 커널 부팅 후 파일시스템에서 NAT 설 정을 위한 툴인 iptables를 설치하도록 하겠다. NAT 구축을 위한 iptables 유틸리티 iptables는 버전을 사용하였고 미리 ARM용으로 빌드를 해 놓았다. 제공되는 CD에 포함되어 있는 파일을 사용하면 된다. (경로 : Application/NAT_Router/iptables arm.tgz) iptables 설치 압축파일을 파일시스템에 적재한다. Z-MODEM이나 FTP를 사용하여 타겟보드의 파일시스템의 최상위 디렉토리에 다운로드한 후에 압축을 해제한다. 320TKU]# tar xzf iptables arm.tgz

247 먼저 iptables를 실행하여 사용가능한 옵션들을 살펴보자. 320TKU]# iptables --help 다음과 같이 옵션들을 확인할 수 있다

248 타겟보드의 네트워크 설정 타겟보드의 eth0는 외부 네트워크 망으로 연결을 위해 공인 IP를 가질 것이고 eth1은 내부 네트 워크를 위한 사설 IP를 할당할 것이다. 공인 IP는 사용자의 환경에 따라 달라지기 때문에 사용할 수 있는 반드시 가용 IP를 사용하도록 한다. 먼저 eth0 인터페이스부터 설정을 한다. 여기서 설정하는 네트워크 환경은 하나의 예시에 불과하다 각자 환경에 맞는 설정을 하도록 한 다. 320TKU]# ifconfig eth netmask TKU]# route add -net default gw eth0 같은 대역의 공인 IP로 Ping 테스트를 해본다. 320TKU]# ping 로컬PC와의 연결에 사용될 무선 랜 네트워크 설정을 한다. 320TKU]# iwconfig eth2 mode ad-hoc 320TKU]# iwconfig eth2 essid hybus 320TKU]# ifconfig eth 그리고 Network IP 환경 설정을 위해 /etc 밑에 있는 설정파일들을 수정한다. 320TKU]# vi /etc/sysconfig/network 게이트웨이 항목을 삭제한다

249 /etc/sysconfig/network-scripts/ifcfg-eth0에서 타겟보드의 eth0에 해당사항을 입력한다. 320TKU]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/resolv.conf 파일에 DNS의 IP를 적도록 한다. 320TKU]# vi /etc/resolv.conf 여기까지 무선 NAT 라우터 기능을 하게 될 타겟보드에 대한 네트워크 설정을 마쳤다

250 로컬PC의 무선 네트워크 설정 여기서는 USB 타입의 무선 랜 WL-54G를 사용하겠다. 물론 다른 종류의 무선 랜을 사용해도 무 방하다. 사용방법만 다를 뿐이지 절차에 있어서는 비슷하다. 하나의 예로서 설명하는 것이니 참 고만 하도록 한다. 설치 CD를 넣고 드라이버 및 유틸리티 설치를 진행한다. 설치가 완료되었으면 무선 랜을 로컬 PC의 USB 단자에 연결한다. 다음과 같이 유틸리티가 나타난다. Mode를 Station으로 변경하고, Refresh를 클릭한다

251 이 중에서 "hybus"로 된 SSID를 찾아서 오른쪽의 [Connect this site] 버튼을 클릭한다. 성공적으로 연결이 되면 다음과 같이 접속 상태를 보여주게 된다. 일반적으로 'WindowsXP'의 사용자의 경우는 다른 무선 네트워크 카드를 사용하더라도 다음과 같이 설정하면 된다. 무선랜카드가 설치가 되어 있으면 우측하단에 무선네트워크가 모니터링 된다. 다른 방법으로는 내 네트워크 환경설정에서 무선랜카드를 오른쪽 마우스로 클릭하면 된다

252 다음과 같이 앞에서 설정한 네트워크가 보이는지 확인하고 만일 보이지 않는다면 네트워크 목 록 새로 고침을 통해 주변의 무선네트워크를 새로이 검색한다. 네트워크가 검색이 되면 해당 네트워크(hybus)를 선택하고 연결을 눌러 접속을 시도한다

253 무선네트워크에 성공적으로 연결이 되면 아래와 같이 로컬 PC의 무선 네트워크를 설정한다. 타 겟보드의 무선네트워크와 동일 대역의 사설 IP를 입력하고 게이트웨이는 타겟보드의 eth2에 설 정한 IP를 입력한다. DNS 서버 주소는 타겟보드에서 연결되는 공인 IP의 DNS 서버 주소를 입력 한다. 즉 타겟보드의 eth2는 우리가 일반적으로 사용하는 무선 공유기역할을 하게 되는것이다

254 네트워크에 대한 대부분의 설정을 마치고 NAT 기능 설정만 남았다. iptables 유틸리티를 이용하여 아래와 같이 설정을 하고 iptables-save로 저장을 한다. 320TKU]# iptables -P INPUT ACCEPT 320TKU]# iptables -P OUTPUT ACCEPT 320TKU]# iptables -P FORWARD ACCEPT 320TKU]# echo 1 > /proc/sys/net/ipv4/ip_forward 320TKU]# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 320TKU]# iptables-save iptables-save를 입력하면 아래와 같이 설정내용이 출력된다. NAT 테스트 및 결과 Connection 및 NAT 설정이 정확히 이루어 졌는지 확인을 위해 다음과 Ping 테스트를 수행한다. 320TKU]# ping 대역이 다른 외부 네트워크의 공인 IP

255 320TKU]# ping 접속할 로컬 PC(windows 환경)의 명령입력창에서 ping test 를 해본다. 시작 => 실행 => cmd" 입력 -- cmd 실행 > ping 지금까지 설정한 타겟보드의 네트워크에 Ping테스트

256 정상적으로 핑테스트가 이루어지면 마지막으로 무선랜카드가 연결된 로컬PC에서 실제로 웹브라우저를 이용하여 웹 서핑을 해본다. 하이버스 홈페이지에도 접속해 본다

슬라이드 1

슬라이드 1 사용 전에 사용자 주의 사항을 반드시 읽고 정확하게 지켜주시기 바랍니다. 사용설명서의 구성품 형상과 색상은 실제와 다를 수 있습니다. 사용설명서의 내용은 제품의 소프트웨어 버전이나 통신 사업자의 사정에 따라 다를 수 있습니다. 본 사용설명서는 저작권법에 의해 보호를 받고 있습니다. 본 사용설명서는 주식회사 블루버드소프트에서 제작한 것으로 편집 오류, 정보 누락

More information

<4D6963726F736F667420506F776572506F696E74202D20C0BDBCBA484D4920C0FBBFEB20C5DAB7B9B8C5C6BDBDBA20B4DCB8BBB1E228B9DFC7A5C0DAB7E129>

<4D6963726F736F667420506F776572506F696E74202D20C0BDBCBA484D4920C0FBBFEB20C5DAB7B9B8C5C6BDBDBA20B4DCB8BBB1E228B9DFC7A5C0DAB7E129> Terminal Platform 권오일 ([email protected]) 현대오토넷 목차 1. 텔레매틱스 시스템 개요 P3 2. 텔레매틱스 단말기 개요 P4 3. 텔레매틱스 단말기 하드웨어 P9 4. 텔레매틱스 단말기 소프트웨어 P15 5. 음성 HMI 적용 전체 시나리오 P22 6. 향후 계획 P26 2 1. 텔레매틱스 시스템 개요 3 Block Diagram

More information

ESP1ºÎ-04

ESP1ºÎ-04 Chapter 04 4.1..,..,.,.,.,. RTOS(Real-Time Operating System)., RTOS.. VxWorks(www.windriver.com), psos(www.windriver.com), VRTX(www.mento. com), QNX(www.qnx.com), OSE(www.ose.com), Nucleus(www.atinudclus.

More information

<4D F736F F F696E74202D20454D43BCB3B0E8B4EBC3A5BBE7B7CA2828C1D629B8B6B7E7C0CEC6F75FBDC5C1D6C8A3292E707074>

<4D F736F F F696E74202D20454D43BCB3B0E8B4EBC3A5BBE7B7CA2828C1D629B8B6B7E7C0CEC6F75FBDC5C1D6C8A3292E707074> 제품에대한 EMC 설계 대책사례 마루인포 신주호선임 2009. 5. 29 목차 1. Network Camera System 2. Navigation 2-1. PND (Portable Navigation Device) 2-2. AVN (Audio Video Navigation) 2 1. Network Camera System 1. U-City 주차관리시스템 그림

More information

안전을 위한 주의사항 제품을 올바르게 사용하여 위험이나 재산상의 피해를 미리 막기 위한 내용이므로 반드시 지켜 주시기 바랍니다. 2 경고 설치 관련 지시사항을 위반했을 때 심각한 상해가 발생하거나 사망에 이를 가능성이 있는 경우 설치하기 전에 반드시 본 기기의 전원을

안전을 위한 주의사항 제품을 올바르게 사용하여 위험이나 재산상의 피해를 미리 막기 위한 내용이므로 반드시 지켜 주시기 바랍니다. 2 경고 설치 관련 지시사항을 위반했을 때 심각한 상해가 발생하거나 사망에 이를 가능성이 있는 경우 설치하기 전에 반드시 본 기기의 전원을 Digital Video Recorder 간편설명서 XD3316 안전을 위한 주의사항 제품을 올바르게 사용하여 위험이나 재산상의 피해를 미리 막기 위한 내용이므로 반드시 지켜 주시기 바랍니다. 2 경고 설치 관련 지시사항을 위반했을 때 심각한 상해가 발생하거나 사망에 이를 가능성이 있는 경우 설치하기 전에 반드시 본 기기의 전원을 차단하고, 전원 플러그를 동시에

More information

슬라이드 제목 없음

슬라이드 제목 없음 < > Target cross compiler Target code Target Software Development Kit (SDK) T-Appl T-Appl T-VM Cross downloader Cross debugger Case 1) Serial line Case 2) LAN line LAN line T-OS Target debugger Host System

More information

hd1300_k_v1r2_Final_.PDF

hd1300_k_v1r2_Final_.PDF Starter's Kit for HelloDevice 1300 Version 11 1 2 1 2 3 31 32 33 34 35 36 4 41 42 43 5 51 52 6 61 62 Appendix A (cross-over) IP 3 Starter's Kit for HelloDevice 1300 1 HelloDevice 1300 Starter's Kit HelloDevice

More information

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션 (Host) set up : Linux Backend RS-232, Ethernet, parallel(jtag) Host terminal Target terminal : monitor (Minicom) JTAG Cross compiler Boot loader Pentium Redhat 9.0 Serial port Serial cross cable Ethernet

More information

Microsoft Word - FS_ZigBee_Manual_V1.3.docx

Microsoft Word - FS_ZigBee_Manual_V1.3.docx FirmSYS Zigbee etworks Kit User Manual FS-ZK500 Rev. 2008/05 Page 1 of 26 Version 1.3 목 차 1. 제품구성... 3 2. 개요... 4 3. 네트워크 설명... 5 4. 호스트/노드 설명... 6 네트워크 구성... 6 5. 모바일 태그 설명... 8 6. 프로토콜 설명... 9 프로토콜 목록...

More information

Mango220 Android How to compile and Transfer image to Target

Mango220 Android How to compile and Transfer image to Target Mango220 Android How to compile and Transfer image to Target http://www.mangoboard.com/ http://cafe.naver.com/embeddedcrazyboys Crazy Embedded Laboratory www.mangoboard.com cafe.naver.com/embeddedcrazyboys

More information

10X56_NWG_KOR.indd

10X56_NWG_KOR.indd 디지털 프로젝터 X56 네트워크 가이드 이 제품을 구입해 주셔서 감사합니다. 본 설명서는 네트워크 기능 만을 설명하기 위한 것입니다. 본 제품을 올바르게 사 용하려면 이 취급절명저와 본 제품의 다른 취급절명저를 참조하시기 바랍니다. 중요한 주의사항 이 제품을 사용하기 전에 먼저 이 제품에 대한 모든 설명서를 잘 읽어 보십시오. 읽은 뒤에는 나중에 필요할 때

More information

KDTÁ¾ÇÕ-1-07/03

KDTÁ¾ÇÕ-1-07/03 CIMON-PLC CIMON-SCADA CIMON-TOUCH CIMON-Xpanel www.kdtsys.com CIMON-PLC Total Solution for Industrial Automation PLC (Program Logic Controller) Sphere 8 Total Solution For Industrial Automation PLC Application

More information

전자교탁 사양서.hwp

전자교탁 사양서.hwp 사 양 서 품 목 단 위 수량 SYSTEM CONSOLE EA 32 - 사용자에 따른 타블렛 모니터 저소음 전동 각도 조절기능이 내장된 교탁 - 교탁 상/하부 별도의 조립이 필요 없는 일체형(All in One type) CONSOLE - 상판에 리미트 센서를 부착하여 장비 및 시스템의 안정성 강화 - 금형으로 제작, 슬림하고 견고하며 마감이 깔끔한 미래지향적

More information

Flute-GR_BV199_DOS.indb

Flute-GR_BV199_DOS.indb 안전을 위한 주의사항 사용자의 안전을 지키고 재산상의 손해 등을 막기 위한 내용입니다. 반드시 읽고 올바르게 사용해 주세요. BV-199 사용설명서 차례 1 장. 컴퓨터 시작 차례 3 제품의 특장점 6 사용설명서를 읽기 전에 7 안전을 위한 주의사항 10 사용시 올바른 자세 20 제품의 구성물 23 기본 구성물 23 각 부분의 명칭 24 앞면 24 뒷면 25

More information

Microsoft Word - MV210_CPUSpec.doc

Microsoft Word - MV210_CPUSpec.doc Hardware Specification Brief 마이크로비젼 / Microvision 서울특별시구로구구로 3 동 235 번지한신 IT 타워 1004 호 ( 전화 ) 02-3283-0101, ( 팩스 ) 02-3283-0160 (Web) http://www.microvision.co.kr Copyright 2011 Microvision 1 Contents

More information

Contents I. 칼라스 네트워크 플레이어란 1. Pc-Fi를 넘어서 발전한 차세대 음악 플레이어 ---------------- 4 2. 칼라스 네트워크 플레이어의 장점 3. 시스템 기본 구성 ------------------------ 6 -------------

Contents I. 칼라스 네트워크 플레이어란 1. Pc-Fi를 넘어서 발전한 차세대 음악 플레이어 ---------------- 4 2. 칼라스 네트워크 플레이어의 장점 3. 시스템 기본 구성 ------------------------ 6 ------------- [ CALLAS Network Player ] Owner s Manual ( 주 ) 금 잔 디 음 향 예.술.을.담.는.스.피.커.과.학 Contents I. 칼라스 네트워크 플레이어란 1. Pc-Fi를 넘어서 발전한 차세대 음악 플레이어 ---------------- 4 2. 칼라스 네트워크 플레이어의 장점 3. 시스템 기본 구성 ------------------------

More information

2005 2004 2003 2002 2001 2000 Security Surveillance Ubiquitous Infra Internet Infra Telematics Security Surveillance Telematics Internet Infra Solutions Camera Site (NETWORK) Monitoring & Control

More information

목차 제 1 장 inexio Touch Driver소개... 3 1.1 소개 및 주요 기능... 3 1.2 제품사양... 4 제 2 장 설치 및 실행... 5 2.1 설치 시 주의사항... 5 2.2 설치 권고 사양... 5 2.3 프로그램 설치... 6 2.4 하드웨

목차 제 1 장 inexio Touch Driver소개... 3 1.1 소개 및 주요 기능... 3 1.2 제품사양... 4 제 2 장 설치 및 실행... 5 2.1 설치 시 주의사항... 5 2.2 설치 권고 사양... 5 2.3 프로그램 설치... 6 2.4 하드웨 최종 수정일: 2010.01.15 inexio 적외선 터치스크린 사용 설명서 [Notes] 본 매뉴얼의 정보는 예고 없이 변경될 수 있으며 사용된 이미지가 실제와 다를 수 있습니다. 1 목차 제 1 장 inexio Touch Driver소개... 3 1.1 소개 및 주요 기능... 3 1.2 제품사양... 4 제 2 장 설치 및 실행... 5 2.1 설치 시

More information

OfficeServ 솔루션 OfficeServ 솔루션 OfficeServ는 삼성전자의 기업형 IP 솔루션으로서 음성과 데이터, 유선과 무선이 융합된 미래 오피스형 솔루션입니다. OfficeServ 7400/7200 삼성전자가 다년간 쌓아 온 기간망 사업 경험 및 모바일

OfficeServ 솔루션 OfficeServ 솔루션 OfficeServ는 삼성전자의 기업형 IP 솔루션으로서 음성과 데이터, 유선과 무선이 융합된 미래 오피스형 솔루션입니다. OfficeServ 7400/7200 삼성전자가 다년간 쌓아 온 기간망 사업 경험 및 모바일 Unlimited Connectivity, Enterprise Convergence Unlimited Connectivity, Enterprise Convergence SMB IP 중소용량 IP-PBX SYSTEM Solution 네트워크사업부 Enterprise 영업팀 경기도 수원시 영통구 삼성로 129 E-mail : [email protected]

More information

인켈(국문)pdf.pdf

인켈(국문)pdf.pdf M F - 2 5 0 Portable Digital Music Player FM PRESET STEREOMONO FM FM FM FM EQ PC Install Disc MP3/FM Program U S B P C Firmware Upgrade General Repeat Mode FM Band Sleep Time Power Off Time Resume Load

More information

Microsoft Word - HD-35 메뉴얼_0429_.doc

Microsoft Word - HD-35 메뉴얼_0429_.doc 자주 묻는 질문들...2 제품의 특장점...3 안전을 위한 주의사항...5 사용을 위한 주의사항...5 각 부분의 이름...6 HD-35 조립/분리하기...7 PC와 USB 케이블 연결하기...8 1. 윈도우 98/ME에서 설치과정...9 2. NTFS를 FAT32 포맷방식으로 바꾸기...11 설치 및 연결하기...14 1. 비디오 연결방법...14 2. 오디오

More information

Microsoft PowerPoint - User Manual-100 - 20150521.pptx

Microsoft PowerPoint - User Manual-100 - 20150521.pptx CIC-100 사용 설명서 (User Manual) 나의 커뮤니티, 보는 이야기 TocView [모델명 : CIC-100] 주의사항 매뉴얼의 내용은 서비스 향상을 위하여 개별 사용자의 사전 동의 또는 별도의 공지 없이 변경될 수 있습니다. 사용자의 인터넷 환경에 따라 제품 성능 및 기능의 제작 또는 사용이 불가능할 수 있습니다. 본 제품의 이용 중 장애에 의하여

More information

<목 차 > 제 1장 일반사항 4 I.사업의 개요 4 1.사업명 4 2.사업의 목적 4 3.입찰 방식 4 4.입찰 참가 자격 4 5.사업 및 계약 기간 5 6.추진 일정 6 7.사업 범위 및 내용 6 II.사업시행 주요 요건 8 1.사업시행 조건 8 2.계약보증 9 3

<목 차 > 제 1장 일반사항 4 I.사업의 개요 4 1.사업명 4 2.사업의 목적 4 3.입찰 방식 4 4.입찰 참가 자격 4 5.사업 및 계약 기간 5 6.추진 일정 6 7.사업 범위 및 내용 6 II.사업시행 주요 요건 8 1.사업시행 조건 8 2.계약보증 9 3 열차운행정보 승무원 확인시스템 구축 제 안 요 청 서 2014.6. 제 1장 일반사항 4 I.사업의 개요 4 1.사업명 4 2.사업의 목적 4 3.입찰 방식 4 4.입찰 참가 자격 4 5.사업 및 계약 기간 5 6.추진 일정 6 7.사업 범위 및 내용 6 II.사업시행 주요 요건 8 1.사업시행 조건 8 2.계약보증 9 3.시운전 및 하자보증 10

More information

1217 WebTrafMon II

1217 WebTrafMon II (1/28) (2/28) (10 Mbps ) Video, Audio. (3/28) 10 ~ 15 ( : telnet, ftp ),, (4/28) UDP/TCP (5/28) centralized environment packet header information analysis network traffic data, capture presentation network

More information

KDTÁ¾ÇÕ-2-07/03

KDTÁ¾ÇÕ-2-07/03 CIMON-PLC CIMON-SCADA CIMON-TOUCH CIMON-Xpanel www.kdtsys.com CIMON-SCADA Total Solution for Industrial Automation Industrial Automatic Software sphere 16 Total Solution For Industrial Automation SCADA

More information

MAX+plus II Getting Started - 무작정따라하기

MAX+plus II Getting Started - 무작정따라하기 무작정 따라하기 2001 10 4 / Version 20-2 0 MAX+plus II Digital, Schematic Capture MAX+plus II, IC, CPLD FPGA (Logic) ALTERA PLD FLEX10K Series EPF10K10QC208-4 MAX+plus II Project, Schematic, Design Compilation,

More information

VZ94-한글매뉴얼

VZ94-한글매뉴얼 KOREAN / KOREAN VZ9-4 #1 #2 #3 IR #4 #5 #6 #7 ( ) #8 #9 #10 #11 IR ( ) #12 #13 IR ( ) #14 ( ) #15 #16 #17 (#6) #18 HDMI #19 RGB #20 HDMI-1 #21 HDMI-2 #22 #23 #24 USB (WLAN ) #25 USB ( ) #26 USB ( ) #27

More information

DE1-SoC Board

DE1-SoC Board 실습 1 개발환경 DE1-SoC Board Design Tools - Installation Download & Install Quartus Prime Lite Edition http://www.altera.com/ Quartus Prime (includes Nios II EDS) Nios II Embedded Design Suite (EDS) is automatically

More information

PLC Robot Starter Quick Guide

PLC Robot Starter Quick Guide KOR V1.3 PLC Robot Starter Quick Guide Web: www.altsoft.kr E-mail: [email protected] Tel: 02-547-2344 Features AltPLC BeagleBone Processor - TI Sitara AM3358/3359-1 GHz ARM Cortex-A8-32 Bit RISC Processor,

More information

DWCOM15/17_manual

DWCOM15/17_manual TFT-LCD MONITOR High resolution DWCOM15/17 DIGITAL WINDOW COMMUNICATION DIGITAL WINDOW COMMUNICATION 2 2 3 5 7 7 7 6 (Class B) Microsoft, Windows and Windows NT Microsoft VESA, DPMS and DDC Video Electronic

More information

Microsoft Word - JAVS_UDT-1_상세_메뉴얼.doc

Microsoft Word - JAVS_UDT-1_상세_메뉴얼.doc UDT-1 TRANSPORTER 한글 상세 제품 설명서 SoundPrime. 저작권 본 저작권은 Soundprime 이 소유하고 있습니다. Soundprime 의 허가 없이 정보 검색 시스템상에서 복사, 수정, 전달, 번역, 저장을 금지하며, 컴퓨터언어나 다른 어떠한 언어로도 수정될 수 없습니다. 또한 다른 형식이나 전기적, 기계적, 자기적, 광학적, 화학적,

More information

CONTENTS 목차 1. 전원 및 설치시 주의사항 2 2. 시스템 사용시 바른 자세 4 3. 시스템 구성품 확인 5 슬림형 케이스1 6 슬림형 케이스2 7 타워형 케이스1 8 타워형 케이스2 9 일체형 케이스1 10 망분리형 케이스1 11 4. 시스템 시작 및 종료

CONTENTS 목차 1. 전원 및 설치시 주의사항 2 2. 시스템 사용시 바른 자세 4 3. 시스템 구성품 확인 5 슬림형 케이스1 6 슬림형 케이스2 7 타워형 케이스1 8 타워형 케이스2 9 일체형 케이스1 10 망분리형 케이스1 11 4. 시스템 시작 및 종료 오리온 알토는 Windows 7을 권장합니다. DESKTOP PC 이 기기는 가정용(B급)으로 전자파적합기기로서 주로 가정에서 사용하는 것을 목적으로 하며, 모든 지역에서 사용할 수 있습니다. * 제품 연결 및 작동 등 올바른 사용을 위해서 이 설명서를 주의 깊게 읽어 주시기 바랍니다. 또한, 향후 사용을 위해서 매뉴얼을 보관하여 주십시오. * 본 이미지는

More information

목 차 1. 안전을 위한 주의사항 2. 사 전에 2-1. 제품 특징 2-2. 제품 구성 2-3. 각 부분의 명칭 2 4 5 6 7 3-11. 전 뷰어 / 뷰어 설정 3-12. 전 뷰어 / 환경 설정 3-13. 환경설정 본 값 3-14. 재생방법 (블랙박스) 3-15.

목 차 1. 안전을 위한 주의사항 2. 사 전에 2-1. 제품 특징 2-2. 제품 구성 2-3. 각 부분의 명칭 2 4 5 6 7 3-11. 전 뷰어 / 뷰어 설정 3-12. 전 뷰어 / 환경 설정 3-13. 환경설정 본 값 3-14. 재생방법 (블랙박스) 3-15. 사설명서 http://www.innopix.kr 목 차 1. 안전을 위한 주의사항 2. 사 전에 2-1. 제품 특징 2-2. 제품 구성 2-3. 각 부분의 명칭 2 4 5 6 7 3-11. 전 뷰어 / 뷰어 설정 3-12. 전 뷰어 / 환경 설정 3-13. 환경설정 본 값 3-14. 재생방법 (블랙박스) 3-15. 재생방법 (일반 동영상 플레이어) 3-16.

More information

1. GigE Camera Interface를 위한 최소 PC 사양 CPU : Intel Core 2 Duo, 2.4GHz이상 RAM : 2GB 이상 LANcard : Intel PRO/1000xT 이상 VGA : PCI x 16, VRAM DDR2 RAM 256MB

1. GigE Camera Interface를 위한 최소 PC 사양 CPU : Intel Core 2 Duo, 2.4GHz이상 RAM : 2GB 이상 LANcard : Intel PRO/1000xT 이상 VGA : PCI x 16, VRAM DDR2 RAM 256MB Revision 1.0 Date 11th Nov. 2013 Description Established. Page Page 1 of 9 1. GigE Camera Interface를 위한 최소 PC 사양 CPU : Intel Core 2 Duo, 2.4GHz이상 RAM : 2GB 이상 LANcard : Intel PRO/1000xT 이상 VGA : PCI x

More information

untitled

untitled Huvitz Digital Microscope HDS-5800 Dimensions unit : mm Huvitz Digital Microscope HDS-5800 HDS-MC HDS-SS50 HDS-TS50 SUPERIORITY Smart Optical Solutions for You! Huvitz Digital Microscope HDS-5800 Contents

More information

CL100B_manual_kor_m.0.2.indd

CL100B_manual_kor_m.0.2.indd ULTIMATE SAMRT CAR BLACK BOX BLACKSYS CL-100B USER MANUAL 2CH Full HD Car DVR with brilliant image Simultaneous recording of front with Full HD resolution (1920x1080, 25fps) and rearview with HD resolution

More information

Microsoft Word - Automap3

Microsoft Word - Automap3 사 용 설 명 서 본 설명서는 뮤직메트로에서 제공합니다. 순 서 소개 -------------------------------------------------------------------------------------------------------------------------------------------- 3 제품 등록 --------------------------------------------------------------------------------------------------------------------------------------

More information

untitled

untitled EZ-TFT700(T) : EZ-TFT700(T) : Rev.000 Rev No. Page 2007/08/03 Rev.000 Rev.000. 2007/12/12 Rev.001 1.6 Allstech,,. EZ-TFT700(T). Allstech EZ-TFT700(T),,. EZ-TFT700(T) Allstech. < > EZ-TFT Information(13h)

More information

APOGEE Insight_KR_Base_3P11

APOGEE Insight_KR_Base_3P11 Technical Specification Sheet Document No. 149-332P25 September, 2010 Insight 3.11 Base Workstation 그림 1. Insight Base 메인메뉴 Insight Base Insight Insight Base, Insight Base Insight Base Insight Windows

More information

<4D6963726F736F667420576F7264202D2045564552554E20B4DCB8BB20C1A1B0CB20B9D720C1B6C4A120B8C5B4BABEF35F76312E335F2E646F63>

<4D6963726F736F667420576F7264202D2045564552554E20B4DCB8BB20C1A1B0CB20B9D720C1B6C4A120B8C5B4BABEF35F76312E335F2E646F63> EVERUN 단말 점검 및 조치 매뉴얼(v1.3) 2008-09-04 1. 기본 점검사항 1.1 KT WIBRO CM 프로그램 정보 1.2 장치관리자 진입경로 1.2.1 시작/제어판에서 실행 1.2.2 바탕화면에서 실행 1.3 장치 관리자에서 드라이버 확인 1.3.1 WIBRO 드라이버 확인 1.3.2 Protocol 드라이버 확인 1.4 Windows 스마트

More information

LCD Monitor

LCD Monitor LCD MONITOR quick start guide 2443BW 2443BWX ii 제품 설명 제품 구성 구성품이 모두 들어 있는지 확인한 후 누락된 제품이 있으면 구입한 대리점으로 연락해 주 세요. 구성품 이외의 별매품을 구입하려면 서비스 센터로 연락하세요. 구성품 선택 사양1 선택 사양2 모니터 & 심플 스탠드 모니터 & 심플 스탠드 심플 스탠드의 경우

More information

[8051] 강의자료.PDF

[8051] 강의자료.PDF CY AC F0 RS1 RS0 OV - P 0xFF 0x80 0x7F 0x30 0x2F 0x20 0x1F 0x18 0x17 0x10 0x0F 0x08 0x07 0x00 0x0000 0x0FFF 0x1000 0xFFFF 0x0000 0xFFFF RAM SFR SMOD - - - GF1 GF0 PD IDL 31 19 18 9 12 13 14 15 1 2 3 4

More information

CLX8380_KR.book

CLX8380_KR.book 이 사용설명서와 제품은 저작권법에 의해 보호되어 있습니다. 삼성전자 ( 주 ) 의 사전 서면 동의 없이 사용설명서 및 제품의 일부 또는 전체를 복사, 복제, 번역 또는 전자매체나 기계가 읽을 수 있는 형태로 바꿀 수 없습니다. 이 사용설명서와 제품은 표기상의 잘못이나 기술적인 잘못이 있을 수 있으며 사전 통보 없이 이러한 내용들이 변경될 수 있습니다. CLX-8380ND,

More information

0806 블랙박스 메뉴얼 L5 원고작업_수정

0806 블랙박스 메뉴얼 L5 원고작업_수정 CLON L5 USER'S MANUAL Full HD Driving Image Recorder EFL3.0mm F2.0 DRIVING IMAGE RECORDER Digital L5 Recorder 본 제품을 사용하기 전에... www.eyeclon.com 제품을 구입해 주셔서 감사합니다. (아이클론)은 엠씨넥스의 상표입니다. 엠씨넥스 설명서의 모든 내용은 저작권법에

More information

PCServerMgmt7

PCServerMgmt7 Web Windows NT/2000 Server DP&NM Lab 1 Contents 2 Windows NT Service Provider Management Application Web UI 3 . PC,, Client/Server Network 4 (1),,, PC Mainframe PC Backbone Server TCP/IP DCS PLC Network

More information

Microsoft PowerPoint - 02-Development-Environment-1.ppt

Microsoft PowerPoint - 02-Development-Environment-1.ppt 개발환경 1 임베디드시스템소프트웨어 I 차례 개발환경 Host와 Target의연결 Host 및 target 사양 Toolchain이란, 설치방법 시험 Cross Compile Minicom 설정및사용방법 JTAG 설치및사용방법 Bootloader, kernel, file system flash 방법 개발환경 1 2 개발환경 Host 시스템 임베디드소프트웨어를개발하는시스템

More information

기술 이력서 2.0

기술 이력서 2.0 Release 2.1 (2004-12-20) : : 2006/ 4/ 24,. < > Technical Resumé / www.novonetworks.com 2006.04 Works Projects and Technologies 2 / 15 2006.04 Informal,, Project. = Project 91~94 FLC-A TMN OSI, TMN Agent

More information

LCD Display

LCD Display LCD Display SyncMaster 460DRn, 460DR VCR DVD DTV HDMI DVI to HDMI LAN USB (MDC: Multiple Display Control) PC. PC RS-232C. PC (Serial port) (Serial port) RS-232C.. > > Multiple Display

More information

TEL:02)861-1175, FAX:02)861-1176 , REAL-TIME,, ( ) CUSTOMER. CUSTOMER REAL TIME CUSTOMER D/B RF HANDY TEMINAL RF, RF (AP-3020) : LAN-S (N-1000) : LAN (TCP/IP) RF (PPT-2740) : RF (,RF ) : (CL-201)

More information

다음 사항을 꼭 확인하세요! 도움말 안내 - 본 도움말에는 iodd2511 조작방법 및 활용법이 적혀 있습니다. - 본 제품 사용 전에 안전을 위한 주의사항 을 반드시 숙지하십시오. - 문제가 발생하면 문제해결 을 참조하십시오. 중요한 Data 는 항상 백업 하십시오.

다음 사항을 꼭 확인하세요! 도움말 안내 - 본 도움말에는 iodd2511 조작방법 및 활용법이 적혀 있습니다. - 본 제품 사용 전에 안전을 위한 주의사항 을 반드시 숙지하십시오. - 문제가 발생하면 문제해결 을 참조하십시오. 중요한 Data 는 항상 백업 하십시오. 메 뉴 다음 사항을 꼭 확인하세요! --------------------------------- 2p 안전을 위한 주의 사항 --------------------------------- 3p 구성품 --------------------------------- 4p 각 부분의 명칭 --------------------------------- 5p 제품의 규격

More information

Microsoft PowerPoint - eSlim SV5-2410 [20080402]

Microsoft PowerPoint - eSlim SV5-2410 [20080402] Innovation for Total Solution Provider!! eslim SV5-2410 Opteron Server 2008. 3 ESLIM KOREA INC. 1. 제 품 개 요 eslim SV5-2410 Server Quad-Core and Dual-Core Opteron 2000 Series Max. 4 Disk Bays for SAS and

More information

목차 본 취급설명서의 사용법 본 사용설명서에서는 제품상에 표시된 채널명 및 버튼명, 소프트웨어의 메뉴명 등이 대괄호 ([ ]) 안에 표시됩니 (예: [MASTER] 채널, [ON/ OFF], [File] 메뉴) 시작하시기 전에 특징...3 부속품...4 시작하시기 전에

목차 본 취급설명서의 사용법 본 사용설명서에서는 제품상에 표시된 채널명 및 버튼명, 소프트웨어의 메뉴명 등이 대괄호 ([ ]) 안에 표시됩니 (예: [MASTER] 채널, [ON/ OFF], [File] 메뉴) 시작하시기 전에 특징...3 부속품...4 시작하시기 전에 XDJAERO http://pioneerdj.com/support/ http://rekordbox.com/ 목차 본 취급설명서의 사용법 본 사용설명서에서는 제품상에 표시된 채널명 및 버튼명, 소프트웨어의 메뉴명 등이 대괄호 ([ ]) 안에 표시됩니 (예: [MASTER] 채널, [ON/ OFF], [File] 메뉴) 시작하시기 전에 특징...3 부속품...4

More information

<BFC0B7A3C1F6C4B72DBBE7BFEBC0DABCB3B8EDBCAD5FC8AEC0E5BABB28343070C7D1B1DB295F32303133303631312E6169>

<BFC0B7A3C1F6C4B72DBBE7BFEBC0DABCB3B8EDBCAD5FC8AEC0E5BABB28343070C7D1B1DB295F32303133303631312E6169> SMART CAM 내 손안의 스마트 CCTV Orange Box 400/800 사용자 설명서 Part.01 시작에 앞서 일러두기 본 설명서를 분실하였을 경우 http://myorangecam.com 에서 설명서를 다운받아서 다시 보실 수 있습니다. (PDF 문서는 Adobe Reader 가 PC에 설치되 있어야 하며 http://kr.adobe.com 에서

More information

untitled

untitled 1... 2 System... 3... 3.1... 3.2... 3.3... 4... 4.1... 5... 5.1... 5.2... 5.2.1... 5.3... 5.3.1 Modbus-TCP... 5.3.2 Modbus-RTU... 5.3.3 LS485... 5.4... 5.5... 5.5.1... 5.5.2... 5.6... 5.6.1... 5.6.2...

More information

Microsoft PowerPoint - XAD-400.ppt [호환 모드]

Microsoft PowerPoint - XAD-400.ppt [호환 모드] 4Ch H.264 Hardware Codec H.264 User s Manual VER 2.0 4 Channel Real-time playback / USB backup The most stable and reliable real stand alone Digital Video Multiplex Recorder 설치 및 사용시 주의사항 초기설치 및 사용시 주의사항

More information

0922 Monitor22...._kor_1

0922 Monitor22...._kor_1 본 사용설명서는 사용자가 언제라도 볼 수 있는 장소에 보관하십시오. TV튜너의 내장으로, 모니터 기능외에 TV로도 사용할 수 있는 모니터입니다. 좁은 공간도 효율적으로 이용할 수 있는 Slim하고 Simple한 디자인. 인체공학적인 디자인으로 사용 편리성 제고. 와이드형 TFT LCD 패널의 채용으로 넓은 화면의 구현. 최대 해상도 680 x 050(WSXGA+)지원.

More information

LCD Monitor

LCD Monitor LCD MONITOR quick start guide 320TSn-2 ii Floor standing type) LCD Display D-Sub AAA X 2) 8 DVI KIT LAN TV Note TV MENU MENU] 9 ENTER ENTER] SOURCE SOURCE] [PC DVI HDMI MagicInfo] TV TV D.MENU D.MENU TV

More information

ez-md+_manual01

ez-md+_manual01 ez-md+ HDMI/SDI Cross Converter with Audio Mux/Demux Operation manual REVISION NUMBER: 1.0.0 DISTRIBUTION DATE: NOVEMBER. 2018 저작권 알림 Copyright 2006~2018 LUMANTEK Co., Ltd. All Rights Reserved 루먼텍 사에서

More information

파인드라이브를 사용해 주셔서 대단히 감사합니다. 제품을 사용하시기 전에 반드시 이 설명서를 읽어 주십시오. 제품의 수명은 올바른 사용법과 비례하며, 불완전한 사용은 제품 고장은 물론 차량손상과 교통사고의 원인이 될 수 있습니다. 본 문서는 MONSTER 3 모델을 기준

파인드라이브를 사용해 주셔서 대단히 감사합니다. 제품을 사용하시기 전에 반드시 이 설명서를 읽어 주십시오. 제품의 수명은 올바른 사용법과 비례하며, 불완전한 사용은 제품 고장은 물론 차량손상과 교통사고의 원인이 될 수 있습니다. 본 문서는 MONSTER 3 모델을 기준 파인드라이브를 사용해 주셔서 대단히 감사합니다. 제품을 사용하시기 전에 반드시 이 설명서를 읽어 주십시오. 제품의 수명은 올바른 사용법과 비례하며, 불완전한 사용은 제품 고장은 물론 차량손상과 교통사고의 원인이 될 수 있습니다. 본 문서는 MONSTER 3 모델을 기준으로 작성되었으며, 구입 모델에 따라 사용설명서에 소개된 기능에 제한이 있을 수 있습니다.

More information

제품 소개 및 특징 제품 사용 시 주의사항 본 제품은 차량 사고 발생시의 영상과 음성을 저장하여 사고 원인을 분석하는데 도 움을 주는 차량용 영상 기록 장치입니다.! 본 제품은 개인적인 용도로만 사용하여야 하며, 사용설명서에 명시된 사 항 외에 다른 목적으로 제품을 사

제품 소개 및 특징 제품 사용 시 주의사항 본 제품은 차량 사고 발생시의 영상과 음성을 저장하여 사고 원인을 분석하는데 도 움을 주는 차량용 영상 기록 장치입니다.! 본 제품은 개인적인 용도로만 사용하여야 하며, 사용설명서에 명시된 사 항 외에 다른 목적으로 제품을 사 CONTENTS 제품소개 및 특징 3 제품사용 시 주의사항 4 기본 구성품 7 각부 명칭 및 기능 8 제품 설치 0 제품 음성 안내 제품 LED 동작 2 저장 모드별 설명 3 LCD 화면안내 5 주차감시 모드 실행 27 PC 연결/분리 및 데이터 백업 28 전용 뷰어 설치 및 실행 29 전용 뷰어 기능 설명 34 업그레이드 방법 39 SD카드 관리요령 40

More information

untitled

untitled (Rev. 1.6) 1 1. MagicLAN.......8 1.1............8 1.2........8 1.3 MagicLAN.......10 2.........12 2.1.... 12 2.2 12 2.3....12 3. Windows 98SE/ME/2000/XP......13 3.1.....13 3.2 Windows 98SE.... 13 3.3 Windows

More information

chapter4

chapter4 Basic Netw rk 1. ก ก ก 2. 3. ก ก 4. ก 2 1. 2. 3. 4. ก 5. ก 6. ก ก 7. ก 3 ก ก ก ก (Mainframe) ก ก ก ก (Terminal) ก ก ก ก ก ก ก ก 4 ก (Dumb Terminal) ก ก ก ก Mainframe ก CPU ก ก ก ก 5 ก ก ก ก ก ก ก ก ก ก

More information

I 안전 지침 다음 안전 지침을 이용해 사용자 자신과 북톱(Booktop)를 보호하십 시오. M1022 북톱(Booktop) 컴퓨터를 사용할 때 주의: 휴대용 컴퓨터를 신체 위에 직접 올려놓고 장시간 동 안 사용하지 마십시오. 장시간 작동으로 인해 컴퓨터 밑부 분에서

I 안전 지침 다음 안전 지침을 이용해 사용자 자신과 북톱(Booktop)를 보호하십 시오. M1022 북톱(Booktop) 컴퓨터를 사용할 때 주의: 휴대용 컴퓨터를 신체 위에 직접 올려놓고 장시간 동 안 사용하지 마십시오. 장시간 작동으로 인해 컴퓨터 밑부 분에서 저작권 2010 모든 권리는 당사가 소유합니다 중국에서 인쇄 M1022 북톱(Booktop) 사용 설명서 초판: 2010/12 이 사용 설명서에는 새 북톱(Booktop) PC의 설정과 사용에 대한 설명이 들어있습니다. 사용 설명서 안의 정보는 정확성 여부가 신중 히 검토되었으며, 사전 통지 없이 변경될 수 있습니다. 이 사용 설명서의 어떤 부분도 사전 서면

More information

특허청구의 범위 청구항 1 디바이스가 어플리케이션을 실행하는 방법에 있어서, 상기 디바이스에 연결된 제1 외부 디바이스와 함께 상기 어플리케이션을 실행하는 단계; 상기 어플리케이션의 실행 중에 제2 외부 디바이스를 통신 연결하는 단계; 및 상기 제1 외부 디바이스 및

특허청구의 범위 청구항 1 디바이스가 어플리케이션을 실행하는 방법에 있어서, 상기 디바이스에 연결된 제1 외부 디바이스와 함께 상기 어플리케이션을 실행하는 단계; 상기 어플리케이션의 실행 중에 제2 외부 디바이스를 통신 연결하는 단계; 및 상기 제1 외부 디바이스 및 (19) 대한민국특허청(KR) (12) 공개특허공보(A) (11) 공개번호 10-2014-0033653 (43) 공개일자 2014년03월19일 (51) 국제특허분류(Int. Cl.) G06F 9/44 (2006.01) G06F 15/16 (2006.01) (21) 출원번호 10-2012-0099738 (22) 출원일자 2012년09월10일 심사청구일자 없음

More information

Copyright 2009 Hewlett-Packard Development Company, L.P. Microsoft 및 Windows 는 Microsoft Corporation 의 미국 등록 상표입니다. Bluetooth 는 해당 소유권자가 소유한 상표이 며 Hew

Copyright 2009 Hewlett-Packard Development Company, L.P. Microsoft 및 Windows 는 Microsoft Corporation 의 미국 등록 상표입니다. Bluetooth 는 해당 소유권자가 소유한 상표이 며 Hew HP Envy 13 사용 설명서 Copyright 2009 Hewlett-Packard Development Company, L.P. Microsoft 및 Windows 는 Microsoft Corporation 의 미국 등록 상표입니다. Bluetooth 는 해당 소유권자가 소유한 상표이 며 Hewlett-Packard Company 가 라이센스 계약에 따라

More information

LCD Monitor

LCD Monitor LCD MONITOR quick start guide 400FP-2 460FP-2 400FPn-2 460FPn-2 ii Floor standing type) Note LCD Display MagicInfo Software CD MagicInfo Manual CD (FPn-2.) (AAA X 2) (FPn-2.) BNC to RCA (46.) D-Sub DVI

More information

Copyright 2009 Hewlett-Packard Development Company, L.P. Intel 은 미국 및 다른 국가에서 Intel Corporation 의 상표입니다. Microsoft 및 Windows 는 Microsoft Corporation 의

Copyright 2009 Hewlett-Packard Development Company, L.P. Intel 은 미국 및 다른 국가에서 Intel Corporation 의 상표입니다. Microsoft 및 Windows 는 Microsoft Corporation 의 HP ENVY 15 사용 설명서 Copyright 2009 Hewlett-Packard Development Company, L.P. Intel 은 미국 및 다른 국가에서 Intel Corporation 의 상표입니다. Microsoft 및 Windows 는 Microsoft Corporation 의 미국 등록 상표입니다. Bluetooth 는 해당 소유권

More information

Remote UI Guide

Remote UI Guide Remote UI KOR Remote UI Remote UI PDF Adobe Reader/Adobe Acrobat Reader. Adobe Reader/Adobe Acrobat Reader Adobe Systems Incorporated.. Canon. Remote UI GIF Adobe Systems Incorporated Photoshop. ..........................................................

More information

목차 1. 개요... 3 2. USB 드라이버 설치 (FTDI DRIVER)... 4 2-1. FTDI DRIVER 실행파일... 4 2-2. USB 드라이버 확인방법... 5 3. DEVICE-PROGRAMMER 설치... 7 3-1. DEVICE-PROGRAMMER

목차 1. 개요... 3 2. USB 드라이버 설치 (FTDI DRIVER)... 4 2-1. FTDI DRIVER 실행파일... 4 2-2. USB 드라이버 확인방법... 5 3. DEVICE-PROGRAMMER 설치... 7 3-1. DEVICE-PROGRAMMER < Tool s Guide > 목차 1. 개요... 3 2. USB 드라이버 설치 (FTDI DRIVER)... 4 2-1. FTDI DRIVER 실행파일... 4 2-2. USB 드라이버 확인방법... 5 3. DEVICE-PROGRAMMER 설치... 7 3-1. DEVICE-PROGRAMMER 실행파일... 7 4. DEVICE-PROGRAMMER 사용하기...

More information

CANTUS Evaluation Board Ap. Note

CANTUS Evaluation Board Ap. Note Preliminary CANTUS - UART - 32bits EISC Microprocessor CANTUS Ver 1. October 8, 29 Advanced Digital Chips Inc. Ver 1. PRELIMINARY CANTUS Application Note( EVM B d ) History 29-1-8 Created Preliminary Specification

More information

소개 TeraStation 을 구입해 주셔서 감사합니다! 이 사용 설명서는 TeraStation 구성 정보를 제공합니다. 제품은 계속 업데이트되므로, 이 설명서의 이미지 및 텍스트는 사용자가 보유 중인 TeraStation 에 표시 된 이미지 및 텍스트와 약간 다를 수

소개 TeraStation 을 구입해 주셔서 감사합니다! 이 사용 설명서는 TeraStation 구성 정보를 제공합니다. 제품은 계속 업데이트되므로, 이 설명서의 이미지 및 텍스트는 사용자가 보유 중인 TeraStation 에 표시 된 이미지 및 텍스트와 약간 다를 수 사용 설명서 TeraStation Pro II TS-HTGL/R5 패키지 내용물: 본체 (TeraStation) 이더넷 케이블 전원 케이블 TeraNavigator 설치 CD 사용 설명서 (이 설명서) 제품 보증서 www.buffalotech.com 소개 TeraStation 을 구입해 주셔서 감사합니다! 이 사용 설명서는 TeraStation 구성 정보를

More information

Windows Embedded Compact 2013 [그림 1]은 Windows CE 로 알려진 Microsoft의 Windows Embedded Compact OS의 history를 보여주고 있다. [표 1] 은 각 Windows CE 버전들의 주요 특징들을 담고

Windows Embedded Compact 2013 [그림 1]은 Windows CE 로 알려진 Microsoft의 Windows Embedded Compact OS의 history를 보여주고 있다. [표 1] 은 각 Windows CE 버전들의 주요 특징들을 담고 OT S / SOFTWARE 임베디드 시스템에 최적화된 Windows Embedded Compact 2013 MDS테크놀로지 / ES사업부 SE팀 김재형 부장 / [email protected] 또 다른 산업혁명이 도래한 시점에 아직도 자신을 떳떳이 드러내지 못하고 있는 Windows Embedded Compact를 오랫동안 지켜보면서, 필자는 여기서 그와 관련된

More information

차례 사용하기 전에 준비 및 연결 간편 기능 채널 관련 영상 관련 음성 관련 시간 관련 화면잔상 방지를 위한 주의사항... 4 각 부분의 이름... 6 제품의 설치방법... 10 TV를 켜려면... 15 TV를 보려면... 16 외부입력에 연결된 기기명을 설정하려면..

차례 사용하기 전에 준비 및 연결 간편 기능 채널 관련 영상 관련 음성 관련 시간 관련 화면잔상 방지를 위한 주의사항... 4 각 부분의 이름... 6 제품의 설치방법... 10 TV를 켜려면... 15 TV를 보려면... 16 외부입력에 연결된 기기명을 설정하려면.. 한 국 어 사용설명서 LED LCD MONITOR TV 사용전에 안전을 위한 주의사항을 반드시 읽고 정확하게 사용하세요. LED LCD MONITOR TV 모델 목록 M2280D M2380D 1 www.lg.com 차례 사용하기 전에 준비 및 연결 간편 기능 채널 관련 영상 관련 음성 관련 시간 관련 화면잔상 방지를 위한 주의사항... 4 각 부분의 이름...

More information

삼성전자는 Windows 를 권장합니다. PC 소프트웨어 PC 솔루션 삼성 삼성전자만의 편리하고 다양한 소프트웨어를 통해 초보자도 보다 쉽고 빠르게 이용 가능합니다. Easy Settings 삼성 패스트 스타트 Easy File Share (PC to PC) (삼성 컨

삼성전자는 Windows 를 권장합니다. PC 소프트웨어 PC 솔루션 삼성 삼성전자만의 편리하고 다양한 소프트웨어를 통해 초보자도 보다 쉽고 빠르게 이용 가능합니다. Easy Settings 삼성 패스트 스타트 Easy File Share (PC to PC) (삼성 컨 삼성전자는 Windows 를 권장합니다. PC 소프트웨어 PC 솔루션 삼성 삼성전자만의 편리하고 다양한 소프트웨어를 통해 초보자도 보다 쉽고 빠르게 이용 가능합니다. Easy Settings 삼성 패스트 스타트 Easy File Share (PC to PC) (삼성 컨트롤센터 대체) 전원버튼을 누르거나 덮개를 열면 몇초 내에 작업 시작 무선으로 PC간 (최대

More information

User Guide

User Guide HP Pocket Playlist 사용 설명서 부품 번호: 699916-AD2 제 2 판: 2013 년 1 월, 초판: 2012 년 12 월 Copyright 2012, 2013 Hewlett-Packard Development Company, L.P. Microsoft, Windows 및 Windows Vista 는 Microsoft Corporation

More information

SW테스트베드 장비 리스트

SW테스트베드 장비 리스트 SW테스트베드 장비 리스트(04년) 번호 장비명 수량 용도 제품 사양 Bluetooth를 3.CM OBD SCAN ELM37 0 지원하는 차량 ECU 초 미니 안드로이드폰 용 OBD 스캐너 스캐너 OBD 분배기, OBD 연장케이블 Chip : Broadcm BCM83 Soc 라즈베리파이 MODELB+ ARM 기반 컴퓨팅 보드 Core architecture

More information

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D313939392D382E687770>

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D313939392D382E687770> i ii iii iv v vi 1 2 3 4 가상대학 시스템의 국내외 현황 조사 가상대학 플랫폼 개발 이상적인 가상대학시스템의 미래상 제안 5 웹-기반 가상대학 시스템 전통적인 교수 방법 시간/공간 제약을 극복한 학습동기 부여 교수의 일방적인 내용전달 교수와 학생간의 상호작용 동료 학생들 간의 상호작용 가상대학 운영 공지사항,강의록 자료실, 메모 질의응답,

More information

디지털공학 5판 7-8장

디지털공학 5판 7-8장 Flip-Flops c h a p t e r 07 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 292 flip flop Q Q Q 1 Q 0 set ON preset Q 0 Q 1 resetoff clear Q Q 1 2 SET RESET SET RESET 7 1 crossednand SET RESET SET RESET

More information

DDX4038BT DDX4038BTM DDX4038 DDX4038M 2010 Kenwood Corporation All Rights Reserved. LVT A (MN)

DDX4038BT DDX4038BTM DDX4038 DDX4038M 2010 Kenwood Corporation All Rights Reserved. LVT A (MN) DDX4038BT DDX4038BTM DDX4038 DDX4038M 2010 Kenwood Corporation All Rights Reserved. LVT2201-002A (MN) 2 3 [ ] CLASS 1 LASER PRODUCT 4 1 2 Language AV Input R-CAM Interrupt Panel Color Preout

More information

DSP_MON 프로그램 메뉴얼

DSP_MON 프로그램 메뉴얼 UART_CAN Analyzer 윈도우 프로그램 사용자 메뉴얼 리얼시스 TEL : 031-420-4326 FAX : 031-420-4329 주소 : 경기도 안양시 동안구 관양동 799 안양메가밸리 319호 - 1 - UART_CAN Analyzer 제품을 구입해 주셔서 감사합니다. 본 제품을 구입하신 고객께서는 먼저 사용 설명서를 잘 읽어 보시고 제품을 사용하여

More information

User Guide

User Guide 하드웨어 참조 설명서 HP RP2 소매 시스템 Copyright 2014 Hewlett-Packard Development Company, L.P. Microsoft 와 Windows 는 Microsoft 그룹의 미 국 등록 상표입니다. 본 설명서의 내용은 사전 통지 없이 변경될 수 있습니다. HP 제품 및 서비스에 대한 유일한 보증은 제품 및 서비스와 함께

More information

CZ-KETI-IOTG200

CZ-KETI-IOTG200 CZ-KETI-IOTG200 Hardware Manual http://www.mangoboard.com/ http://cafe.naver.com/embeddedcrazyboys Crazy Embedded Laboratory www.mangoboard.com cafe.naver.com/embeddedcrazyboys CRZ Technology 1 Document

More information

고객 카드 현대모비스 제품을 구입해 주셔서 대단히 감사합니다. A/S 마크란? 공업 진흥청이 애프터 서비스가 우수한 업체를 선정, 지정하는 마크로 애프터 서비스 센터 운영관리 등 8개 분야 45개 항목의 까다로운 심사로 결정됩니다. 주의 : 본 제품의 디자인 및 규격은

고객 카드 현대모비스 제품을 구입해 주셔서 대단히 감사합니다. A/S 마크란? 공업 진흥청이 애프터 서비스가 우수한 업체를 선정, 지정하는 마크로 애프터 서비스 센터 운영관리 등 8개 분야 45개 항목의 까다로운 심사로 결정됩니다. 주의 : 본 제품의 디자인 및 규격은 CAR AUDIO SYSTEM 3XKRC07 AM100MDDG 사용설명서 ATYPE 고객 카드 현대모비스 제품을 구입해 주셔서 대단히 감사합니다. A/S 마크란? 공업 진흥청이 애프터 서비스가 우수한 업체를 선정, 지정하는 마크로 애프터 서비스 센터 운영관리 등 8개 분야 45개 항목의 까다로운 심사로 결정됩니다. 주의 : 본 제품의 디자인 및 규격은 제품의

More information

Siemens

Siemens SIEMENS () 2004 7 Updated 2004 DEC 09 1. 4 1.1 4 1.2 4 2. 5 2.1 5 2.2 6 2.3 6 2.4 7 3. 8 3.1 50/60 Hz DIP 8 4. 9 4.1 420 9 4.2 420 9 4.3 (CB) 10 5. / () 11 5.1 11 5.2 : P0003 12 6. 13 6.1 13 6.2 15 6.2.1

More information

목차 1. 제품 소개... 4 1.1 특징... 4 1.2 개요... 4 1.3 Function table... 5 2. 기능 소개... 6 2.1 Copy... 6 2.2 Compare... 6 2.3 Copy & Compare... 6 2.4 Erase... 6 2

목차 1. 제품 소개... 4 1.1 특징... 4 1.2 개요... 4 1.3 Function table... 5 2. 기능 소개... 6 2.1 Copy... 6 2.2 Compare... 6 2.3 Copy & Compare... 6 2.4 Erase... 6 2 유영테크닉스( 주) 사용자 설명서 HDD014/034 IDE & SATA Hard Drive Duplicator 유 영 테 크 닉 스 ( 주) (032)670-7880 www.yooyoung-tech.com 목차 1. 제품 소개... 4 1.1 특징... 4 1.2 개요... 4 1.3 Function table... 5 2. 기능 소개... 6 2.1 Copy...

More information

USB USB DV25 DV25 REC SRN-475S REC SRN-475S LAN POWER LAN POWER Quick Network Setup Guide xdsl/cable Modem PC DVR 1~3 1.. DVR DVR IP xdsl Cable xdsl C

USB USB DV25 DV25 REC SRN-475S REC SRN-475S LAN POWER LAN POWER Quick Network Setup Guide xdsl/cable Modem PC DVR 1~3 1.. DVR DVR IP xdsl Cable xdsl C USB USB DV25 DV25 REC SRN-475S REC SRN-475S LAN POWER LAN POWER Quick Network Setup Guide xdsl/cable Modem PC DVR 1~3 1.. DVR DVR IP xdsl Cable xdsl Cable PC PC Step 1~5. Step, PC, DVR Step 1. Cable Step

More information

Microsoft Word - Installation and User Manual_CMD V2.2_.doc

Microsoft Word - Installation and User Manual_CMD V2.2_.doc CARDMATIC CMD INSTALLATION MANUAL 씨앤에이씨스템(C&A SYSTEM Co., Ltd.) 본사 : 서울특별시 용산구 신계동 24-1(금양빌딩 2층) TEL. (02)718-2386( 代 ) FAX. (02) 701-2966 공장/연구소 : 경기도 고양시 일산동구 백석동 1141-2 유니테크빌 324호 TEL. (031)907-1386

More information

1.LAN의 특징과 각종 방식

1.LAN의 특징과 각종 방식 0 Chapter 1. LAN I. LAN 1. - - - - Switching - 2. LAN - (Topology) - (Cable) - - 2.1 1) / LAN - - (point to point) 2) LAN - 3) LAN - 2.2 1) Bound - - (Twisted Pair) - (Coaxial cable) - (Fiber Optics) 1

More information

歯메뉴얼v2.04.doc

歯메뉴얼v2.04.doc 1 SV - ih.. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 - - - 23 24 R S T G U V W P1 P2 N R S T G U V W P1 P2 N R S T G U V W P1 P2 N 25 26 DC REACTOR(OPTION) DB UNIT(OPTION) 3 φ 220/440 V 50/60

More information

Microsoft PowerPoint - eSlim SV5-2510 [080116]

Microsoft PowerPoint - eSlim SV5-2510 [080116] Innovation for Total Solution Provider!! eslim SV5-2510 Opteron Server 2008. 03 ESLIM KOREA INC. 1. 제 품 개 요 eslim SV5-2510 Server Quad-Core and Dual-Core Opteron 2000 Series 6 internal HDD bays for SAS

More information

Microsoft Word - ZIO-AP1500N-Manual.doc

Microsoft Word - ZIO-AP1500N-Manual.doc 목 차 사용자 설명서 1 장 제품 소개 ------------------------------ 1 2 장 제품 내용물 ---------------------------- 2 3 장 AP 연결 설정 방법 ------------------------ 3 4 장 동작 방식별 설정 방법 --------------------- 7 (1) 엑세스 포인트 모드 -----------------------

More information

CD-RW_Advanced.PDF

CD-RW_Advanced.PDF HP CD-Writer Program User Guide - - Ver. 2.0 HP CD-RW Adaptec Easy CD Creator Copier, Direct CD. HP CD-RW,. Easy CD Creator 3.5C, Direct CD 3.0., HP. HP CD-RW TEAM ( 02-3270-0803 ) < > 1. CD...3 CD...5

More information

MR-3000A-MAN.hwp

MR-3000A-MAN.hwp ITS Field Emulator for Traffic Local Controller [ MR-3000A ] User's Manual MORU Industrial Systems. www.moru.com - 1 - 1. 개요 MR-3000A는교통관제시스템에있어서현장용교통신호제어기의개발, 신호제어알고리즘의개발및검증, 교통신호제어기생산 LINE에서의자체검사수단등으로활용될수있도록개발된물리적모의시험장치이다.

More information

歯J2000-04.PDF

歯J2000-04.PDF - - I. / 1 II. / 3 III. / 14 IV. / 23 I. (openness), (Modulization). (Internet Protocol) (Linux) (open source technology).. - Windows95, 98, (proprietary system). ( ). - (free).,. 1),.,,,. 1). IBM,. IBM

More information

Microsoft Word - UG-BetaDraft_KO_TT-OK.doc

Microsoft Word - UG-BetaDraft_KO_TT-OK.doc DocuPrint C2090 FS 사용설명서 Adobe, Adobe 로고, Acrobat Reader는 Adobe Systems Incorporated의 상표입니다. Microsoft, Windows, Windows Server는 미국 및/또는 다른 나라의 Microsoft Corporation의 등록상표 또 는 상표입니다. 소프트웨어 스크린 샷을 사용하는

More information

T100MD+

T100MD+ User s Manual 100% ) ( x b a a + 1 RX+ TX+ DTR GND TX+ RX+ DTR GND RX+ TX+ DTR GND DSR RX+ TX+ DTR GND DSR [ DCE TYPE ] [ DCE TYPE ] RS232 Format Baud 1 T100MD+

More information