대학시절, 임베디드에 진심이었던 시절이 있었습니다.
임베디드 개발 동아리에 들어가 'Atmega128', 'Coretex m4' , 'RaspBerryPi' 등 여러 제어보드를 다뤄보기도 하고, 해커톤에 참가해 수상도 하고 졸업하고 나서도 한컴 MDS 에서 진행한, 요즘으로 말하면 임베디드 부트캠프도 다녔는데 '한컴 MDS 임베디드 개발자 양성과정' 에서 진행한 프로젝트에 대해서 정리해 보려고 합니다.
한이음 ICT 해커톤 공모전 도전기
https://www.owl-dev.me/blog/37
펌웨어 프로젝트 소스
https://github.com/jinsujj/joystick-firmware
소프트웨어 개발 과정 중에서, 하드웨어를 제어하기 위한 소프트웨어를 흔히 "임베디드 소프트웨어 (Embedded Software)" 라 칭합니다.
그리고 임베디드 소프트웨어로는 운영체제 없이 제어하는 '펌웨어(Firmware)' 와 주로 Linux O/S 에서 동작하는 "커널 모듈 ( Kernel Module)", 디바이스 드라이버(Device Driver) 로 분류됩니다.
교육 중에 프로젝트를 구상해야 하는 시기에, 평소 들고다니는 하드웨어 보관 상자에, 언젠가 써먹겠지 하고 쟁여두던 서보모터와, 조이스틱 하드웨어 모듈이 있어서, 교육 마지막 프로젝트 과제에서, 이들을 이용해 펌웨어 제작을 하게 되었습니다.
이번 프로젝트는 S3C2450 칩에서 제공하는 여러 기능중에,
아날로그 신호를 디지털로 변환해주는 ADC (Analog Digital Converter) 레지스터와 , 펄스폭 단위로 서보모터를 제어하는 PWM ( Pulse with modulation) 레지스터,그리고 타이머를 체킹하는 WDT (Watch Dog Timer) 레지스터를 활용해서 구현했습니다.
S3C2450 - SoC 칩 ( 타겟 보드 )
S3C2450 보드 칩 사용자 매뉴얼 ( DataSheet )
(* 아래 2개 동일한 PDF 문서 URL 입니다)
https://www.manualslib.com/download/1308248/Samsung-S3c2416.html
http://www.fdi.ucm.es/profesor/mendias/psyd/docs/S3C2450.pdf
'서보모터'와, '조이스틱', '부저' 센서 모듈과, 타겟 보드 SoC DataSheet 을 활용해, 펌웨어 파일을 만들고 S3C2450 칩에 Linux O/S 를 올려서 S3C2450 SoC 칩이 위 하드웨어들을 제어하는 방식을 갖게 됩니다.
전체 소스는 Github Repo 에서 확인이 가능하며 하드웨어를 제어하기 위한 레지스터 비트 맵핑은 어렵지만, 소스 로직 자체는 간단합니다. 핵심이 되는 소스로는, 펌웨어 동작 시작 관련 Main.c , 아날로그 디지털 컨버터 관련 addUse.c, 조이스틱 관련 Joystic.c 로 구성됩니다.
참고로 리눅스용 C 컴파일러는 GCC (GNU Compiler Collection) 라 불리며, 아래 단계를 거쳐 빌드 됩니다.
전처리 단계: C 파일을 gcc 컴파일러로 컴파일 할 경우 전처리 단계가 진행되는데, 그 결과로 i 파일을 만들어냅니다.
Main.c
ADC (Analog Digital Conveter) 레지스터의 경우도 마찬가지로 메모리 맵핑을 해줍니다 ( DataSheet 577 Page )
각 비트는 C 언어로 비트연산을 통해 각 메모리에 설정을 해줍니다.
좀더 구체적으로는 Interrupt, polling 및, 각 클럭에 대한 계산 로직까지 고려해야 하지만 핵심은 아래와 같습니다
조이스틱은 이 펌웨어의 핵심 동작 로직으로 먼저 사용할 함수를 미리 선언해 둡니다.
절차적 지향 프로그래밍에서 자주 사용하던 방법으로, 객체 지향 프로그래밍에 빗대어 설명하자면 인터페이스 선언과 비슷합니다.
다음은 const 값 같은 부저 음계에 대한 값을 선언해 둡니다.
임베디드의 세계에서는, Soc 타겟보드에 종속적으로, 개발하려는 SoC 칩에 대한 메모리 주소를 상세하게 알고있어야 하는 단점이 있습니다.
이부분은 서보모터와, 부저에 대한 초기 세팅으로, 기본적으로 Port B 레지스터를 사용하되, 서보모터의 x 축은 GPB0, y 축은 GPB2 그리고 부저는 GPB1 을 사용합니다.
참고로 서보모터는 PWM ( Pulse with Modulation) 을 사용하기 위해서 타이머를 사용해야 하는데, 타이머 out 핀이 Port B 레지스터에 물려있어서, PortB 레지스터를 사용했습니다.( DataSheet 42 Page )
PWM Timer 관련해서는 'TOUT0', 'TOU1' 'TOU2', 'TOU3' 이렇게 4개의 PWM 신호를 받을 수 있습니다. ( DataSheet 286 Page )
서보모터를 제어하는 로직으로 x 축, y 축 모두 Timer4 번 레지스터를 활용했습니다.
동작로직은 while 문을 돌려서, nput 모드로 조이스틱 모듈로 input 받고, output 모드로 서보모터 모듈로 output 합니다.
각 동작 사이에는 Delay 시간을 걸어주었습니다.
rGPBDAT &= ~(0x1 <<0) // 00 = input Mode
rGPBDAT |= (0x1 <<0) // 01 = output Mode
* 참고로 rTCFG0, rTCFG1 을 동작에 의미없는... 삭제했어야할 코드입니다.
motor x 와 동일합니다.
motor x 와 비슷합니다.
Delay 를 걸어주기 위해서 WatchDog Timer 레지스트리를 사용합니다.
구체적인 설정에 대한 설명은 위에 읽는 방법에 대해 기술하여 생략합니다. 다만 PCLK 는 CPU 가 가지고 있는 3Ghz 와 같은 1초에 몇번 Switching 을 할 수 있는지를 나타내는 지표로, FPGA 와 동일하게, 이 클럭을 16 분의1, 128분의1 등으로 줄여서, 타이머 클럭으로 사용합니다.
ADC (Analog Digital Converter) 관련해서 AIN8(XM), AIN9(XP) 2개의 채널을 활용해서 아날로그 신호를 디지털로 변환합니다.
이 신호는 모터 x 축과, y축을 활용하는 구간에서 적용됩니다.
Joystic.c
[Reference]