分析内种LCD驱动程序框架
LCD在fbmem.c文件中
1.找到init.函数
static int __initfbmem_init(void)
{
做的工作: (1).if (register_chrdev(FB_MAJOR,"fb",&fb_fops))注册字符处理函数结构体,以及生成设备号,
(2)fb_class = class_create(THIS_MODULE, "graphics");生成一个类
}
2.打开注册设备中的字符函数结构体fb_fops

static const struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
.ioctl = fb_ioctl,
.mmap = fb_mmap,
.open = fb_open,
.release = fb_release,
};
APP层如果要打开这个设备,就会执行经过系统调用执行fb_open函数
3.分析这个函数
static int fb_open(struct inode *inode, struct file *file)
{
int fbidx = iminor(inode);生成一个次设备号
struct fb_info *info;定义一个fb_info结构体
if (!(info = registered_fb[fbidx]))把registered_fb[]结构体数组中以这个设备的次设备号为索引,把数组中的值赋值给info

}
4.如果应用程序要对这个驱动进行读写操作,就会调用read函数
static ssize_t
fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
那么读函数主要做的工作:

int fbidx = iminor(inode);获得设备的次设备号
struct fb_info *info = registered_fb[fbidx];在fb_info结构体中以此设备号为索引找到一个成员赋值给info变量。
if (info->fbops->fb_read)如果字符结构体函数定义fb_read,则执行相应处理
return info->fbops->fb_read(info, buf, count, ppos);
total_size = info->screen_size; 虚拟屏的大小
buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,分配页大小的缓冲区
src = (u32 __iomem *) (info->screen_base + p);//显存基地址,作为源地址
dst = buffer;把分配的缓冲区作为目的地址
*dst++ = fb_readl(src++);把源地址中的数据拷贝到目的地址中
if (copy_to_user(buf, buffer, c))把数据传递到应用程序
kfree(buffer);释放缓冲区

}
不管是读还是写都用到了registered_fb[];
5.那么这个结构体数组是怎么赋值的呢registered_fb[];
在这个函数中有对这个结构体进行赋值
int register_framebuffer(struct fb_info *fb_info)
{
分析这个函数
fb_info->dev = device_create(fb_class, fb_info->device,
MKDEV(FB_MAJOR, i), "fb%d", i);在fb_class类下面创建一个类的设备,
fb_init_device(fb_info);初始化这个设备
......对fb_info进行初始化操作
registered_fb[i] = fb_info;把这个传进来的变量存入数组中,那么是由谁调用这个函数,并传进参数的呢
可以发现有很多不同厂家的触摸屏.c函数都会调用这个函数,这说明这个函数是抽象出来的,大家都在用它,那么根据什么来区别他们呢,那就根据registered_fb数组中的成员,
}
6.比如打开s3c2410fb.c这个函数,
找到init函数
int __devinit s3c2410fb_init(void)
{
return platform_driver_register(&s3c2410fb_driver);
}
进入到int platform_driver_register(struct platform_driver *drv)里面
{
drv->driver.bus = &platform_bus_type;
....
return driver_register(&drv->driver);
}
}
进入int driver_register(struct device_driver * drv)函数里面
{....
return bus_add_driver(drv);
int bus_add_driver(struct device_driver *drv)
error = driver_attach(drv);
bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
driver_probe_device(drv, dev);
if (drv->bus->match && !drv->bus->match(dev, drv))
return ret;如果设备和驱动的名字匹配,那么就会调用probe函数,也就是会调用
.probe = s3c2410fb_probe,这个函数
7.分析这个函数static int __init s3c2410fb_probe(struct platform_device *pdev)
{
主要工作:struct fb_info *fbinfo;定义一个fb_info结构体指针变量
fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);为这个结构体指针变量分配大小
....初始化这个结构体
ret = register_framebuffer(fbinfo);注册这个结构体,就把这个结构体注册到内核中,也就是存在registered_fb数组中去,
}
总结:整个LCD驱动架构就是设备和驱动分离
驱动是对所有的LCD抽出来的共性
设备是根据不同厂家的LCD来进注册,如果设备的名字和驱动的名字相同,那么就可以调用probe函数对着设备进行注册;从而达到了设备和驱动分离的目的。

