얼마 되지 않은 나이이지만 그래도 꾸준히 간단한 프로그램을 작성하고 다른 프로그램 코드를 보면서 지내왔다. 임베디드 시스템이란것을 하면서 하드웨어에 대한 지식이 있어야 한다는것을 알고 공부를 조금씩 했었다.
네트워크 프로그램을 작성하면 일단 인터넷에서 서버/클라이언트 소스를 찾아서 내컴퓨터로 가져온이후 이 프로그램을 수정하거나? 이 프로그램의 소켓 설정등을 내 프로그램에 복사하여 넣는다.
수많은 사용자가 네트워크 프로그램을 작성하면서 10여개의 API를 사용하여 원하는 프로그램을 만들어 낸다. 10여개의 API를 나열하는 방법은 너무나 많다. 나열하는 방법이 많아도 우리는 네트워크 응용을 구축하여 잘 작동시키고 있다.
eCos로 들어와서 내가 만드는 프로그램에 숨어있는 네트워크 프로그램을 시작하였다. 이것이 작동하지 않는다. 임베디드 보드에 올려야 하지만 vmware를 사용하여 개발중이라 생각보다 빠른 컴파일 빠른 작동 확인이 가능하지만. 정말 원인을 찾는데 오랜 시간을 들였다.
작동하지 않는 결과를 어렵게 찾았다. 궁극적인 내용은 모르지만 원인은 간단하다.
main Thread 에서는 block I/O를 하면 안된다.
- ecos Main()
1. main() //C or C++ 스타일
2. cyg_user_start()
3. cyg_start()
모두 프로그램의 시작을 나타낸다.
cyg_user_start, cyg_start 앞에는 externC를 붙여줘야 작동이 가능하다. (externC 부분을 참조) 나는 cyg_start를 가지고 프로그램을 시작했다. 그리고 그속에서 주된 프로그램이 시작하기 전에 네트워크로 정보를 교화하는 코드가 들어간다. 메시지를 보내고 응답을 받고 응답을 받는데, 항상 reset이 걸린다. 특별할것이 없는 코드였으므로 이곳저곳 찾아 보며 범위를 줄였다. 그리고 결국 찾은 것은 UDP로 메시지를 받아 들이는 recvfrom에서 문제가 발생하는 것이다. 아무리 arg를 검토해봐도 죽는 이유를 몰랐다. 결국 이해 한것은 새로운 thread를 생성한 곳에서 block I/O를 해야 문제가 발생하지 않는다는 것이다.
먼저 thread를 생성하고 schduler를 가동시키고 이후에 block I/O를 수행해야 한다. 이것은 eCos의 제약사항일까? 아니면 당연히 이렇게 해야하는 것인데 우리가 지금까지 몰랐던 것일가?
또한가지는 init_all_networks_interface() 라는 함수이다. 이것은 thread를 만들고 그곳에서 호출하도록 만들었었다. 그런데 이것도 이상하게 작동을 한다. networks의 MAC을 FF로 쭈욱 찍어 주는 것이다. 이것도 무엇인가 잘못된것이다. 이것은 Main Thread에서 수행해 주어야 한다. 그래야 옳바르게 작동한다.
임베디드 시스템을 하면서 많은 프로그래밍의 제한사항을 만나고 있다. 1차적인 것은 시스템의 성능, 그리고 메모리의 관리(임베디드에서는 메모리가 제한적이다.
초반에 적었듯 함수의 호출 순서에 따라서 내가 원하는 결과로 작동하거나? 작동하지 않거나가 적용이 된다. 일반 PC에서는 아무런 문제가 없던 코드인데 임베디드로 eCos로 들어오면 문제가 발생한다.
좀더 꼼꼼히 살펴보아야하고, 좀더 꼼꼼히 체크해야한다. 건성 건성 프로그래머다 라는 생각으로 코딩하고 컴파일하고 실행하고 하던 PC프로그램과는 다르다. 코딩할때 정신을 똑바로 차리고 배운데로 권해주는데로 프로그램을 하면 한번에 끝낼것을 이유을 찾는데 오랜시간이 걸리고 해결하기 위해서 또 많은 시간을 허비한다.
지금까지 너무나 잘 만들어진 운영체제에게 대충 만들어도 돌아가는 프로그램을 했다면 반성하며 앞으로는 잘 만들어졌지만 규칙을 따르지 않으면 안돌아가는 운영체제에서 규칙을 지키며 프로그램을 해보자. 내가 사랑하는 임베디드 시스템에서