linux驱动开发之应用程序控制LCD屏

1, 打开设备
int fd = open(“/dev/fb0”, O_RDWR);
2, 获取到lcd屏的信息xres, yres, bpp

        struct fb_var_screeninfo var;//var是容器,用来存放数据

        ioctl(fd, FBIOGET_VSCREENINFO, &var);//FBIOGET_VSCREENINFO表示获取可变屏幕信息,以后看到GET,一般表示拿东西,这里向驱动拿
                            |
                            .unlocked_ioctl = fb_ioctl,
                                    |
                                    struct fb_info *info = file_fb_info(file);//
                                                |//从registered_fb数组中得到fb_info
                                                struct fb_info *info = registered_fb[fbidx];
                                    do_fb_ioctl(info, cmd, arg);
                                        |
                                        void __user *argp = (void __user *)arg;
                                        switch (cmd) {
                                            case FBIOGET_VSCREENINFO:
                                                var = info->var;
                                                copy_to_user(argp, &var, sizeof(var)) ? -EFAULT : 0;


        size_t length = var.xres * var.yres * var.bits_per_pixel / 8

3,映射显存(一帧)到用户空间

        //返回一个地址
         char *addr = mmap(NULL, size_t length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

        framebuffer_ptr =(char *)mmap(  NULL,//如果此值为NULL,则表示用内核来自动给你分配一块虚拟空间
                                 screensize,        //空间大小
                                 PROT_READ|PROT_WRITE,//权限
                                 MAP_SHARED,        //是否可以共享
                                 framebuffer_fd,        //文件描述符
                                 0);            //从哪个地方开始

4, 得到图片数据,将数据写入到addr

        /*1.打开一副图片*/
        pic_fd =open(argv[2],O_RDWR);
        printf("pic_fd=%d\n",pic_fd);

        /*2.获取图片大小*/
        len =lseek(pic_fd, 0, SEEK_END);//SEEK_END表示定位到一个文件的末尾
        printf("len =%ld\n",len);

        buffer =(char *)malloc(len);

        lseek(pic_fd, 0, SEEK_SET);
        /*3.读取图片数据*/
        read(pic_fd,buffer,len); 

        // buffer 存了bmp的图片数据, framebuffer_ptr映射之后的显存位置
        draw_bmp(buffer,(unsigned short *) framebuffer_ptr);
            |
             bmp_read_file(bmpfilename, &bmpdata);//跳过bmp文件头
             bmp2fb16_rgb565(bmpdata, fb);
                |//bmp2fb16_rgb565(unsigned char *bmpdata,unsigned short *fb16)
                 fb16_buff = fb16; //  fb16_buff就是framebuffer_ptr,映射之后的显存位置
                for (y = ysize; y > 0 ; y--)
                {
                    for (x = 0 ; x < xsize; x++) /*copy one line to frame buffer*/
                    {   
                        /*copy one pixel to frame buffer*/
                        b = *bmpdata;
                        bmpdata++;
                        b >>= 3;
                        g = *bmpdata;
                        bmpdata++;
                        g >>= 2;
                        r = *bmpdata;
                        bmpdata++;
                        r >>= 3;
                        pixel16 = (unsigned short) ((r << 11) | (g << 5) | b);  
                        *( fb16_buff +  (y* xsize + x)  ) = pixel16;//将一个像素填写到显存
                    }
                }

程序文件:链接:https://pan.baidu.com/s/1ggeHO1H 密码:yfvz
这里写图片描述
lcd.test是主程序
jpeg2bmp.o是图片数据格式的解析
framebuffer.o是初始化framebuffer子系统
把lcd_test复制到指定路径中:cp lcd_test *.bmp /opt/rootfs/drv_module/
在开发板执行命令./lcd_test /dev/fb0 logo_girl_800*480.bmp
出现以下调试信息
这里写图片描述
程序阻塞在这里,等待用户的输出(输入1显示图片,输入2显示文字)
附录:
readme.txt

1.用bmp文件 800*480
2.注意 x,y参数 800 ,480
unsigned int bpp    =16;
unsigned int xsize  =800;
unsigned int ysize  =480;

在mach-smkv210.c 查看并修改.
static struct s3c_fb_pd_win smdkv210_fb_win0 = {
    /*
    .win_mode = {
        .left_margin    = 13,
        .right_margin   = 8,
        .upper_margin   = 7,
        .lower_margin   = 5,
        .hsync_len  = 3,
        .vsync_len  = 1,
        .xres       = 800,
        .yres       = 480,
    },
    .max_bpp    = 32,
    .default_bpp    = 24,
    */


    .win_mode = {
            .left_margin       = 46,
            .right_margin   = 219,
            .upper_margin   = 23,
            .lower_margin   = 22,
            .hsync_len  = 10,
            .vsync_len  = 10,
            .xres       = 800,
            .yres       = 480,
        },
        .max_bpp    = 32,
        .default_bpp    = 16,//这是16bpp

};


3.main()中
buffer =(char *)malloc(1152054); //不要小于bmp文件大小

运行:
[root@farsight /]# ./lcd_test /dev/fb0 logo_icer_800x480.bmp
pic_fd=3
len =1152054
xres =800
yres =480
screensize =768000
framebuffer_ptr is mmaped ok!
1
test picture!
loadjpeg00000!!!!
bmpread0000000!!!!
bm2fb1600000000000!!!!
2
length1 =23
length =23
length =23
发布了97 篇原创文章 · 获赞 135 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/weixin_37787043/article/details/79266374