03Camera驱动详细分析1Linux 设备模型介绍
Linux设备驱动程序原理及框架-内核模块入门篇
Linux设备驱动程序原理及框架-内核模块入门篇内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块内核模块介绍Linux采用的是整体式的内核结构,这种结构采用的是整体式的内核结构,采用的是整体式的内核结构的内核一般不能动态的增加新的功能。
为此,的内核一般不能动态的增加新的功能。
为此,Linux提供了一种全新的机制,叫(可安装) 提供了一种全新的机制,可安装) 提供了一种全新的机制模块” )。
利用这个机制“模块”(module)。
利用这个机制,可以)。
利用这个机制,根据需要,根据需要,在不必对内核重新编译链接的条件将可安装模块动态的插入运行中的内核,下,将可安装模块动态的插入运行中的内核,成为内核的一个有机组成部分;成为内核的一个有机组成部分;或者从内核移走已经安装的模块。
正是这种机制,走已经安装的模块。
正是这种机制,使得内核的内存映像保持最小,的内存映像保持最小,但却具有很大的灵活性和可扩充性。
和可扩充性。
内核模块内核模块介绍可安装模块是可以在系统运行时动态地安装和卸载的内核软件。
严格来说,卸载的内核软件。
严格来说,这种软件的作用并不限于设备驱动,并不限于设备驱动,例如有些文件系统就是以可安装模块的形式实现的。
但是,另一方面,可安装模块的形式实现的。
但是,另一方面,它主要用来实现设备驱动程序或者与设备驱动密切相关的部分(如文件系统等)。
密切相关的部分(如文件系统等)。
课程内容内核模块介绍应用层加载模块操作过程内核如何支持可安装模块内核提供的接口及作用模块实例内核模块应用层加载模块操作过程内核引导的过程中,会识别出所有已经安装的硬件设备,内核引导的过程中,会识别出所有已经安装的硬件设备,并且创建好该系统中的硬件设备的列表树:文件系统。
且创建好该系统中的硬件设备的列表树:/sys 文件系统。
(udev 服务就是通过读取该文件系统内容来创建必要的设备文件的。
)。
linux驱动模型
我们将详细的介绍Linux的设备驱动模型。
Linux设备驱动模型是一个相当复杂的系统,对于初学者来说真有些无从入手。
而且更加困难的是,随着新的Linux Kernel的release,Linux 的设备驱动模型总会有或大或小的变化,我们将尽量展现Linux Kernel 的这种变化。
早期的Linux内核(版本2.4之前)并没有实现一个统一的设备模型,设备节点的创建一般是mknod命令手动创建或利用devfs文件系统创建。
早期的Linux发行版一般会采用手动创建的方式预先把通常用到的节点都创建出来,而嵌入式系统则会采用devfs的方式。
起初Linux 2.6 内核还支持devfs,但从2.6.18开始,内核完全移除了devfs系统而采用的udev的方式动态的创建设备节点。
因此,新的Linux发行版都采用udev的方式管理设备节点文件。
Linux2.6设备驱动模型的基本元素是Class、Bus、Device、Driver,下面我们分别介绍各个部分。
Class 和Class Device驱动模型最基本的概念是设备及其类别,Linux中使用struct class 和struct class_device来管理不同类别的设备。
由于设备驱动模型是一个复杂的系统,我们还是从一个简单的例子开始介绍,然后在逐步展开。
其实实现设备节点的动态创建是一个很简单的事情,并不需要太多的代码。
我们修改我们的驱动初始化函数如下:#include <linux/device.h>#define DEVNAME "hello"static dev_t dev;static struct class *hello_c lass;static struct cdev *hello_cdev;static int __init hello_init(void){int error;error = alloc_chrdev_region(&dev, 0, 2, "hello");if (error){printk("hello: alloc_chardev_region failed! ");goto out;}hello_cdev = cdev_alloc();if (hello_cdev == NULL){printk("hello: alloc cdev failed! ");error = -ENOMEM;goto out_chrdev;}hello_cdev->ops = &hello_fops;hello_cdev->owner = THIS_MODULE;error = cdev_add(hello_cdev, dev, 1);if (error){printk("hello: cdev_add failed! ");goto out_cdev;}hello_class = class_create(THIS_MODULE, DEVNAME);if (IS_ERR(hello_class)){error = PTR_ERR(hello_class);goto out_chrdev;}class_device_create(hello_class, NULL, dev, NULL, DEVNAME);memset (hello_buf, 0, sizeof(hello_buf));memcpy(hello_buf, DEFAULT_MSG, sizeof(DEFAULT_MSG));printk("hello: Hello World! ");return 0;out_cdev:cdev_del(hello_cdev);out_chrdev:unregister_chrdev_region(hello_cdev->dev, 2);out:return error;}static void __exit hello_exit(void){class_device_destroy(hello_class, dev);class_destroy(hello_class);unregister_chrdev_region(hello_cdev->dev, 2);cdev_del(hello_cdev);printk("hello: Goodbye World ");}重新编译这个驱动程序,当加载这个驱动到内核中时,系统(一般是hotplug和udev系统)就会自动的创建我们指定的设备名字:/dev/hello,同时,你也可以发现在sysfs系统中添加了新的文件:/sys/class/hello/hello/。
Linux设备驱动模型与sysfs---platform总线设备驱动
Linux在2.6版本引入了设备驱动模型,设备驱动模型负责统一实现和维护一些特性,诸如:热插拔、对象生命周期、用户空间和驱动空间的交互等基础设施1.设备驱动模型基本概念设备驱动模型主要包含:类(class)、总线(bus)、设备(device)、驱动(driver),它们的本质都是内核中的几种数据结构的“实例”∙类的本质是class结构体类型,各种不同的类其实就是class的各种实例∙总线的本质是bus_type结构体类型,各种不同的总线其实就是bus_type的各种实例∙设备的本质是device结构体类型,各种不同的设备其实就是device的各种实例∙驱动的本质是device_driver结构体类型,各种不同的驱动其实就是device_driver的各种实例2.sysfs基本概念sysfs其实就是/sys目录,其主要作用就是:展示设备驱动模型中各组件的层次关系,并将各组件的本体——内核中的数据结构以文件形式呈现,方便用户层查看及操作3./sys目录结构与设备驱动模型∙/sys目录结构很好的展示了驱动设备模型,如图:∙注意:同一个设备可能在/sys中存在多个设备文件,比如一颗led的设备文件可能在/sys/bus/platform/devices/led1,同时还有一个在/sys/class/leds/led1。
虽然他们都是同一颗led的设备文件,但是他们的来源、机制、原理都是不同的,不能混为一谈4.各组件的特性与联系∙kobject:设备驱动模型各实例的最基本单元,提供一些公用型服务如:提供该实例在sysfs中的操作方法(show和store);提供在sysfs中以文件形式存在的属性,其实就是应用接口;提供各个实例的层次架构,让sysfs中弄出目录结构。
设备驱动模型中每个实例内部都会包含一个kobject∙总线、设备、驱动,这三者有着密切的联系。
在内核中,设备和驱动是分开注册的,注册设备的时候,并不需要驱动已经存在,而驱动被注册的时候,也不需要对应的设备已经被注册。
Linux系统设备驱动程序概述精品文档12页
Linux系统设备驱动程序概述1.1 Linux设备驱动程序分类Linux设备驱动程序在Linux的内核源代码中占有很大的比例,源代码的长度日益增加,主要是驱动程序的增加。
在Linux内核的不断升级过程中,驱动程序的结构还是相对稳定。
在2.0.xx到2.2.xx的变动里,驱动程序的编写做了一些改变,但是从2.0.xx的驱动到2.2.xx的移植只需做少量的工作。
Linux系统的设备分为字符设备(char device),块设备(block device)和网络设备(network device)三种。
字符设备是指存取时没有缓存的设备。
块设备的读写都有缓存来支持,并且块设备必须能够随机存取(random access),字符设备则没有这个要求。
典型的字符设备包括鼠标,键盘,串行口等。
块设备主要包括硬盘软盘设备,CD-ROM等。
一个文件系统要安装进入操作系统必须在块设备上。
网络设备在Linux里做专门的处理。
Linux的网络系统主要是基于BSD unix的socket机制。
在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递。
系统里支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。
1.2编写驱动程序的一些基本概念无论是什么操作系统的驱动程序,都有一些通用的概念。
操作系统提供给驱动程序的支持也大致相同。
下面简单介绍一下网络设备驱动程序的一些基本要求。
1.2.1发送和接收这是一个网络设备最基本的功能。
一块网卡所做的无非就是收发工作。
所以驱动程序里要告诉系统你的发送函数在哪里,系统在有数据要发送时就会调用你的发送程序。
还有驱动程序由于是直接操纵硬件的,所以网络硬件有数据收到最先能得到这个数据的也就是驱动程序,它负责把这些原始数据进行必要的处理然后送给系统。
这里,操作系统必须要提供两个机制,一个是找到驱动程序的发送函数,一个是驱动程序把收到的数据送给系统。
1.2.2中断中断在现代计算机结构中有重要的地位。
UT4412BV03开发板学习linux设备驱动模型(一)
UT4412BV03开发板学习linux设备驱动模型(一)设备驱动模型概述:设备驱动模型比较复杂,linux系统将设备和驱动归结到设备驱动模型中来管理,设备驱动模型的提出解决了以前编写驱动时没有统一的方法的局面,设备驱动模型给各种驱动程序提供了很多辅助性的函数,这些函数经过严格测试,可以很大程度上提高驱动开发人员的工作效率。
设备驱动模型中用到的几个核心的数据结构,分别是kobjeck,kset,subsystem,这些结构体使设备驱动模型组成了一个层次结构,该层次结构将驱动,设备,总线等联系起来,形成了一个完整的设备驱动。
kobject结构体提供了一个最基本的设备对象管理能力,每一个在内核中注册的kobject对象都对应于sysfs文件中的一个目录。
对应头文件:#include<linux/kobject.h>对应源文件:kobjeck.c1.kobject结构体struct kobject {const char *name; //kobject结构体的名字,作为一个目录显示在sysfs文件系统中struct list_head entry; //链接下一个kobject结构体struct kobject *parent; //指向本结构体的指针struct kset *kset; //指向kset结构体的指针struct kobj_type *ktype; //指向kobj_type结构体的指针,设备属性结构体struct sysfs_dirent *sd; //struct kref kref; //表示该对象的引用计数,内核提供增加和减少引用计数的kobject_get();kobject_put();当计数为0时,该对象的所有资源被释放unsigned int state_initialized:1; //表示kobject结构体是否初始化过,1表示初始化过,0表示未初始化过。
Camera驱动在Linux内核的移植解读
题_Camera驱动在Linux内核的移植Camera驱动在Linux内核的移植Linux 3.0.8 内核的配置系统由以下3 个部分组成:> Makefile:分布在Linux 内核源代码中的Makefile,定义Linux 内核的编译规则> 配置文件Kconfig:给用户提供配置选择的功能> 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供字符界面和图形界面)。
这些配置工具都是使用脚本语言编写的,如Tcl/TK、perl 等。
在Linux 内核中增加程序需要完成以下 3 项工作:> 1. 将编写的源代码复制到Linux 内核源代码的相应目录> 2. 在目录的Kconfig 文件中增加新源代码对应项目的编译配置选项> 3. 在目录的Makefile 文件中增加对新源代码的编译条目1. 实例引导:S3C2440 处理器的RTC 与LED 驱动配置。
首先,在Linux/drivers/char 目录中包含了S3C2410 处理器的RTC 设备驱动源代码s3c2410-rtc.c。
而在该目录的Kconfig 文件中包含S3C2410_RTC 的配置项目:config S3C2410_RTCbool "S3C2410 RTC Driver"depends on ARCH_S3C2410helpRTC (Realtime Clock)driver for the clock inbuilt into the Samsung S3C2410. This can provide periodic interrupt rates from 1Hz to 64Hz for user programs, and wakeup from Alarm.上述Kconfig 文件的这段脚本意味着只有在ARCH_S3C2410 项目被配置的情况下,才会出现S3C2410_RTC 配置项目,这个配置项目为布尔型(要么编译入内核,要么不编译,选择"Y" 或"N" ),菜单撒很难过显示的字符串为"S3C2410 RTC Driver","help" 后面的内容为帮助信息。
linux设备模型深探
if (error) {
//v如果创建失败。减少相关的引用计数
kobj_kset_leave(kobj);
kobject_put(parent);
kobj->parent = NULL;
/* be noisy on error issues */
if (error == -EEXIST)
};
void obj_test_release(struct kobject *kobject)
{
printk("eric_test: release .\n");
}
ssize_t eric_test_show(struct kobject *kobject, struct attribute *attr,char *buf)
}
上面的流程主要分为两部份。一部份是kobject的初始化。在这一部份,它将kobject与给定的ktype关联起来。初始化kobject中的各项结构。另一部份是kobject的名称设置。空间层次关系的设置,具体表现在sysfs文件系统中.
对于第一部份,代码比较简单,这里不再赘述。跟踪第二部份,也就是kobject_add_varg()的实现.
{
printk("have show.\n");
printk("attrname:%s.\n", attr->name);
sprintf(buf,"%s\n",attr->name);
return strlen(attr->name)+2;
}
ssize_t eric_test_store(struct kobject *kobject,struct attribute *attr,const char *buf, size_t count)
Linux下安装摄像头驱动详解
Linux下安装摄像头驱动详解439小游戏/在windows下安装摄像头驱动相当简单,通常主程序直接setup就OK,在linux下安装摄像头驱动就不那么容易了。
我们都知道每个linux版本官方都有相应的驱动程序提供下载,linux下安装摄像头驱动的方法如下:1、摄像头(Webcam)驱动说明;摄像头在Windows的驱动极为容易,最多是点几下鼠标,没有什么太大的难度。
但在Linux 中,驱动起来是有点困难,这并不是说Linux多高雅。
只能说开发商唯利是图,没有好处的事,他们的确不怎么积极。
Linux 的用户比较少,所以他们也不把用户当回事。
目前看来摄像头(Webcam)在 Linux 中驱动基本成熟,缺少的是应用程序的支持,比如即时通讯工具支持视频的好程序比较少。
有些芯片组是没有任何问题,在国内,大多摄像头的芯片组是Z-Star,也有显示为Vimmicro(和Z-Star是同样的芯片)的。
在Fedora 5.0或SuSE 10.x中,已经支持了很多摄像头,应该说即插即用。
对于我们来说,是不是即插即用,那是另一回事,只有幸运儿才有这个的福气。
如果您的摄像头接上还是用不了,那您就有必要看一下我写的这个文档了。
本文操作环境: Fedora Core 5.0 。
由于大部份是用源码包编译,所以还是有通用性的;1.1 摄像头在Linux中是如何支持的;在 Linux中,硬件的驱动程序,都是由内核支持的;目前比较新内核版本也集成了一些的摄像头驱动。
就是Fedora、SuSE最新版本所支持的内核也是来自由 。
所以支持也是极为正常的。
内核对硬件的支持分为内置于和外挂模块两种方便。
对于摄像头来说,大多是模块支持的;1.2 摄像头(Webcam)驱动网址;替换mxhaard.free.fr目前最新版本的摄像头驱动,已经到了 spca5xx-20060501.tar.gz 版本;您可以在上面的地址下载;2、驱动摄像头详细过程;2.1 查看摄像头型号;我们用用到 lshal 工具,在老版本的Linux是没有这个工具的。
Linux设备驱动模型介绍
文库资料 ©2017 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.第1章 Linux 设备驱动模型介绍设备驱动模型,对系统的所有设备和驱动进行了抽象,形成了复杂的设备树型结构,采用面向对象的方法,抽象出了device 设备、driver 驱动、bus 总线和class 类等概念,所有已经注册的设备和驱动都挂在总线上,总线来完成设备和驱动之间的匹配。
总线、设备、驱动以及类之间的关系错综复杂,在Linux 内核中通过kobject 、kset 和subsys 来进行管理,驱动编写可以忽略这些管理机制的具体实现。
设备驱动模型的内部结构还在不停的发生改变,如device 、driver 、bus 等数据结构在不同版本都有差异,但是基于设备驱动模型编程的结构基本还是统一的。
Linux 设备驱动模型是Linux 驱动编程的高级内容,这一节只对device 、driver 等这些基本概念作介绍,便于阅读和理解内核中的代码。
实际上,具体驱动也不会孤立的使用这些概念,这些概念都融合在更高层的驱动子系统中。
对于大多数读者可以忽略这一节内容。
1.1.1 设备在Linux 设备驱动模型中,底层用device 结构来描述所管理的设备。
device 结构在文件<linux/device.h>中定义,如程序清单1.1所示。
程序清单1.1 device 数据结构定义struct device {struct device *parent; /* 父设备*/ struct device_private *p; /* 设备的私有数据 */ struct kobjectkobj; /* 设备的kobject 对象 */ const char *init_name; /*设备的初始名字 */ struct device_type *type;/* 设备类型*/ struct mutex mutex; /*同步驱动的互斥信号量 */ struct bus_type *bus; /*设备所在的总线类型 */ struct device_driver *driver; /*管理该设备的驱动程序*/ void*platform_data;/*平台相关的数据 */ struct dev_pm_infopower;/* 电源管理*/#ifdef CONFIG_NUMA int numa_node; /*设备接近的非一致性存储结构*/ #endifu64 *dma_mask; /* DMA 掩码*/ u64 coherent_dma_mask; /*设备一致性的DMA 掩码*/struct device_dma_parameters *dma_parms; /* DMA 参数*/ struct list_headdma_pools; /* DMA 缓冲池*/ struct dma_coherent_mem*dma_mem; /* DMA 一致性内存 */ /*体系结构相关的附加项*/ struct dev_archdata archdata;/* 体系结构相关的数据*/ #ifdef CONFIG_OFstruct device_node*of_node;文库资料 ©2017 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.注册和注销device 的函数分别是device_register()和device_unregister(),函数原型如下:int __must_check device_register(struct device *dev); void device_unregister(struct device *dev);大多数不会在驱动中单独使用device 结构,而是将device 结构嵌入到更高层的描述结构中。
linux内核驱动模型和实现原理
linux内核驱动模型和实现原理Linux内核驱动模型和实现原理:Linux内核是一个模块化的系统,它允许用户通过加载和卸载模块来扩展系统功能。
内核驱动程序是一种特殊类型的模块,它负责与硬件设备进行交互,控制设备的操作,并将设备的功能暴露给用户空间。
在Linux内核中,驱动程序的实现原理和模型是非常重要的。
首先,让我们来了解Linux内核驱动的模型。
Linux内核驱动模型主要由字符设备驱动、块设备驱动和网络设备驱动组成。
每种驱动类型都有自己的特点和工作方式。
字符设备驱动主要用于与字符设备进行交互,如终端设备、串口设备等。
字符设备驱动通常使用文件系统接口,通过文件描述符来访问设备,提供读写操作。
块设备驱动主要用于与块设备进行交互,如硬盘、闪存等。
块设备驱动负责管理设备的数据块,提供块设备的读写操作,支持文件系统的操作。
网络设备驱动主要用于与网络设备进行交互,如网卡、无线网卡等。
网络设备驱动负责管理网络设备的数据传输,实现网络协议栈的功能。
在Linux内核中,每种驱动类型都有对应的数据结构和函数接口,驱动程序通过这些接口与设备进行交互。
驱动程序的核心功能包括设备的注册、初始化、数据传输和中断处理等。
驱动程序的实现原理主要涉及以下几个方面:1.设备的注册和初始化:驱动程序在加载时需要将设备注册到内核中,以便内核能够识别设备并分配资源。
设备的初始化包括对设备的配置、内存的映射、中断的注册等操作。
2.数据传输和操作:驱动程序通过设备的接口进行数据的读写操作,如字符设备驱动可以使用read和write函数来进行数据传输,块设备驱动可以使用request和transfer函数来进行块的读写操作。
3.中断处理:设备通常会触发中断,驱动程序需要注册中断处理函数来处理设备的中断事件。
中断处理函数通常包括中断的处理、数据的传输、设备的复位等操作。
4.设备的管理和资源的释放:驱动程序需要负责设备的管理和资源的释放,包括设备的打开和关闭、内存的释放、中断的注销等操作。
linux驱动基础知识讲解精品课件
分配和释放字符设备号
1. 动态分配设备编号(主要是主设备号) • int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name) • dev 是一个仅用于输出的参数, 它在函数成功完成时保 存已分配范围的第一个编号。 • baseminor 应当是请求的第一个要用的次设备号,它常 常是 0. • count 和 name 参数跟request_chrdev_region 的一样 .
• 中断屏蔽很少被单独使用,原子操作只能针对整数 来进行。因此自旋锁和信号量应用最为广泛。
27
加锁机制
1. 锁机制可以避免竞争状态正如门锁和门一样,门后的房 间可想象成一个临界区。
2. 在一段时间内,房间里只能有一个内核任务存在,当一 个任务进入房间后,它会锁住身后的房门;当它结束对 共享数据的操作后,就会走出房间,打开门锁。如果另 一个任务在房门上锁时来了,那么它就必须等待房间内的 任务出来并打开门锁后,才能进入房间。
(1) 计时器模块 通过复位硬件寄存器来复位计时。
(2) 串口模块 LK采用串口模块来配置它的输入/输出系统,在这个模块初始化 后,我们可以使用LK提供的“printf(…)”等函数来使用串口功能。
(3) I2C模块 (4) PWM模块 (5) PMIC模块 (6) RTC模块 和计时器模块一样,在U-Boot中,I2C/PMIC/RTC重新复位寄存器来 复位这些模块。
(7) LED模块 通过这power off charging个模块,设备能够通知用户当前的充电状态。
(8) 充电模块 这个模块负责关机充电(power off charging)、低电压充电(lower charging in the system)。
关于设备模型、设备与驱动关联的过程分析-linux设备驱动
关于设备模型、设备与驱动关联的过程分析-linux设备驱动关于设备模型、设备与驱动关联的全过程分析本文的大多数内容参考了:对于网络上设备与驱动关联的全过程分析(I2C方式)一文。
在此特别感谢这位作者前辈的无私奉献。
本人只是添加了一些个人理解和补充。
在Linux操作系统中,驱动程序的加载分为两种:内核启动时自动加载和用户手动加载;硬件设备也可以采用两种方式添加到系统中:在系统启动前及系统运行时的热插拨。
下面,我们以arm体系结构下的at91处理器中的I2C控制器为例,介绍一下硬件设备及相关的驱动程序是如何绑定及松绑的。
1. 平台驱动注册过程具体的目录如下:关于设备模型、设备与驱动关联的全过程分析。
1.1 at91_i2c_init()函数1.2 platform_driver_register()函数1.3 driver_register()函数1.4 bus_add_driver()函数1.5 dd.c文件driver_attach()函数1.1 at91_i2c_init()函数在文件drivers/i2c/busses/i2c-at91.c中,定义了结构体struct platform_driver并进行了初始化,通过使用module_init()宏进行声明,当模块被加载到内核时会调用 at91_i2c_init()函数。
在此函数中,调用了platform_driver_register()函数来完成注册。
static struct platform_driver at91_i2c_driver = {.probe= at91_i2c_probe,.remove = __devexit_p(at91_i2c_remove),.suspend= at91_i2c_suspend,.resume= at91_i2c_resume,.driver= {.name= "at91_i2c",.owner= THIS_MODULE,},};static int __init at91_i2c_init(void){return platform_driver_register(&at91_i2c_driver);}1.2 platform_driver_register()函数在文件drivers/base/platform.c中,实现并导出了platform_driver_register()函数,以便使其他模块中的函数可以调用此函数。
【IT专家】linux设备驱动模型
本文由我司收集整编,推荐下载,如有疑问,请与我司联系linux设备驱动模型2012/06/05 0 最早在去年的时候学习MMC/SD/SDIO的时候就接触过设备驱动模型,但是当时也整天看书也是迷迷糊糊的,因此最终也没有将这部分知识很好的整理一下。
现在再次接触到这部分知识。
也算是完成一直以来的一个想法。
把这部分知识简单的整理一下备忘。
设备驱动模型最初是为了解决设备的电源管理而产生的,但是最后发展起来之后,作用就越来越大了,特别适合设备管理。
对于linux设备驱动工程师来说,掌握设备驱动模型非常重要。
linux的设备驱动模型的底层机制主要包括:kobject,kobj_type,kset等几个结构。
这几个结构定义在include/linux/kobject.h中。
kobject代表设备驱动模型中一个基本对象。
每个kobject都对应于sysfs中的一个目录。
上层结构例如device,device_driver,bus_type都嵌入了一个kobject,这相当于面向对象程序设计机制中的继承机制。
kobject的定义如下: 60 struct kobject { 61 const char *name;/*名称*/ 62 struct list_head entry;/*用于链入所属的kset的链表*/ 63 struct kobject *parent;/*父object*/ 64 struct kset *kset;/*所属kset*/ 65 struct kobj_type *ktype;/*所属ktype*/ 66 struct sysfs_dirent *sd;/*sysfs中的目录项*/ 67 struct kref kref;/*生命周期(引用计数)管理*/ 68 unsigned int state_initialized:1;/*标记:初始化*/ 69 unsigned int state_in_sysfs:1;/*标记:在sysfs 中*/ 70 unsigned int state_add_uevent_sent:1;/*标记:已发出KOBJ_ADD uevent*/ 71 unsigned int state_remove_uevent_sent:1;/*标记:已发出的KOBJ_REMOVE uevent*/ 72 unsigned int uevent_suppress:1;/*标记:禁止发出uevent*/ 73 };kobject的基本操作: 76 int kobject_set_name(struct kobject *kobj, const char *name, ...); 77 extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, 78 va_list vargs); 79 80 static inline const char *kobject_name(const struct kobject *kobj) 81 { 82 return kobj- name; 83 } 84 85 extern void kobject_init(struct kobject *kobj, struct kobj_type *ktype);。
camera驱动具体分析(基于S5PV210)
一、Camera工作原理介绍1.结构一般来说,camera主要是由lens和sensor IC两部分组成,其中有的sensor IC集成了DSP,有的没有集成,但也需要外部DSP处理。
细分的来讲,camera设备由下边几部分构成:1)lens(镜头)一般camera的镜头结构是有几片透镜组成,分有塑胶透镜(Plastic)和玻璃透镜(Glass) ,通常镜头结构有:1P,2P,1G1P,1G3P,2G2P,4G等。
2)sensor(图像传感器)Senor是一种半导体芯片,有两种类型:CCD和CMOS。
Sensor将从lens 上传导过来的光线转换为电信号,再通过内部的AD转换为数字信号。
由于Sensor的每个pixel只能感光R光或者B光或者G光,因此每个像素此时存贮的是单色的,我们称之为RAW DATA数据。
要想将每个像素的RAW DATA数据还原成三基色,就需要ISP来处理。
3)ISP(图像信号处理)主要完成数字图像的处理工作,把sensor采集到的原始数据转换为显示支持的格式。
4)CAMIF(camera控制器)芯片上的camera接口电路,对设备进行控制,接收sensor采集的数据交给CPU,并送入LCD进行显示。
2.工作原理外部光线穿过lens后,经过color filter滤波后照射到Sensor面上,Sensor将从lens上传导过来的光线转换为电信号,再通过内部的AD转换为数字信号。
如果Sensor 没有集成DSP,则通过DVP的方式传输到baseband,此时的数据格式是RAW DATA。
如果集成了DSP,则RAW DATA 数据经过AWB、color matrix、lens shading、gamma、sharpness、AE和de-noise处理,后输出YUV或者RGB格式的数据。
最后会由CPU送到framebuffer中进行显示,这样我们就看到camera拍摄到的景象了。
linux设备模型详解
linux设备模型详解1.背景随着设备拓扑结构越来越复杂,需要为内核建立一个统一的设备模型,对系统结构做一般性的抽象描述。
有了该抽象结构,可支持多种不同的任务:-电源管理完成电源管理工作需要对系统结构的理解,且有严格的顺序,如:一个USB宿主适配器,在处理完所有与其相连接的设备面前是不能关闭的;-与用户空间通信由/sysfs虚拟文件系统展示设备的属性-热插拔设备-对象生命周期2.sysfs 虚拟文件系统sysfs 是一个特殊的文件系统,类似于/proc。
sysfs不仅象/proc一样允许用户空间访问内核的数据,而且它以更结构化的方式向用户提供内核数据信息。
sysfs的一个目的就是展示设备驱动模型中各组件的层次关系。
其顶级目录包括:-block-device-bus-drivers-class-power-firmware每个目录代表一个kobject对象,每个文件代表kobject的属性。
3.Kobject、Kset 和 subsystemKobjectKobject 是组成设备模型的基本结构。
类似于C++中的基类,它嵌入于更大的对象的对象中--所谓的容器--用来描述设备模型的组件。
如bus, devices, drivers 都是典型的容器。
容器有了kobject之后,允许内核:⏹保存对容器的引用计数⏹保存容器之间的层次关系⏹为每个容器的属性提供一个用户视图struct kobject{char * k_name;char name[20];struct k_ref kref;struct list_head entry;struct kobject * parent;struct kset * kset;struct ktype * ktype;struct dentry * dentry;};struct kobj_type{void (*release) (struct kobject *);struct sysfs_ops *sysfs_ops;struct attribute **default_attrs;};Kset一个kset是嵌入相同类型结构的kobject集合。
Camera驱动在Linux内核的移植解读
题_Camera驱动在Linux内核的移植Camera驱动在Linux内核的移植Linux 3.0.8 内核的配置系统由以下3 个部分组成:> Makefile:分布在Linux 内核源代码中的Makefile,定义Linux 内核的编译规则> 配置文件Kconfig:给用户提供配置选择的功能> 配置工具:包括配置命令解释器(对配置脚本中使用的配置命令进行解释)和配置用户界面(提供字符界面和图形界面)。
这些配置工具都是使用脚本语言编写的,如Tcl/TK、perl 等。
在Linux 内核中增加程序需要完成以下 3 项工作:> 1. 将编写的源代码复制到Linux 内核源代码的相应目录> 2. 在目录的Kconfig 文件中增加新源代码对应项目的编译配置选项> 3. 在目录的Makefile 文件中增加对新源代码的编译条目1. 实例引导:S3C2440 处理器的RTC 与LED 驱动配置。
首先,在Linux/drivers/char 目录中包含了S3C2410 处理器的RTC 设备驱动源代码s3c2410-rtc.c。
而在该目录的Kconfig 文件中包含S3C2410_RTC 的配置项目:config S3C2410_RTCbool "S3C2410 RTC Driver"depends on ARCH_S3C2410helpRTC (Realtime Clock)driver for the clock inbuilt into the Samsung S3C2410. This can provide periodic interrupt rates from 1Hz to 64Hz for user programs, and wakeup from Alarm.上述Kconfig 文件的这段脚本意味着只有在ARCH_S3C2410 项目被配置的情况下,才会出现S3C2410_RTC 配置项目,这个配置项目为布尔型(要么编译入内核,要么不编译,选择"Y" 或"N" ),菜单撒很难过显示的字符串为"S3C2410 RTC Driver","help" 后面的内容为帮助信息。
对 Linux 设备驱动模型的一些理解
对Linux设备驱动模型的一些理解作者:张俊岭EMAIL: sprite_zjl@; jlzhang@QQ: 251450387日期:2009-9-15说明:对于Linux设备驱动工程师来说,掌握设备驱动模型非常重要。
本文档基于2.6.30 内核,记录了一些我对Linux设备驱动模型的一些总结和理解,可能有错误和不当之处,欢迎交流和指正。
1 底层机制Linux的设备驱动模型的底层机制主要包括:kobject,kobj_type,kset等几个结构。
这几个结构的定义在include/linux/kobject.h中。
1.1 kobjectkobject代表设备驱动模型中一个基本对象,类似于MFC中最顶层的基类CObject。
每个kobject都对应于sysfs中的一个目录。
上层结构例如device,device_driver,bus_type都嵌入了一个kobject,这相当于面向对象程序设计语言中的继承机制。
kobject的定义如下:struct kobject {char *name; /* 名称 */constlist_head entry; /* 用于链入所属kset的链表 */struct*parent; /* 父kobject */structkobjectkset *kset; /* 所属kset */structkobj_type *ktype; /* 所属ktype */struct*sd; /* sysfs中的目录项 */structsysfs_direntkref kref; /* 生命周期(引用计数)管理 */structstate_initialized:1;/* 标记:初始化 */intunsignedintstate_in_sysfs:1; /* 标记:在sysfs中 */unsignedstate_add_uevent_sent:1; /* 标记:已发出KOBJ_ADD uevent */intunsignedstate_remove_uevent_sent:1; /* 标记:已发出KOBJ_REMOVE uevent */ unsignedintuevent_suppress:1; /* 标记:禁止发出uevent */intunsigned};kobject的基本操作:/* 设置名称 */int kobject_set_name(struct kobject *kobj, const char *name, ...)/* 初始化 */void kobject_init(struct kobject *kobj, struct kobj_type *ktype);/* 添加 */int kobject_add(struct kobject *kobj,struct kobject *parent, const char *fmt, ...);/* 初始化 & 添加 */int kobject_init_and_add(struct kobject *kobj,struct kobj_type *ktype,struct kobject *parent,const char *fmt, ...);/* 删除 */void kobject_del(struct kobject *kobj);/* 引用计数加1 */struct kobject *kobject_get(struct kobject *kobj);/* 引用计数减1 */void kobject_put(struct kobject *kobj);/* 获得sysfs路径 */char *kobject_get_path(struct kobject *kobj, gfp_t flag);1.2 kobj_typekobj_type是kobject所属的类型,定义了某种类型的kobejct的公共的属性和操作。
Camera模块解析
Camera模块解析手机摄像头功能由多个功能模块组成,主要三个部分,采集,加工,显示。
(1)采集部分由感光的sensor完成,通过CAM IF接口与手机芯片内的CAM连接。
(2)CAM对CAM IF数据进行加工,主要是格式转换,特殊效果等。
最终处理出来的一帧数据,存在内存中。
(3)手机的刷新线程,使用手机内部的DMA功能,或者OVERLAY技术,把处理好的camera图像,显示到LCD上。
刷新部分,不在camera框架范围内,后面只做简单讨论。
图1:Camera典型硬件模块图2 Sensor简介Sensor是对图像的采集系统,通常采用的是ov系列的芯片。
如ov2655等。
通常包含两路接口:(1)控制总线:Sensor也是一个智能嵌入式系统,一般通过I2C 总线与手机芯片通信。
手机可以通过I2C读写Sensor的寄存器,改变Sensor的参数,从而改变其工作方式。
(2)数据总线:Sensor通过CAM IF接口与CAM联系。
图2:sensor硬件连接图由图可知,sensor工作的条件需要:(1)电压供应,一般模拟电压,数字电压。
(2)工作时钟,通常为24M HZ的正弦波。
一般为手机芯片产生(3)SDA,SCL,i2c总线连接,sensor通常为从设备。
(4)standby控制线,手机芯片通过这条GPIO控制线,控制sensor的工作是否开启。
(5)Sensor输出给手机芯片的接口,CAM IF接口:(6)并行数据线,通常8位,10位。
分辨率高的sensor数据线需要更多。
(7)提供给手机芯片内集成的camera模块的PCLK,HCLK,VCLK.(像素同步信号,行同步信号,帧同步信号)。
Sensor通常产出稳定频率的数据图像流,手机芯片可以通过I2C 总线接口,修改寄存器,改变帧频率。
也可以改变sensor的输出流的格式,通常采用yuv422格式。
3 CAM简介CAM就是将Sensor采集过来的数据,转换相应格式,及其他加工,最后存放到内存中。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
struct kobject client->dev.kobj +.name = "0-003c", +.kset = devices_kset, +.ktype = device_ktype, +.parent = i2c->adap.dev.kobj
在 Sys 下形成以下树状结构:
sys
devices
//发送 UEVENT 事件 kobject_uevent(&dev->kobj, KOBJ_ADD); //配对 然后启动 Probe 事件,然后加入到设备驱动链表 bus_probe_device(dev); //加入到父 kobj 链表 if (parent) klist_add_tail(&dev->p->knode_parent, &parent->p->klist_children); put_device(dev); return error; }
Camera 驱动的初始化---以 OV5640 为例
OV5640 初始化的大致流程如下: 现 在 来 具 体 分 析 一 下 OV5640 的 初 始 化 过 程 :
ov5640的初 始 化 过 程
69 : m odule_init() 70 : v4l2_i2c_drv_init() 71 : i2c_add_driver() 72 : i2c_register_driver() 73 : driver_register() 74 : bus_add_driver()
struct i2c_adapter i2c->adap +.nr = 0, +.class = I2C_CLASS_HWMON, +.algo = &aml_i2c_algorithm, +.retries = 2, +.timeout = 5, +.name = aml_i2c_adap0, +.dev->p.driver_data = i2c, +.bus_lock = rt_mutex_init(&adap->bus_lock), +.userspace_clients = INIT_LIST_HEAD(&adap->userspace_clients),
struct device cli来自nt->dev +.platform_data = video_ov5640_data, +.archdata = *aml_i2c_bus_info->archdata, +.addr = aml_i2c_bus_info->addr = (0x78 >> 1), +.irq = aml_i2c_bus_info->irq, +.parent = i2c->adap.dev, +.bus = &i2c_bus_type, +.type = & i2c_client_type,
kobject i2c->adap.dev.kobj +.name = i2c-0, +.kset = devices_kset, +.ktype = device_ktype, +.parent = &(devices_kset.kobj);
struct device_private adap.dev.p +.dev = i2c->adap.dev, +.driver_data = i2c,
i2c_scan_static_board_info(adap); … //适配驱动,启动 probe dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); … return 0; } int device_register(struct device *dev) { device_initialize(dev); return device_add(dev); } 与 adap 关联的设备注册到 i2c_bus_type 上去
19 : list_add_tail()
2: __i2c_board_list 链表被读取到 i2C_BUS_TYPE
从 system.map 中可以看出与 Camera 相关的模块如下: c003288c t __initcall_i2c_init2 … c00328b8 t __initcall_aml_i2c_init3 … c0032c18 t __initcall_i2c_dev_init6 … c0032c28 t __initcall_videodev_init6 c0032c30 t __initcall_v4l2_i2c_drv_init6 c0032c34 t __initcall_v4l2_i2c_drv_init6
bus
i2c-0
i2c
0-003c
uevent
power
new_devices
name
delete_devices
devices
power
modalias
uevent
name
subsystem
0-003c
device_add 是一个非常关键的函数,它把一个设备连接到总线树,并且创建了 sys 下面给 中目录与文件,现在来简单分析 device_add int device_add(struct device *dev) { /* we require the name to be set before, and pass NULL */ //1, kobj_kset_join(kobj); kobj 将会链入 devices_kset //2,kobj 在父 kobj 下面创建相应目录 error = kobject_add(&dev->kobj, dev->kobj.parent, NULL); //创建了文件 uevent_attr error = device_create_file(dev, &uevent_attr); //创建特性 error = device_add_attrs(dev); //klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices); //把 dev 加到总线下的 klist_devices 列表 error = bus_add_device(dev); if (error) goto BusError; error = dpm_sysfs_add(dev); //把设备加入到 list_add_tail(&dev->power.entry, &dpm_list); 电源管理列表 device_pm_add(dev); /* Notify clients of device addition. This call must come * after dpm_sysf_add() and before kobject_uevent(). */ //在总线上发出通知 if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_ADD_DEVICE, dev);
__i2c_board_list 读 取 到 I2C 总 线 树
23 : am l_i2c_probe() 24 : i2c_add_num bered_adapter() 26 : i2c_register_adapter()
27 : i2c_scan_static_board_info() 28 : i2c_new_device() 29 : device_register() 30 : device_add()
c0032d24 t __initcall_video_init6 c0032d28 t __initcall_video2_init6 主要分两部分 一部分与 I2C 相关,一部分与 Video 相关,一般一些宏定义在 autoconf.h 中 得到体现;一般设备的启动次序如下: 1, 先建立和注册总线—如 platform_bus_type, i2c_bus_type 2, 读取设备列表到总线中去,链成链表 3, 驱动模块启动,然后配对到相应的设备 调用 Probe 函数 完成初始化 对于热插拔的设备 1, 设备插入系统,系统调用相应的处理程序 sbin/ueventd 并发布 Net Sock 事件 2, 同时,设备根据总线匹配到相应的驱动 调用驱动的 Probe 函数 完成初始化; 1, __i2c_board_list 中都是一些 I2C 设备,这些设备在 aml-i2c 驱动 加载时 链接到相 应的 i2c 总线树上;具体的流程如下
aml_i2c_probe() 会填充数据 adap i2c_add_numberd_adapter()会把 adap 放到 i2c_adapter_idr 树中
现在重点分析 i2c_register_adapter:
static int i2c_register_adapter(struct i2c_adapter *adap) { … //注册 i2c-0 设备,创建对应的目录/sys/bus/i2c/devices/i2c-0 dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.bus = &i2c_bus_type; adap->dev.type = &i2c_adapter_type; res = device_register(&adap->dev); … //加载 i2c 设备列表