S3C2440A Embedded Linux-Xenomai with Realtime CAN (USB-host RTDM)

이번에도 글 제목이 아주 거창하다.
일전에 400MHz짜리 S3C2440A 컨트롤러가 내장된 네비게이터에 Linux-Xenomai를 포팅했었다(글보기).
껍데기도 깨끗하니 어디 좋은데 쓸데가 없을까 하다가 마침 8축 Actuator 구동 시험을 할 일이 있어 구현해 봤다.
제어 대상은 독일 Dunker motor라는 회사에서 만든 제어기 일체형 서보모터이고 CANopen 방식 인터페이스를 사용한다.


[CANopen 인터페이스 방식 Servo Actuator]

문제는 네비게이터에 CAN 포트가 당연히 없다는 것이다.

다행이 여러모로 확장 가능한 USB 호스트 포트가 있어 요놈을 활용해 보기로 했다.
아주 쉽다. 네비게이터에 달린 USB호스트에 USB to CAN 컨버터를 그냥 낑구면 되는 것이다!!! 정말 쉽지 않은가?

그러나 진짜 문제는 여기서 부터다.

Linux기반 USB 호스트측 SW(USB OHCI) 소스는 쉽게 구할 수 있으나 당연히 RTDM(Realtime Driver Module)을 필요로 하는 실시간 운영체제에는 쓸 수가 없다. 엄연히 이야기 하자면 사용은 가능하나 언제 실시간이 깨질지 모른다. 힘들게 실시간 운영체제를 쓰는 의미가 없다.
USB 호스트측 SW를 RTDM으로 처음부터 다시 만들어야 한다.

다음 문제가 또 있다. USB to CAN 컨버터다.

'디바이스 드라이버는 이렇게 저렇게 만드시오, 어플리케이션 API는 이러쿵 저러쿵 만드시오' 하는 메뉴얼따윈 당연히 없다. 드라이버 소스도 못 구한다.
그런데 USB to CAN 컨버터의 디바이스 드라이버도 RTDM용으로 다시 짜야한다.

그리고 또...

CAN 패킷 I/O를 위한 User level의 API 라이브러리도 실시간용으로 다시 만들어야 한다!!!

음... 머리가 아프군...

USB 호스트용 OHCI소스를 분석한다.
control pipe, bulk-in pipe, bulk-out pipe 등등 low level 제어 코드를 뽑아내 RTDM용으로 디바이스 드라이버를 완전히 다시 만든다.
OHCI 기능과는 무관한 오직 USB-CAN만을 위한 디바이스 드라이버를 만들었다.
USB to CAN 컨버터 드라이버는 소스를 구할 수 없으니 WireShark의 USB sniffing기능을 이용해 드라이버 동작을 reverse engineering한다.
User level API동작 분석은 API Monitor라는 툴을 이용해 관련 DLL에 접근하는 모든 API함수들의 동작 시퀸스와 완벽하지는 않지만 매개 변수 값들을 확인하고 알 수 없는 값들은 추정한다.
이렇게 간단한 방법으로 구현했다. 움하하...


[리눅스 부팅 및 Linux Framebuffer 동작 확인]


[SDL을 이용한 GUI구성 - 버튼, 텍스트 박스등 제작 테스트]

400MHz ARM9 코어에 USB호스트측 5ms짜리 실시간 태스크와 CANopen 패킷 제어를 위한 50Hz용 실시간 태스크를 만들었다.

8개 Actuator를 20ms주기로 동시에 제어 하도록 구성했다.
GUI는 SDL을 이용해 구현하고 8개 Actuator의 동시 제어를 좀더 직관적으로 하기위해 IIC 통신으로 사용이 가능한 Wii Nunchuk이라는 조이스틱 비스므레한걸 달아 줬다.
8축 CANopen I/O용 5ms/20ms 실시간 태스크 2개, GUI용 Thread 1개, Nunchuk 인터페이스용 Thread 1개, 전체 시스템 서비스 구성용 Thread 1개, 그리고 마지막으로 콘솔 제어 및 모니터링용 main() 루프 한개... CPU를 아주 알차게 쓰고 있는듯 하다.


[최종 완성]