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_FSCREENINFO
và struct fb_fix_screeninfo
có thêm thông tin như type
và line_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;
}
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
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
@Rahul - Phải là thứ tự tôi đặt tiêu đề trong ... Có thể thử sys/types.h trước? – asveikau