2009-12-02 62 views

Trả lời

18

Sử dụng open() vào file ngay trong /dev (ví dụ. /dev/fb0), sau đó sử dụng mmap() để ánh xạ nó vào bộ nhớ. Manpages sẽ giúp các syscalls này nếu bạn không biết cách sử dụng chúng.

Sau đó, có một số cấu trúc và hằng số cho một số ioctl() s trong <linux/fb.h>. Giống như nhiều tiêu đề hạt nhân, bạn có thể tìm hiểu rất nhiều chỉ cần duyệt tệp.

Đặc biệt thú vị là ioctl FBIOGET_VSCREENINFO với struct fb_var_screeninfo. Lưu ý điều này có xres, yres (độ phân giải) và bits_per_pixel. Sau đó, có FBIOGET_FSCREENINFOstruct fb_fix_screeninfo có thêm thông tin như typeline_length.

Vì vậy, pixel tại (x, y) có thể là mmap_base_address + x * bits_per_pixel/8 + y * line_length. Định dạng chính xác của các pixel sẽ phụ thuộc vào cấu trúc bạn truy xuất qua ioctl; đó là công việc của bạn để quyết định cách đọc/ghi chúng.

Nó được một lúc kể từ khi tôi đã làm việc với điều này vì vậy tôi một chút mơ hồ về biết thêm chi tiết ..

Dưới đây là một mẫu mã nhanh chóng và dơ bẩn chỉ để minh họa cách nó được thực hiện ... Tôi thiên đường' t thử nghiệm này.

#include <sys/types.h> 
#include <sys/ioctl.h> 
#include <sys/mman.h> 

#include <linux/fb.h> 

#include <unistd.h> 
#include <fcntl.h> 

#include <stdio.h> 

int main() 
{ 
    struct fb_var_screeninfo screen_info; 
    struct fb_fix_screeninfo fixed_info; 
    char *buffer = NULL; 
    size_t buflen; 
    int fd = -1; 
    int r = 1; 

    fd = open("/dev/fb0", O_RDWR); 
    if (fd >= 0) 
    { 
     if (!ioctl(fd, FBIOGET_VSCREENINFO, &screen_info) && 
      !ioctl(fd, FBIOGET_FSCREENINFO, &fixed_info)) 
     { 
     buflen = screen_info.yres_virtual * fixed_info.line_length; 
     buffer = mmap(NULL, 
         buflen, 
         PROT_READ|PROT_WRITE, 
         MAP_SHARED, 
         fd, 
         0); 
     if (buffer != MAP_FAILED) 
     { 
      /* 
      * TODO: something interesting here. 
      * "buffer" now points to screen pixels. 
      * Each individual pixel might be at: 
      * buffer + x * screen_info.bits_per_pixel/8 
      *   + y * fixed_info.line_length 
      * Then you can write pixels at locations such as that. 
      */ 

      r = 0; /* Indicate success */ 
     } 
     else 
     { 
      perror("mmap"); 
     } 
     } 
     else 
     { 
     perror("ioctl"); 
     } 
    } 
    else 
    { 
     perror("open"); 
    } 

    /* 
    * Clean up 
    */ 
    if (buffer && buffer != MAP_FAILED) 
     munmap(buffer, buflen); 
    if (fd >= 0) 
     close(fd); 

    return r; 
} 
+0

chỉ nhận ra tôi đã quên mất line_length trong "finfo" struct, vì vậy việc cập nhật .. – asveikau

+0

Khi tôi biên soạn tôi đang nhận được một số lỗi như thế này, Trong tập tin bao gồm từ gc: 4: /usr/bao gồm/sys/mman.h: 38: lỗi: các loại xung đột cho 'mode_t' /usr/include/linux/types.h:15: lỗi: khai báo trước của 'mode_t' đã ở đây Trong tệp bao gồm từ gc: 5: /usr/include /unistd.h:203: lỗi: các loại xung đột cho 'gid_t' /usr/include/linux/types.h:27: lỗi: khai báo trước đây của 'gid_t' đã ở đây /usr/include/unistd.h:208 : lỗi: các loại xung đột cho 'uid_t' /usr/include/linux/types.h:26: lỗi: tuyên bố trước đó của 'uid_t' đã ở đây Trong tệp được bao gồm từ /usr/include/bits/fcntl.h:25 , – Rahul

+0

@Rahul - Phải là thứ tự tôi đặt tiêu đề trong ... Có thể thử sys/types.h trước? – asveikau

