I2C驱动框架(kernel-2.6.22.6)
以用i2c通信的实时时钟为例
框架入口源文件:i2c_m41t11.c
(可根据入口源文件,再按着框架到内核走一遍)
内核版本:linux_2.6.22.6 硬件平台:JZ2440
以下是驱动框架:

以下是驱动代码 i2c_m41t11.c :
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/fs.h> static unsigned short normal_i2c[] = {0x68,I2C_CLIENT_END}; //只有七位 0xd0 >> 1
static unsigned short probe[] = {I2C_CLIENT_END};
static unsigned short ignore[] = {I2C_CLIENT_END}; //定义一个 client 地址数据
static struct i2c_client_address_data addr_data =
{
.normal_i2c = normal_i2c,
.probe = probe,
.ignore = ignore,
}; //定义 client
static struct i2c_client *i2c_m41t11_client; //定义 主设备号
static int major; //定义一个 i2c 字符驱动
static struct i2c_driver i2c_m41t11_driver; static ssize_t i2c_m41t11_read(struct file *file, char __user *buf, size_t size, loff_t * offset)
{
printk(" <========= this is m41t11 RTC chip =========> \n");
return ;
} static ssize_t i2c_m41t11_write(struct file *file, const char __user *buf, size_t size, loff_t * offset)
{
printk(" <========== this is m41t11 RTC chip =========> \n");
return ;
} //定义字符操作函数
static struct file_operations i2c_m41t11_fops =
{
.owner = THIS_MODULE,
.read = i2c_m41t11_read,
.write = i2c_m41t11_write,
}; //定义一个字符设备类
static struct class *i2c_m41t11_class; //匹配处理函数
static int m41t11_match_fun(struct i2c_adapter* adpater,int addr ,int kind)
{
printk("match m41t11 RTC chip successfully \n");
//初始化 client 结构体
i2c_m41t11_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
i2c_m41t11_client->adapter = adpater;
i2c_m41t11_client->driver = &i2c_m41t11_driver;
i2c_m41t11_client->addr = addr;
strcpy(i2c_m41t11_client->name, "i2c_m41t11_client");
i2c_attach_client(i2c_m41t11_client); //注册字符设备
major = register_chrdev(,"i2c_m41t11", &i2c_m41t11_fops); i2c_m41t11_class = class_create(THIS_MODULE,"i2c_m41t11_class"); // /sys/class/i2c_m41t11_class
class_device_create(i2c_m41t11_class, NULL, MKDEV(major, ), NULL,"i2c_m41t11_dev"); // /dev/i2c_m41t11_dev
return ;
} static int i2c_m41t11_attach(struct i2c_adapter *adapter)
{ printk("trying to match m41t11 RTC chip \n"); return i2c_probe( adapter , &addr_data , m41t11_match_fun );
} static int i2c_m41t11_detach(struct i2c_client *client)
{
printk("delect m41t11 RTC chip \n");
//字符设备
unregister_chrdev(major, "i2c_m41t11");
class_destroy(i2c_m41t11_class);
class_device_destroy(i2c_m41t11_class,MKDEV(major, )); //client
i2c_detach_client(client);
kfree(i2c_get_clientdata(client));
return ;
} //初始化 i2c_m41t11_driver
static struct i2c_driver i2c_m41t11_driver =
{
.driver = { .name = "i2c_m41t11", },
.attach_adapter = i2c_m41t11_attach,
.detach_client = i2c_m41t11_detach,
}; static int i2c_m41t11_init(void)
{
i2c_add_driver(&i2c_m41t11_driver);
return ;
} static void i2c_m41t11_exit(void)
{
i2c_del_driver(&i2c_m41t11_driver);
} module_init(i2c_m41t11_init);
module_exit(i2c_m41t11_exit); MODULE_LICENSE("GPL");
注:
匹配分为三个个步骤
1. 用驱动的i2c_driver.driver.name与物理设备名字匹配,成功则调用 i2c_driver.attach_adapter。
2. i2c_driver.attach_adapter中用i2c_probe(adapter,addr,match_func)匹配适配器与物理设备,成功则调用 match_func。
3. match_func中创建 i2c_client,将 i2c_driver 与 i2c_adapter 联系起来。
以下是编译驱动的Makefile:
KER_DIR=/work/systems/kernel/linux-2/linux-2.6.22.6
all:
make -C $(KER_DIR) M=`pwd` modules
clean:
make -C $(KER_DIR) M=`pwd` modules clean
rm -fr modules.order
obj-m += i2c_m41t11.o
I2C驱动框架(kernel-2.6.22.6)的更多相关文章
- I2C驱动框架 (kernel-3.4.2)
先用韦老师的图: 注: 新版本内核的i2c驱动框架采用了 i2c_client -------> i2c_bus_type <-------- i2c_driver 框架 如 ...
- I2C驱动框架(四)
参考:I2C子系统之platform_driver初始化——I2C_adap_s3c_init() 在完成platform_device的添加之后,i2c子系统将进行platform_driver的注 ...
- I2C驱动框架(三)
参考:I2C子系统之platform_device初始化——smdk2440_machine_init() I2C驱动框架还应用了另一种总线-设备-驱动模型,平台设备总线platform_bus_ty ...
- Linux 驱动框架---i2c驱动框架
i2c驱动在Linux通过一个周的学习后发现i2c总线的驱动框架还是和Linux整体的驱动框架是相同的,思想并不特殊比较复杂的内容如i2c核心的内容都是内核驱动框架实现完成的,今天我们暂时只分析驱动开 ...
- 【Linux高级驱动】I2C驱动框架分析
1.i2c-dev.c(i2c设备驱动组件层) 功能:1)给用户提供接口 i2c_dev_init //入口函数 /*申请主设备号*/ register_chrdev(I2C_MAJOR(), &q ...
- I2C驱动框架(二)
参考:I2C子系统之I2C bus初始化——I2C_init() 在linux内核启动的时候最先执行的和I2C子系统相关的函数应该是driver/i2c/i2c-core.c文件中的i2c_init( ...
- Linux I2C驱动框架
Linux的I2C体系结构分为3个组成部分: I2C核心( i2c-core.c ): I2C核心提供了I2C总线驱动和设备驱动的注册.注销方法.I2C通信方法("algorithm&qu ...
- I2C驱动框架(五)
参考:I2C子系统之 adapter driver注册——I2C_dev_init() i2c的操作在内核中是当做字符设备来操作的,相关初始化在由i2c_dev_init函数来初始化. static ...
- I2C驱动框架(一)
参考:I2C子系统之内核中I2C子系统的结构 结合vmlinux.lds和Makefile可确定i2c初始化函数的执行顺序如下: 1./dricer/i2c/i2c-core.c中的函数:i2c_in ...
随机推荐
- MAC OS查看端口占用情况及杀死进程
终端命令 sudo lsof -i :9000 COMMAND PID USER FD TYPE DEVICE ...
- 在Android Studio中查看Sqlite的方法
只说最好的方法,使用工具stetho:http://facebook.github.io/stetho/ 1.在Gragle中加上如下语句: dependencies { // Stetho core ...
- Python 函数 (关键字参数)
关键字参数 可变参数允许你传入0个或者任意个参数,这些可变参数在函数调用时会自动组装成一个tuple,而关键字参数允许你传入0个或者任意个含参数名的参数,这些参数在函数内部自动组装成为一个dict d ...
- [JS] Topic - this is ”closure“
Ref: 为什么要用闭包? 背景 闭包是自带运行环境的函数 发哥是自带背景音乐的男人~ 就是有权访问另一个函数作用域的变量的函数. 函数式编程的闭包,就是函数的调味包.方便用户调用函数.不必为了维护繁 ...
- [Android] Java Basic : preview
基础教学:lecture, video, lecturer: Matt Stoker Java教学:http://www.runoob.com/java/java-intro.html[菜鸟教程,非常 ...
- SpringBoot------个性化启动Banner设置
1.添加Banner.txt文件 . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ ...
- django通用视图(类方法)
这周是我入职的第一周,入职第一天看到嘉兴大佬的项目代码.视图中有类方法,我感到很困惑. 联想到之前北京融360的电话面试,问我有无写过类方法……看来有必要了解下视图的类方法,上网搜了很多,原来这就是所 ...
- Dom捕捉事件和冒泡事件-原理与demo测试
先参考一下百度百科对冒泡事件流的解释: ----------不喜欢读文字的同学,可以直接看下面demo,传递顺序简单明了! http://baike.baidu.com/link?url=kaeJHT ...
- io流和序列化
1.使用File操作文件 public class IoTest { public static void main(String[] args) throws IOException { /* 01 ...
- jenkins编辑报错Exception when publishing, exception message的解决办法
jenkins编辑报错Exception when publishing, exception message的解决办法 查看目标主机的磁盘空间是否占满,清理磁盘空间即可