***********《朱有鹏老师嵌入式linux核心课程》 *********** 《5.linux驱动开发-第7部分-5.7.framebuffer驱动详解》 -------------------------------------------------------- 本课程由朱老师物联网大讲堂推出并提供技术支持,课件可打包下载 网盘地址:http://yunpan.cn/cjVy3RAgfDufK 访问密码 4ad7 技术交流QQ群:朱老师物联网讲堂1群 397164505 -------------------------------------------------------- 第一部分、章节目录 5.7.1.framebuffer介绍 5.7.2.framebuffer应用编程实践1 5.7.3.framebuffer应用编程实践2 5.7.4.framebuffer应用编程实践3 5.7.5.framebuffer驱动框架总览 5.7.6.framebuffer驱动框架分析1 5.7.7.framebuffer驱动框架分析2 5.7.8.framebuffer驱动框架分析3 5.7.9.framebuffer驱动分析1 5.7.10.framebuffer驱动分析2 5.7.11.framebuffer驱动分析3 5.7.12.framebuffer驱动分析4 5.7.13.framebuffer驱动分析5 5.7.14.应用层为何不能设置分辨率 5.7.15.折腾内核的启动logo 第二部分、章节介绍 5.7.1.framebuffer介绍 本节介绍framebuffer的概念和来源、设计思想,fb设备的应用层接口等,为下节使用framebuffer应用编程打基础。 5.7.2.framebuffer应用编程实践1 本节基于framebuffer编写应用程序进行显示,主要是打开设备文件及获取设备的关键硬件信息、进行显存映射等。 5.7.3.framebuffer应用编程实践2 本节继续framebuffer应用编程,使用framebuffer在LCD上显示背景色. 5.7.4.framebuffer应用编程实践3 本节继续framebuffer应用编程,使用framebuffer更改分辨率等操作,最后讲述如何去写字、画图等。 5.7.5.framebuffer驱动框架总览 本节对内核的framebuffer驱动框架做整体介绍,各部分涉及哪些文件,每个文件是谁写的,具体功能是什么,详细的代码分析在后面。 5.7.6.framebuffer驱动框架分析1 半节主要分析fbmem_init函数及其内部涉及到的各个点,主要是字符设备驱动的注册和graphics类的创建等。 5.7.7.framebuffer驱动框架分析2 本节开始分析register_framebuffer接口函数,主要是一些检测函数和fops操作方法集合。 5.7.8.framebuffer驱动框架分析3 本节接着分析register_framebuffer接口函数,主要是显示模式、数组注册等。 5.7.9.framebuffer驱动分析1 本节开始分析framebuffer的驱动部分s3cfb.c文件,主要是platform_driver和platform_device的各自定义。 5.7.10.framebuffer驱动分析2 本节开始分析probe函数,主要是几个关键结构体的意义、resource的定义和使用、platdata的提供和数据交换等。 5.7.11.framebuffer驱动分析3 本节接着分析probe函数,主要是pdata中几个函数的调用,resource的使用,尤其是IORESOURCE_MEM类资源的使用。 5.7.12.framebuffer驱动分析4 本节接着分析probe函数,主要是一些硬件操作函数,和调用驱动框架层提供的接口来注册framebuffer设备的部分。 5.7.13.framebuffer驱动分析5 本节接着分析probe函数,主要是时钟设置等函数、内核启动logo的显示、backlight打开等操作。 5.7.14.应用层为何不能设置分辨率 本节通过分析fb驱动中的ioctl实现部分,来回答前面第4节中在应用层为何不能设置分辨率的问题,目的是教会大家如果利用源码分析来帮助自己解决问题。 5.7.15.折腾内核的启动logo 本节是实践课,带大家一起来折腾下内核的启动logo,包括替换一个自定义logo,以及修改内核代码让logo显示在屏幕中央。 第三部分、随堂记录 5.7.1.framebuffer介绍 5.7.1.1、什么是framebuffer (1)裸机中如何操作LCD (2)OS下操作LCD的难点 (3)framebuffer帧缓冲(简称fb)是linux内核中虚拟出的一个设备 (4)framebuffer向应用层提供一个统一标准接口的显示设备 (5)从驱动来看,fb是一个典型的字符设备,而且创建了一个类/sys/class/graphics 5.7.1.2、framebuffer的使用 (1)设备文件 /dev/fb0 (2)获取设备信息 #include (3)mmap做映射 (4)填充framebuffer 5.7.2.framebuffer应用编程实践1 5.7.2.1、打开设备 5.7.2.2、获取设备信息 (1)不可变信息FSCREENINFO,使用ioctl的FBIOGET_FSCREENINFO名 (2)可变信息VSCREENINFO,使用ioctl的FBIOGET_VSCREENINFO名 5.7.3.framebuffer应用编程实践2 5.7.3.1、mmap做映射 做完了mmap后fb在当前进程中就已经就绪了,随时可以去读写LCD显示器了。 5.7.3.2、fb显示之刷背景 5.7.4.framebuffer应用编程实践3 5.7.4.1、设置分辨率 (1)实验失败,实验结果是只能修改虚拟分辨率,不能修改可视分辨率。原因要去驱动里找。 (2)正确的做法是在驱动中去修改参数,然后重新编译运行,才能解决。 5.7.4.2、写字、画线、图片显示等 5.7.5.framebuffer驱动框架总览 5.7.5.1、驱动框架部分 (1)drivers/video/fbmem.c。主要任务:1、创建graphics类、注册FB的字符设备驱动、提供register_framebuffer接口给具体framebuffer驱动编写着来注册fb设备的。本文件相对于fb来说,地位和作用和misc.c文件相对于杂散类设备来说一样的,结构和分析方法也是类似的。 (2)drivers/video/fbsys.c。这个文件是处理fb在/sys目录下的一些属性文件的。 (3)drivers/video/modedb.c。这个文件是管理显示模式(譬如VGA、720P等就是显示模式)的 (4)drivers/video/fb_notify.c 5.7.5.2、驱动部分 (1)drivers/video/samsung/s3cfb.c,驱动主体 (2)drivers/video/samsung/s3cfb_fimd6x.c,里面有很多LCD硬件操作的函数 (2)arch/arm/mach-s5pv210/mach-x210.c,负责提供platform_device的 (3)arch/arm/plat-s5p/devs.c,为platform_device提供一些硬件描述信息的 5.7.5.3、如何分析 (1)经验 (2)分析menuconfig、Makefile、Kconfig等 (3)内核编译后检查编译结果中的.o文件 5.7.6.framebuffer驱动框架分析1 5.7.6.1、fbmem_init函数 (1)#ifdef MODULE (2)fb_proc_fops和fb在proc文件系统中的表现 (3)register_chrdev注册fb设备 (4)class_create创建graphics类 (5)fbmem_exit的对应 5.7.6.2、fb_fops (1)read/write/mmap/ioctl (2)registered_fb和num_registered_fb (3)struct fb_info 5.7.7.framebuffer驱动框架分析2 5.7.7.1、register_framebuffer (1)fb驱动框架开放给驱动编写着的注册接口 (2)fb_check_foreignness (3)remove_conflicting_framebuffers (4)device_create (5)fb_init_device 5.7.7.2、fb在sysfs中的接口 (1)device_attrs (2)dev_set_drvdata和dev_get_drvdata 5.7.8.framebuffer驱动框架分析3 5.7.8.1、fb的mode (1)什么是mode (2)fb_var_to_videomode (3)fb_add_videomode 5.7.8.2、注册登记该fb设备 (1)registered_fb[i] = fb_info; (2)结合fb_read等函数中对fb_info的使用 (3)关键点:数据如何封装、数据由谁准备由谁消费、数据如何传递 5.7.8.3、fb_notifier_call_chain 5.7.9.framebuffer驱动分析1 5.7.9.1、s3cfb.c (1)注意目录结构的组织 (2)s3cfb_driver 5.7.9.2、s3c_device_fb (1)mach-x210.c中,被使用 (2)devs.c中 (3)resource的定义和作用 5.7.10.framebuffer驱动分析2 5.7.10.1、probe函数分析 (1)struct s3c_platform_fb 这个结构体是fb的platform_data结构体,这个结构体变量就是platform设备的私有数据,这个数据在platform_device.device.platform_data中存储。在mach文件中去准备并填充这些数据,在probe函数中通过传参的platform_device指针取出来。 (2)struct s3cfb_global 这个结构体主要作用是在驱动部分的2个文件(s3cfb.c和s3cfb_fimd6x.c)的函数中做数据传递用的。 (3)struct resource (4)regulator 5.7.10.2、platform_data的传递过程 (1)to_fb_plat (2)s3cfb_set_platdata (3)smdkc110_machine_init 5.7.11.framebuffer驱动分析3 5.7.11.1、struct s3cfb_lcd 5.7.11.2、pdata->cfg_gpio 5.7.11.3、pdata->clk_on 5.7.11.4、resource的处理 (1)platform_device中提供resource结构体数组 (2)probe中platform_get_resource取出resource并且按FLAG分头处理 5.7.12.framebuffer驱动分析4 5.7.12.1、一些硬件操作 (1)s3cfb_set_vsync_interrupt (2)s3cfb_set_global_interrupt 5.7.12.2、s3cfb_init_global 5.7.12.3、向框架注册该fb设备 (1)s3cfb_alloc_framebuffer (2)s3cfb_register_framebuffer 5.7.13.framebuffer驱动分析5 5.7.13.1、一些硬件操作 (1)s3cfb_set_clock (2)s3cfb_set_window (3)s3cfb_display_on 5.7.13.2、驱动中处理中断 (1)platform_get_irq (2)request_irq 5.7.13.3、logo显示 s3cfb_probe fb_prepare_logo fb_find_logo 真正查找logo文件 fb_show_logo fb_show_logo_line 真正显示logo fb_do_show_logo info->fbops->fb_imageblit 实际操作硬件fb进行显示工作的函数 5.7.13.4、backlight点亮 5.7.14.应用层为何不能设置分辨率 5.7.14.1、问题描述 (1)第4节时试图在应用层设置分辨率失败了,原因何在? (2)定位问题:肯定是驱动的事儿 (3)进一步驱动中定位:ioctl部分的事儿 5.7.14.2、fb的ioctl部分 (1)fb是典型的字符设备驱动 (2)ioctl分为2部分,在驱动框架部分和驱动部分各有一半 (3)一路追踪找问题 fbmem.c fbmem_init register_chrdev fb_fops fb_ioctl do_fb_ioctl fb_set_var info->fbops->fb_check_var(s3cfb.c中的s3cfb_check_var) 5.7.14.3、让自己的开发板正常显示 (1)移植的核心是lcd参数的更改 5.7.15.折腾内核的启动logo 5.7.15.1、自定义内核启动logo (1)sudo apt-get install netpbm (先让ubuntu上网) (2)pngtopnm logo.png | ppmquant -fs 224 | pnmtoplainpnm > logo_linux_clut224.ppm (3)用制作好的logo_linux_clut224.ppm,替换源码目录drivers/video/logo/logo_x210_clut224.ppm,然后重新编译内核 (4)启动新内核,就能看到新的启动logo了。 5.7.15.2、让logo显示在屏幕中央 image.dx = (info->var.xres - logo->width) / 2; // logo显示的起始坐标x值 image.dy = (info->var.yres - logo->height) / 2;