4

Để thay thế cho asveikau's answer, bạn có thể sử dụng DirectFB, có thể đơn giản hóa rất nhiều thứ cho bạn.

+0

DirectFB cũng có những điều tuyệt vời như mã phần cứng cụ thể để vẽ đường và sao chép hình chữ nhật. – asveikau

+0

Nhưng làm thế nào mà DFB có thể được truy cập – Rahul

+0

Các liên kết này không hoạt động vào năm 2015. – daveloyall

0

Từ Synaptic của tôi trên Rasbian: "DirectFB là một thư viện đồ họa được thiết kế với hệ thống nhúng trong tâm trí. Nó cung cấp hiệu suất tăng tốc phần cứng tối đa ở mức tối thiểu sử dụng tài nguyên và chi phí."

Dù sao, tôi chưa từng thấy công việc này trong bộ đệm khung nhưng tôi hy vọng nó giống như tôi làm hầu hết đồ họa của mình. Bạn có một số không gian địa chỉ tuyến tính, chiều cao * chiều rộng * byte cho mỗi số pixel của byte. Nếu bạn muốn ghi vào một vị trí x, y cụ thể, vị trí trong không gian đó được cho bởi (y * width * bytes trên mỗi pixel) + (x * 3). Màu sắc là các byte liền kề RGB (thường) để cho bạn địa chỉ của pixel đỏ, thêm 1 cho màu xanh lá cây, 2 cho màu xanh lam. Bạn malloc (chiều cao * chiều rộng * byte cho mỗi pixel) một không gian địa chỉ, viết vào nó, sau đó chọn lựa chọn libpng, libjpeg, libtiff để viết bộ đệm đó ra một tệp. Nếu bạn muốn đặt văn bản trong nó quá bạn phải cuộn của riêng bạn, vì vậy tôi lấy trộm một từ một libgif cũ. Tôi đã đạt đến độ tuổi và mức độ kinh nghiệm, nơi dễ dàng hơn để tự làm điều đó hơn là tìm hiểu xem người khác nghĩ nó nên được thực hiện như thế nào. Đồ họa của tôi xuất hiện như sau: data taken as CSV from rtl_power

Tôi đã cố gắng sử dụng bộ đệm khung như được mô tả ở http://raspberrycompote.blogspot.com/2014/04/low-level-graphics-on-raspberry-pi.html nhưng có gì đó không ổn. Tôi đang ở trên Pi 3, nó có thể được viết cho Pi 1 kể từ năm 2014, không phải năm 2017. Nhưng Pi khác với framebuffers truyền thống vì GPU chạy chương trình. Sử dụng phương pháp này: http://elinux.org/RPi_Framebuffer

+0

Alan, đồ thị tìm kiếm thú vị ':)'. Không rõ liệu bạn đang cung cấp câu trả lời cho câu hỏi ban đầu hay câu hỏi mới dưới dạng câu trả lời. (Tôi đọc nó như là một chút của cả hai ...) Nếu ý định của bạn là để được giúp đỡ với vấn đề của bạn, thì tốt hơn là đặt một câu hỏi mới, vì các câu hỏi trong câu trả lời của bạn ở đây không có khả năng nhắc thêm bất kỳ câu trả lời nào. Ngoài ra, vì nó là RaspberryPi liên quan, đặt cược tốt nhất của bạn có lẽ là để đăng trên [** Raspberry pi StackExchange **] (http://raspberrypi.stackexchange.com/). Hay nhất là may mắn. –

+0

Tôi chưa thực sự sử dụng một bộ đệm khung vì OpenBSD không có chúng và đó là chủ yếu là những gì tôi đã chạy trong 15 năm. Không tìm kiếm trợ giúp, chỉ giải thích đồ họa mà không cần thư viện. Tôi sắp thử dùng libvnc vì nó cung cấp cho một framebuffer ảo mà bạn có thể kết nối với một máy khách vnc, và nó chạy trong một cửa sổ thay vì chiếm toàn bộ màn hình. Tôi đang cố gắng để làm SDR với một thác nước vì vậy tôi cần đồ họa di chuyển, không chỉ là hình ảnh tĩnh. –

+0

VNC về cơ bản là framebuffer từ xa, đó là những gì đã cho tôi ý tưởng: https://www.raspberrypi.org/forums/viewtopic.php?f=67&t=189032 (chủ đề của tôi có) –

Các vấn đề liên quan