一. framebuffer结构体
1. fb_info
struct fb_info {
int node; //次设备号
int flags;
struct mutex lock;
struct mutex mm_lock;
struct fb_var_screeninfo var; //可变参数
struct fb_fix_screeninfo fix; //不可变参数
struct fb_monspecs monspecs;
struct work_struct queue;
struct fb_pixmap pixmap;
struct fb_pixmap sprite;
struct fb_cmap cmap;
struct list_head modelist;
struct fb_videomode *mode; //显示模式
#ifdef CONFIG_FB_BACKLIGHT
struct backlight_device *bl_dev;//背光设备
struct mutex bl_curve_mutex;
u8 bl_curve[FB_BACKLIGHT_LEVELS]; //背光级别
#endif
#ifdef CONFIG_FB_DEFERRED_IO
struct delayed_work deferred_work;
struct fb_deferred_io *fbdefio;
#endif
struct fb_ops *fbops; //fb操作函数集
struct device *device; //设备文件
struct device *dev; //设备文件
int class_flag;
#ifdef CONFIG_FB_TILEBLITTING
struct fb_tile_ops *tileops;
#endif
char __iomem *screen_base; //虚拟基地址
unsigned long screen_size; //虚拟显存大小
void *pseudo_palette; //调色板 一般设置为PALETTE_BUFF_CLEAR
#define FBINFO_STATE_RUNNING 0
#define FBINFO_STATE_SUSPENDED 1
u32 state; //状态 状态值为上面两个宏
void *fbcon_par;
void *par;
struct apertures_struct {
unsigned int count;
struct aperture {
resource_size_t base;
resource_size_t size;
} ranges[0];
} *apertures;
};
2. fb_var_screeninfo
struct fb_var_screeninfo {
__u32 xres; //水平分辨率
__u32 yres; //垂直分辨率
__u32 xres_virtual; //水平虚拟分辨率
__u32 yres_virtual; //存执虚拟分辨率
__u32 xoffset;//水平可视区域的偏移
__u32 yoffset;//垂直可视区域的偏移
__u32 bits_per_pixel; //每像素占用多少bit
__u32 grayscale; //灰度等级
struct fb_bitfield red; //红色位域 offset=11 length=5 (RGB565)
struct fb_bitfield green; //绿色位域 offset=5 length=6
struct fb_bitfield blue; //蓝色位域 offset=0 length=5
struct fb_bitfield transp; //透明度位域
__u32 nonstd; //非标准标志
__u32 activate; //激活标志
__u32 height; //物理高度
__u32 width; //物理宽度
__u32 accel_flags;//硬件加速标志
__u32 pixclock;
__u32 left_margin; //左边缘宽度
__u32 right_margin; //右边缘宽度
__u32 upper_margin; //上边缘宽度
__u32 lower_margin; //下边缘宽度
__u32 hsync_len; //水平同步长度
__u32 vsync_len; //垂直同步长度
__u32 sync;
__u32 vmode;
__u32 rotate;//旋转
__u32 reserved[5];
};
2.1 位域 fb_bitfield
3.fb_fix_screeninfo
4. 操作函数集
二. fb系统初始化
1. 主设备号
- #define FB_MAJOR 29
#define FB_MAJOR 29
2. fbmem_init
3. /proc下的接口fb_proc_fops
3.1 操作函数集
3.2 cat /prco/fb
先调用open方法
proc_fb_seq_ops
fb_seq_show函数
接着调用read方法
seq_read方法调用proc_fb_seq_ops的各个方法,最终将seq_file文件里的打印信息,复制到用户空间的buf里面
4. 字符设备捆绑的fb_fops
4.1 操作函数集
4.1.1 打开
4.1.2 读
4.1.3 写
4.1.4 控制
4.1.4.1 do_fb_ioctl函数
4.1.5 映射
三. 分配fb_info
四. 注册与注销framebuffer
1.注册framebuffer
1.1 register_framebuffer
1.2 fb_init_device
2.注销framebuffer
五. 编写framebuffer驱动步骤
1.framebuffer_alloc分配fb_info,设置其重要成员
2.填充可变fb_var_screeninfo和不可变参数fb_fix_screeninfo
3.定义并实现fb_ops并与fb_info捆绑
4.注册设备register_framebuffer
六. 应用层的一个测试实例
如果不是使用fb0那么修改下open函数啊,显示结果是rgb三个方块
七. 截图方法
- cat /dev/fb0 >0.raw
- ./ffmpeg -vcodec rawvideo -pix_fmt rgb565 -s 1920*1080 -i 0.raw -f image2 -vcodec mjpeg 0.jpg
cat /dev/fb0 >0.raw
./ffmpeg -vcodec rawvideo -pix_fmt rgb565 -s 1920*1080 -i 0.raw -f image2 -vcodec mjpeg 0.jpg
借助ffmpeg工具
或者用qt的demo有个screenshot
八. 显示图片方法(针对565 A8平台)
先编译ljpeg库,然后交叉编译下面的c代码 编译时候加上 -ljpeg
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
- #include <linux/fb.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <jpeglib.h>
- #include <jerror.h>
- #define FB_DEV "/dev/fb0"
- /***************** function declaration ******************/
- void usage(char *msg);
- unsigned short RGB888toRGB565(unsigned char red,
- unsigned char green, unsigned char blue);
- int fb_open(char *fb_device);
- int fb_close(int fd);
- int fb_stat(int fd, int *width, int *height, int *depth);
- void *fb_mmap(int fd, unsigned int screensize);
- int fb_munmap(void *start, size_t length);
- int fb_pixel(void *fbmem, int width, int height,
- int x, int y, unsigned short color);
- /************ function implementation ********************/
- int
- main(int argc, char *argv[])
- {
- /*
- * declaration for jpeg decompression
- */
- struct jpeg_decompress_struct cinfo;
- struct jpeg_error_mgr jerr;
- FILE *infile;
- unsigned char *buffer;
- /*
- * declaration for framebuffer device
- */
- int fbdev;
- char *fb_device;
- unsigned char *fbmem;
- unsigned int screensize;
- unsigned int fb_width;
- unsigned int fb_height;
- unsigned int fb_depth;
- unsigned int x;
- unsigned int y;
- /*
- * check auguments
- */
- if (argc != 2) {
- usage("insuffient auguments");
- exit(-1);
- }
- /*
- * open framebuffer device
- */
- if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
- fb_device = FB_DEV;
- fbdev = fb_open(fb_device);
- /*
- * get status of framebuffer device
- */
- fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);
- /*
- * map framebuffer device to shared memory
- */
- screensize = fb_width * fb_height * fb_depth / 8;
- fbmem = fb_mmap(fbdev, screensize);
- /*
- * open input jpeg file
- */
- if ((infile = fopen(argv[1], "rb")) == NULL) {
- fprintf(stderr, "open %s failed\n", argv[1]);
- exit(-1);
- }
- /*
- * init jpeg decompress object error handler
- */
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_create_decompress(&cinfo);
- /*
- * bind jpeg decompress object to infile
- */
- jpeg_stdio_src(&cinfo, infile);
- /*
- * read jpeg header
- */
- jpeg_read_header(&cinfo, TRUE);
- /*
- * decompress process.
- * note: after jpeg_start_decompress() is called
- * the dimension infomation will be known,
- * so allocate memory buffer for scanline immediately
- */
- jpeg_start_decompress(&cinfo);
- if ((cinfo.output_width > fb_width) ||
- (cinfo.output_height > fb_height)) {
- printf("too large JPEG file,cannot display\n");
- return (-1);
- }
- buffer = (unsigned char *) malloc(cinfo.output_width *
- cinfo.output_components);
- y = 0;
- while (cinfo.output_scanline < cinfo.output_height) {
- jpeg_read_scanlines(&cinfo, &buffer, 1);
- if (fb_depth == 16) {
- unsigned short color;
- for (x = 0; x < cinfo.output_width; x++) {
- color = RGB888toRGB565(buffer[x * 3],
- buffer[x * 3 + 1], buffer[x * 3 + 2]);
- fb_pixel(fbmem, fb_width, fb_height, x, y, color);
- }
- } else if (fb_depth == 24) {
- memcpy((unsigned char *) fbmem + y * fb_width * 3,
- buffer, cinfo.output_width * cinfo.output_components);
- }
- y++; // next scanline
- }
- /*
- * finish decompress, destroy decompress object
- */
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- /*
- * release memory buffer
- */
- free(buffer);
- /*
- * close jpeg inputing file
- */
- fclose(infile);
- /*
- * unmap framebuffer's shared memory
- */
- fb_munmap(fbmem, screensize);
- /*
- * close framebuffer device
- */
- fb_close(fbdev);
- return (0);
- }
- void
- usage(char *msg)
- {
- fprintf(stderr, "%s\n", msg);
- printf("Usage: fv some-jpeg-file.jpg\n");
- }
- /*
- * convert 24bit RGB888 to 16bit RGB565 color format
- */
- unsigned short
- RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
- {
- unsigned short B = (blue >> 3) & 0x001F;
- unsigned short G = ((green >> 2) << 5) & 0x07E0;
- unsigned short R = ((red >> 3) << 11) & 0xF800;
- return (unsigned short) (R | G | B);
- }
- /*
- * open framebuffer device.
- * return positive file descriptor if success,
- * else return -1.
- */
- int
- fb_open(char *fb_device)
- {
- int fd;
- if ((fd = open(fb_device, O_RDWR)) < 0) {
- perror(__func__);
- return (-1);
- }
- return (fd);
- }
- /*
- * get framebuffer's width,height,and depth.
- * return 0 if success, else return -1.
- */
- int
- fb_stat(int fd, int *width, int *height, int *depth)
- {
- struct fb_fix_screeninfo fb_finfo;
- struct fb_var_screeninfo fb_vinfo;
- if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
- perror(__func__);
- return (-1);
- }
- if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
- perror(__func__);
- return (-1);
- }
- *width = fb_vinfo.xres;
- *height = fb_vinfo.yres;
- *depth = fb_vinfo.bits_per_pixel;
- return (0);
- }
- /*
- * map shared memory to framebuffer device.
- * return maped memory if success,
- * else return -1, as mmap dose.
- */
- void *
- fb_mmap(int fd, unsigned int screensize)
- {
- caddr_t fbmem;
- if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
- MAP_SHARED, fd, 0)) == MAP_FAILED) {
- perror(__func__);
- return (void *) (-1);
- }
- return (fbmem);
- }
- /*
- * unmap map memory for framebuffer device.
- */
- int
- fb_munmap(void *start, size_t length)
- {
- return (munmap(start, length));
- }
- /*
- * close framebuffer device
- */
- int
- fb_close(int fd)
- {
- return (close(fd));
- }
- /*
- * display a pixel on the framebuffer device.
- * fbmem is the starting memory of framebuffer,
- * width and height are dimension of framebuffer,
- * x and y are the coordinates to display,
- * color is the pixel's color value.
- * return 0 if success, otherwise return -1.
- */
- int
- fb_pixel(void *fbmem, int width, int height,
- int x, int y, unsigned short color)
- {
- if ((x > width) || (y > height))
- return (-1);
- unsigned short *dst = ((unsigned short *) fbmem + y * width + x);
- *dst = color;
- return 0;
- }