LCD内核自带驱动分析的更多相关文章

  1. linux内核SPI总线驱动分析(一)(转)

    linux内核SPI总线驱动分析(一)(转) 下面有两个大的模块: 一个是SPI总线驱动的分析            (研究了具体实现的过程) 另一个是SPI总线驱动的编写(不用研究具体的实现过程) ...

  2. linux内核SPI总线驱动分析(二)(转)

    简而言之,SPI驱动的编写分为: 1.spi_device就构建并注册  在板文件中添加spi_board_info,并在板文件的init函数中调用spi_register_board_info(s3 ...

  3. s3c2440液晶屏驱动 (非内核自带) linux-4.1.24

    对于,不想逐一检查内核自带驱动,想自己编写驱动. 1,make menuconfig 去掉 编译到内核,改为 M 编译为 模块(因为要用到里面的3个.ko 驱动) Device Drivers --- ...

  4. Linux驱动之内核自带的S3C2440的LCD驱动分析

    先来看一下应用程序是怎么操作屏幕的:Linux是工作在保护模式下,所以用户态进程是无法象DOS那样使用显卡BIOS里提供的中断调用来实现直接写屏,Linux抽象出FrameBuffer这个设备来供用户 ...

  5. Linux的LCD驱动分析及移植

    测试平台 宿主机平台:Ubuntu 12.04.4 LTS 目标机:Easy-ARM IMX283 目标机内核:Linux 2.6.35.3 LCD驱动分析 LCD屏的驱动总体上分成两块,一块是GUI ...

  6. 高通 android平台LCD驱动分析

    目前手机芯片厂家提供的源码里包含整个LCD驱动框架,一般厂家会定义一个xxx_fb.c的源文件,注册一个平台设备和平台驱动,在驱动的probe函数中来调用register_framebuffer(), ...

  7. S3C6410 LCD驱动分析(转)

    一. 理论分析1. 几个概念:FIMC :    Fully Interactive Mobile Camera (完全交互式移动摄像机)FIMD:     Fully Interactive Mob ...

  8. mini2440触摸屏驱动分析

    mini2440驱动分析系列之 ---------------------------------------Mini2440触摸屏程序分析 By JeefJiang July,8th,2009 这是 ...

  9. 19.Linux-USB总线驱动分析

    如下图所示,以windows为例,我们插上一个没有USB设备驱动的USB,就会提示你安装驱动程序 为什么一插上就有会提示信息? 是因为windows自带了USB总线驱动程序, USB总线驱动程序负责: ...

随机推荐

  1. EasyUI-datagrid 对于展示数据进行处理(formatter)

    一:声明datagrid列,在列中添加formatter属性,并指定js方法 columns = [[ { title: '编号', field: 'Id', width: 100, sortable ...

  2. hdu4449Building Design(三维凸包+平面旋转)

    链接 看了几小时也没看懂代码表示的何意..无奈下来问问考研舍友. 还是考研舍友比较靠谱,分分钟解决了我的疑问. 可能三维的东西在纸面上真的不好表示,网上没有形象的题解,只有简单"明了&quo ...

  3. 搭建一个简单的Struts2(Struts2_HelloWorld)

    1.导入Jar包 2.配置web.xml 1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-ap ...

  4. springmvc 用注解方式添加事务不生效解决方法

    springmvc 事务注册有很多种方法,在此我只mark 用注解方式添加transaction不生效的解决办法. springmvc 注解方法添加事务步骤: 1.在 spring的 root-con ...

  5. JQuery_DOM 节点操作之复制、替换和 删除节点

    一.复制节点 <script type="text/javascript" src="jquery-1.12.3.min.js"></scri ...

  6. jquery TypeError: $(...).live is not a functio,动态添加class的点击事件处理

    jq版本更新后无live函数的处理.TypeError: $(...).live is not a function jquery live函数语法 jquery版本更新, 发现一个问题: jq自带的 ...

  7. (转)assert 断言式编程

    编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设,可以将断言看作是异常处理的一种高级形式.断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真.可以在任何时候启用 ...

  8. 配置handler vs2013 iis8.0

    <system.webServer> <modules runAllManagedModulesForAllRequests="true" /> <v ...

  9. 并列统计CASE WHEN

    select sum(case when depart = 'Physical' then 1 else 0 end) PhyTotal, sum(case when depart = 'Chemis ...

  10. 简述alert和console.log的区别

    生活中还是得有发现美好和差别的眼睛~~ 学习前端那么久既然还不知道alert和console.log的差别~~~~ 蓝瘦,香菇~~~ 本菜鸟一直以为alert和console.log其实是一样的用法, ...