笔记整理—linux驱动开发部分(9)framebuffer驱动框架

本章我们以X210开发板的屏幕驱动,对framebuffer驱动框架进行介绍。

这里涉及到一下几个文件fbmem.c、fbsys.c(处理sys目录下属性文件)、modedb.c(显示格式)、fb_notify.c(反向唤醒、链表相关、通知链等)。

graphics是fb相关个股类,注册fb字符驱动,提供register_framebuffer/unregister_framebuffer去进行注册和注销fb设备。

驱动部分为:s3cfb.c(驱动主体)、mach_x210.c(platform_device)、devs.c(platform描述信息)、s3cfb_fimd6x.c(LCD硬件操作方法)。

通过分析menuconfig、Makefle、Kconfig等文件分析过程,分析编译的.o文件,十分有什么文件被编译为.o文件则为被包含的文件。

复制代码
module_init()//模块化
subsys_initcall()//内核集成

proc_create创建fb在proc文件系统,fb_seq_show是proc show方法打印次设备号。(cat /proc/fb), fbmem_exit于模块化相关,fb_fops硬件操作方法以函数指针方法实现,fb的设备号为29,不同之处在于次设备号。

生产一个fb设备就去实现一个struct fb_info用于管理所有已经注册的fb设备(misc设备以链表方式管理)多以数组形式表示,以下标做次设备号。

复制代码
int num_register_fb __read_mostly;//注册设备数
__read_mostly 编译器优化方向(读)

struct fb_info中封装了正真的硬件操作方法(fb_info->fb_fops->方法)。

复制代码
register_framebuffer(struct fb_info *fb_info)
    fb_check_foreignness(fb_info)//大小端检测
    remove_conflicting_framebuffers(fb_info->apertures, 
fb_info->fix.id,fb_is_primary_device(fb_info));//去除冲突的fb
    fb_info->dev = device_create(fb_class, fb_info->device, MKDEV(FB_MAJOR, i), NULL, "fb%d", i);//遍历check那个次设备号没被使用(0-31)
    fb_init_device(fb_info);
    //不使用全局变量而是做传递(大量数据传递)
        dev_set_drvdata(fb_info->dev, fb_info);//kernel总体部分,做设备驱动数据交互(保存)
        void *dev_get_drvdata(const struct device *dev)//内核得到数据,进行处理
        device_create_file(fb_info->dev, &device_attrs[i]);//sysfs中创建文件

bbp:bits_per_pixel,使用几位去描述一个像素点。

提供驱动或应用使用的接口:

复制代码
fb_var_to_videomode()//去fb中提取信息成为设置参数(提取)
fb_add_videomode()//将提取到的videmode进行添加

fb驱动,以platform方式实现驱动,因为LCD操控器被集成了。

复制代码
static struct platform_driver s3cfb_driver = {
	.probe = s3cfb_probe,//初始化方法
	.remove = __devexit_p(s3cfb_remove),//移除方法
	.driver = {
		   .name = S3CFB_NAME,//platform_driver对照名
		   .owner = THIS_MODULE,
	},
};

在mach.c中被platform_add.devices()添加。

复制代码
struct platform_device s3c_device_fb = {
	.name		  = "s3cfb",//与driver在的参数对应
	.id		  = -1,//自分配id
	.num_resources	  = ARRAY_SIZE(s3cfb_resource),//资源数组个数
	.resource	  = s3cfb_resource,//资源数组(地址范围(静态映射),中断资源)
	.dev		  = {
		.dma_mask		= &fb_dma_mask,
		.coherent_dma_mask	= 0xffffffffUL
	}
};

对于ARM而言,寄存器与内存是统一编址的。

复制代码
s3cfb_probe()//在此去实现device和driver的相遇

probe函数分析:

