[완료] Frame Buffer 디바이스 드라이버 작성시 mmap 에 관해
안녕하세요.
FB 디바이스 드라이버를 공부삼아 작성해 보고 있습니다.
개발환경을 설명드리면 ARM9 코어를 가진 Target 보드로 칩자체에 LCD 드라이버가 내장된 타입이 아닙니다.
즉, BUS를 통해 외부 LCD의 register에 접근함으로서 instruction/data를 write함으로서 LCD 초기화나 이미지 출력등이 되는 방식입니다. 제 설명이 좀 어려워 죄송합니다만 임베디드 계열에서 LCD를 다뤄보신분은 무슨 소리를 하고 있는지 아마 이해가 되시리라 생각합니다. ;;
이미 커널상에 포함되어있는 비슷한 Driver는 ../drivers/video/arcfb.c 가 비슷한 예입니다.
서론이 길었습니다만 현재 제가 작성한 Driver로 다음과 같은 application 예제를 사용하면 선 그리기라든지 점찍기등은 잘되는 상태입니다. (간단히 필요한 부분만 추렸습니다)
void fb_test_1()
{
fbfd = open("/dev/fb0", O_RDWR); // FB를 File Descriptor를 이용해 열어서
lseek(fbfd, 100, SEEK_SET) // 100번째 pixel 위치로 이동해
write(fbfd, 0x0A0A, 2); // 0X0A0A 색을 가지는 픽셀을 찍는다
}
문제는 아래와 같이mmap 방식으로 접근하면 에러가 나고 실행이 되질 않습니다.
void fb_test_2()
{
int *pmmap;
fbfd = open("/dev/fb0", O_RDWR);
pmmap = (int *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fbfd, 0);
pmmap[100]= 0x0A0A
}
간단한 예로서 든 의사코드 수준이지만 나름대로 현재 문제점을 간략하게 정리했습니다.
칩자체에 LCD 드라이버를 가지고 있는 경우(ex. s3c2410fb.c)가 아니기 때문에 메모리 매핑시
에러가 나는 것인지 뭔지 잘 모르겠습니다.
드라이버를 작성해 콘솔의 로그 출력이랄지 궁극적으로는 Qt/Embedded 같은 GUI Framework등을
올려보고 싶은데 여기서 꽉 막혀서 더 이상 넘어가질 않네요.
비슷한 종류의 LCD(I/O 방식으로 억세스하는)의 FB를 작성해 보신 사례랄지
이와 같은 에러의 원인이랄지에 대해 아시는 것이라면 무엇이든 ;;
큰!!! 도움이 될 듯 합니다.
언듯보기에는 별
언듯보기에는 별 문제가 없어보이긴 하는데요.
에러 내용을 올려주세요.
어떤 에러가 발생하는지 올리신 내용만으로는 알기가 힘드네요.
혹시 드라이버쪽 mmap이 잘못된 것은 아닌가요?
arcfb 같은 형태로
arcfb 같은 형태로 드라이버를 작성하셨다면 mmap() 은 불가능합니다.
드라이버내에서 fb 용 메모리를 할당하고, 이 메모리 영역을 유저에게 제공한 다음,
1. 커널쓰레드를 만들어서 auto-refresh 를 한다던가
2. .fb_sync 콜백으로 refresh 를 구현한다음 어플리케이션에서 필요한 순간에 fsync() 을 한다던가
3. 위의 1번 2번을 조합해서 평상시의 UI 는 manual refresh, 동영상등은 auto refresh 로 선택할 수 있게 한다던가
하는 방법을 많이 사용합니다. 일종의 wrapper 를 드라이버내에서 구현하는 방식이죠.
1번 방식을 사용한다고 결정난다하더라도 2번까지 구현해두는 것이 좋습니다.
커널의 fb logo 는 .fb_imageblit 콜백호출 후 .fb_sync 콜백을 호출합니다.
커널 쓰레드는 init 프로세스가 뜨기 전까진 정지상태이므로 초기에 logo 가 짠~ 하고 나타나기 위해선 .fb_sync 콜백이 필요합니다.
OTL
답글 감사합니다.
제가 FB 내부구현에 익숙치 않아서 sync랄지 어떤식으로 호출되며 콜백을 만들어 줘야할지 확실히는 모르겠지만 어느정도 감은 잡혔습니다. 대단히 감사합니다.
그리고 참고로 Linux Frame Buffer Device Development 에서 다음 글을 읽었습니다.
http://sourceforge.net/mailarchive/message.php?msg_id=Pine.LNX.4.62.0701141211030.18479%40pademelon.sonytel.be
요약하자면 mappable이 불가능한 device의 경우 __get_free_pages()등을 이용해 shodow buffer라는 걸 따로 만들어 두고 bushi님이 말씀하신대로 쓰레드 등을 이용해 auto-refresh하는 방식을 사용하는 듯 합니다.
그런데 한가지 마음에 걸리는 부분이 있습니다. auto-refresh를 한다고 하면 전체 화면을 다시 그려줘야 하는데 그렇다면 부하가 많이 걸리지 않을까 하는 점입니다. 어떻게든 변경이 일어난 부분만을 인식해 refresh해주는 방법이라든지 없을까요? 이런 의문이 생기는 이유는 같은 사이트에서 또 다음과 같은 글을 보았기 때문입니다.
http://sourceforge.net/mailarchive/message.php?msg_id=170385E48B041543AC99CCD09E325AD1952BB9%40mail.rogermanagement.com.au
-------------------------------------------------------------------------------
Re: [Linux-fbdev-devel] Driver for Sharp LH155BA Richard Wolf
Re: [Linux-fbdev-devel] Driver for Sharp LH155BA
From: Antonino A. Daplas - 2006-08-01 01:18
Richard Wolf wrote:
>
> Presumably if I take the shadow buffer route then I could maintain _two_
> shadow buffers. This would allow me to detect whether the user accessible
> buffer had been changed and update the display only when necessary.
Yes, that will work too.
Tony
-------------------------------------------------------------------------------
찾아보았는데 user가 업데이트한 영역을 detect할 수 있는 방법이 있다고 써있는데,
제가 아는 한도내에서는 찾을 수가 없었습니다.
추가) 방금 알았는데, 위 메일에서 말하는 Driver는 아마도 epson1355fb.c을 말하는 듯 합니다
답변 미리 감사드립니다. ^^;
버퍼 두 개를 만들고
버퍼 두 개를 만들고 if () 문으로 비교해보기 전엔 알 수 없습니다.(인용하신 메일도 아마 이걸 뜻하는 것 같습니다.)
이론적으로야 가능하지만, 해상도가 크기라도 하면 if () 때문에 발생하는 오버해드도 ...
대안으로 refresh window 를 정의한 ioctl 을 만들어서 어플리케이션에게 사용을 강요할 순 있지만,
auto refresh 에 써먹으려면 머리 좀 써야겠죠.
OTL
감사합니다.
디바이스를 처음 만들어보니 Virtual Memory 개념부터해서 어려운 게 한 두가지가 아니네요.
더 고민해보겠습니다. (__)
제가 난독증이
제가 난독증이 있었나보네요;;;
질문 윗부분에 있는 설명도 제대로 안읽고 mmap을 사용하신다기에 당연히 내부 컨트롤러가 있고 memory mapped register를 사용한 control일줄 알았다는;; ^^;;;
감사합니다 ^^
그냥 이런 관심도 헤매는 어린양에게는 큰 힘이됩니다. ㅠㅠ
댓글 달기