지난 시간에 이어 display - driver를 잇는 adapter 부분을 구현해 보도록 하겠습니다. 궁극적으로는 아래와 같은 구조가 될 것입니다. display → adapter → driver 결국 adapter 패턴이 있어 display도 다른 driver처럼 사용할 수 있게 됩니다. 먼저 adapter의 header(interface) 부터 살펴 보도록 하겠습니다. extern driver_t *setup_display_adapter(void); setup_display_adapter을 extern으로 선언해줍니다. setup_display_adapter를 호출하면 driver_t의 포인터를 전달해 주도록 되어있습니다. 헤더를 선언할 때 아래와 같은 코드가 많이 나오는데요, 혹시 모르시는 분들이..
예제1) http://dextto.tistory.com/140 예제2) http://kingoh.tistory.com/entry/Factory-Method-%ED%8C%A8%ED%84%B4 우선 위의 두가지 예제를 통해 Java에선 어떻게 Factory method를 구현했는지 보고 오시면 더 좋을 거 같습니다. C언어에선 class라는 개념이 없기 때문에 어떻게 보면 이전 글들에서도 알게 모르게 계속해서 Factory method를 써왔습니다. 이번엔 다시 한번 Factory method를 살펴 보도록 하겠습니다. 이번 예제는 display를 구현해 보도록 하겠습니다. MCU 기반 Firmware에선 display하기 위한 데이터는 프레임 버퍼라 불리우는 메모리에 RGB color를 쌓아 놓고 한번에 ..
Template method(템플릿 메소드) 디자인 패턴도 매우 유용한 패턴입니다. 기능은 같으나 구현방법이 다른 메소드들의 구조를 제시하고 기능과 구현방법이 같은 메소드는 대표로 하나만 제시되는 방법입니다. 예를 들어 도형을 그리는 것을 생각해보도록 하겠습니다. 도형에는 삼각형, 사각형, 원 등이 있습니다. 넓이와 높이(원의 경우 지름)을 통해 도형을 설정하는 것은 모두 똑같습니다. 그러나 구체적으로 모양은 다 다릅니다. 도형을 그릴 때 메모리라는 사상위에 비트를 역상시켜 해당 도형을 그리는 방법을 사용하는데 이는 어느 도형이나 이미지를 그리든 동일합니다. 따라서 도형의 모양을 만드는 기능은 개별 구현이 가능하도록 추상 메소드로 하고 그리는 부분은 모두 같으므로 하나만 구현하면 됩니다. 설명이 약간 어..
Strategy 패턴은 아주 단순하며 디자인 패턴 중에 가장 유용한 패턴입니다. 사용법은 아주 간단하며 interface를 만들고 원하는 곳에서 Concrete 코드를 치환해서 사용하면 됩니다. 적절한 예제일지는 모르지만, 특정한 상황에서 uart를 spi로 변경하는 드라이버 예제를 보도록 하겠습니다. 먼저 interface를 구현해보도록 하겠습니다. /* driver.h */ typedef struct { bool (*open)(void); bool (*close)(void); bool (*read)(uint32_t addr, uint8_t *value); bool (*write)(uint32_t addr, uint8_t *value, uint32_t len); }driver_t; open, clo..
[네이버 지식백과]builder 패턴 (쉽게 배우는 소프트웨어 공학, 2015. 11. 30., 한빛아카데미(주)) Builder 패턴을 공부해 봅시다. 이해하기 좀 어려울 수도 있겠는데요, 각각의 구현은 다르지만 기능은 같은 객체들을 관리하는 관리자를 만드는 패턴입니다. 사용자 즉 main 함수에서는 객체를 만들 뿐 기능을 사용하기 위해 직접 호출하지 않고 관리자를 통해서만 일 처리를 합니다. 이번에는 Key(버튼) 처리하는 기능으로 예제를 만들어 봤습니다. 언제가 꼭 해보고 싶었던 예제인데요, firmware에서는 참 많이 쓰이는 기능입니다. Key 처리 기능은 하드웨어가 바뀌면서 프로젝트마다 바뀔 소지가 있습니다. 단순 1:1 GPIO를 사용할 수도 있고 ADC를 사용할수도 있습니다. 혹은 1:N ..
[네이버 지식백과] facade 패턴 (쉽게 배우는 소프트웨어 공학, 2015. 11. 30., 한빛아카데미(주)) 프로그램 디자인 패턴은 문법이 아닙니다. 따라서 하나의 패턴으로 프로그램 전체를 완성시킬 수는 없습니다. 그리고 완벽하게 룰을 지키는 패턴도 필요없구요. 상황에 따라 여러 패턴들을 조금씩 응용해서 사용할 뿐입니다. 너무 복잡한 패턴은 굳이 쓸 필요가 없습니다. 오히려 유지보수 혹은 한 프로젝트에 다수의 개발자가 존재할 경우 코드를 이해하지 못하는 경우가 발생할 수 있습니다 또한 인수인계 발생시에 왜 이런 패턴을 구현했는지 잘 설명해줘야 합니다. 안그러면 좋은 구조로 잘 설계된 프로그램이 타인에 의해 조금씩 붕괴되는 광경을 목격하실 겁니다. 보통 알고리즘을 사용할 때 복잡한 절차가 있게 마련..
RTOS조차도 없는 Firmware에서는 각각의 기능 프로세스의 처리 시간을 적당히 잘 분배 해야 합니다. 처리 시간이 긴 프로세스는 여러개로 쪼개야 하며, 특히 인터럽트 발생시 인터럽트 루틴에 긴 처리시간을 요구하는 코드를 넣으면 절대 안됩니다. 더욱이 간당간당한 처리시간을 요구한는 코드를 넣는 경우가 더욱 위험합니다. 왜냐하면 어쩔때는 잘 돌아가고 어쩔때는 에러를 발생시키는 경우가 발생할 수도 있으며 이러한 경우에는 디버깅이 상당히 힘들어 집니다.처음부터 아예 인터럽트 루틴에서는 단순히 데이를 적당한 자료구조에 적재해놓던가, 해당 플래크를 set하는 수준 혹은 메시지를 던져주는 수준에서 마무리하는 것이 가장 좋습니다. 만약 전체 시스템이 1초단위로 어떠한 처리가 끝나야 한다면, 각각의 프로세스들이 최..
기본적인 OS가 아예없는 Firmware에서 모든 기능은 무한루프와 인터럽트로 이루어져 있습니다. 이번장에서는 기본적으로 무한루프를 어떻게 실행하면 관리가 좋을 지 생각해보도록 하겠습니다. 우선 우리가 알고 있는 기본적인 while 무한루프입니다. 위의 코드는 간단해보이지만 실제적으로는 훨씬 더 복잡해 질 가능성이 있습니다. 만약 설정(#ifdef)에 따른 process 유무가 들어 간다면 더욱 복잡해 집니다. 이제 소개할 scheduler는 RTOS가 없기 때문에 컨텍스트 스위칭인 일어나지 않는 것을 잘 이해해야 합니다. 그리고 순차적으로 프로세싱이 동작합니다. 따라서 하나의 프로세스나 흐름이 너무 많은 시간을 소요하면 지연 문제가 발생 할 수 있습니다. (이상하게도 해당 소스는 에디터에서 이상하게 변..