复制代码
static int __devinit s3cfb_probe(struct platform_device *pdev)
    struct s3c_platform_fb *pdata;//platform_data,用于描述platform设备私有数据在                                    
    platform_device.device.platform_data,在mach文件在填充,之后在probe中使用
    struct s3cfb_global *fbdev;//在fb驱动(驱动框架)中进行数据交互(s3cfb.c和s3cfb_fimd6x.c)
    struct resource *res;//描述资源(内存、中断等)
    kzalloc();内存分配
    fbdev->dev = &pdev->dev;//挂接数据
    regulator()//整流器,针对耗电驱动,实现电压电流不同模式供电
    pdata = to_fb_plat(&pdev->dev);//从pdev得到pdata(一般存在device中),但也可以使用别的方法传递这个数据(s3cfb_set_platdata)实现pdata,本质是是对device中的pdata的填充,如何填充可以看menuconfig的设置,使用pdata是灵活的,不会写死的。
    struct s3cfb_lcd封装了LCD的物理属性(fbdev->lcd==pdata->lcd)
    pdata->cfg_gpio(pdev);ek070tn93_cfg_gpio()初始化LCD使用的GPIO
    pdata->clk_on()=NULL;//用于打开LCD时钟默认情况下,用什么设备,就开什么时钟,别的默认是关闭的
    //resource使用流程
    platform_get_resource();取各种类型资源,以flags做对比
    request_mem_region();取出资源做内存申请
    ioremap()//做内存映射fbdev->reg
    //resource使用流程结束
    s3cfb_set_vsync_interrupt();//vsync中断使能
	s3cfb_set_global_interrupt(;//全局中断
	s3cfb_init_global();//初始化global相关(output;display_mode;polarity;timing;LCD_size等)
    s3cfb_alloc_framebuffer()//完成fb结构体填充与malloc
    s3cfb_register_framebuffer();//注册fb
    s3cfb_set_clock();//像素时钟<-s3cfb.init_fbinfo
	s3cfb_set_window();
    platform_get_irq();//中断设置
    backlight_on();开背景
    fb_prepare_logo()//logo获取
        调用fb_find_logo()//通过宏定义确定ppm文件
    fb_show_logo()//显示logo
        调用fb_show_logo_line()
            调用fb_do_show_logo()
                调用fb_imageblit()

应用层mode的var与驱动层mode的var会进行判别用户层十分合法

复制代码
if(var->xres>lcd->xres)
    var->xrex=lcd->xres

LCD窗口设计(虚拟窗口),这样做是为了减少刷新压力(不动的内容不刷新,只去刷新在改变的部分)

相关推荐
GG-_-Bond几秒前
9.1kv存储持久化模拟面试
linux·c语言·数据结构·c++
Dola_Zou20 分钟前
Linux工控机核心算法防逆向与自动化加固方案
linux·自动化·软件加密
江湖人称菠萝包29 分钟前
【Qt】《Qt 5.9 C++开发指南》笔记-Chapter3-Qt类库概述
笔记·qt·qt5
欧米欧42 分钟前
解析Linux从umask位运算到粘滞位
linux
AAA代码批发商1 小时前
Days 46 i.MX6ULL 裸机开发|从内核切入外设,汇编点亮 LED(补充)
arm开发·嵌入式·裸机开发
无敌贵点大王1 小时前
RTThread学习记录10——C语言实现面向对象的编程
c语言·stm32·学习·链表
江屿风1 小时前
【Linux系统】【Linux进程终止等待详解与程序替换机制初体验】流食般投喂
linux·运维·笔记·系统架构·centos·unix
螺蛳粉 螺蛳粉1 小时前
CentOS 7.9 自建 Yum 源服务器搭建指南
linux·服务器·centos
单片机仿真设计2 小时前
【proteus仿真】基于 STM32F103 的汽车温度监测系统(仿真图+程序)
stm32·单片机·嵌入式硬件·proteus·课设
anew___2 小时前
舵机——让 Arduino 动起来
c++·stm32·单片机·嵌入式硬件·c