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 ...
随机推荐
- Java如何检查端口是否被使用?
在Java编程中,如何扫描打开的端口(是否被使用)? 以下示例显示如何通过创建 Socket 对象来检查主机上打开或正在使用的端口(相当于一个简单的端口扫描器). package com.yiibai ...
- 父页面操作嵌套iframe子页面的HTML标签元素
一个页面A.html使用iframe嵌套一个页面B.html,在A页面写js操作B页面HTML元素,首先要获取到B页面document对象,才能对嵌套页面进行操作 请看一个实例,在A页面写js操作B页 ...
- 【代码审计】XYHCMS V3.5任意文件读取漏洞分析
0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...
- luanet更名为distri.lua
为了更好的体现luanet的设计意图和避免与网上另一个开源项目重名造成混淆, luanet正式更名为distri.lua.后需开发工作包括跨平台,日志,通过Fork创建新线程正在开发中. 新地址:ht ...
- Automatic Summarization of Bug Reports
CONTENT: example : KDE bug report: https://bugs.kde.org/show_bug.cgi?id=188311 (其中还有很多comments没显示) ...
- css - Grid网格布局
.wrapper{ display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 1 ...
- C#实现二叉树--二叉链表结构
二叉树的简单介绍 关于二叉树的介绍请看这里 : 二叉树的简单介绍 http://www.cnblogs.com/JiYF/p/7048785.html 二叉链表存储结构: 二叉树的链式存储结构是指,用 ...
- mysql格式化小数保留小数点后两位(小数点格式化)
格式化浮点数的问题,用format(col,2)保留两位小数点,出现一个问题,例如下面的语句,后面我们给出解决方法 SELECT FORMAT(12562.6655,2); 结果:12,562.67 ...
- centos 7 删除yum安装的openjdk
# java -version # rpm -qa | grep java rpm -e --nodeps (rpm -qa的结果们) # java -version
- Python不支持函数重载
函数重载与Python: 函数重载的好处就是不用为了不同的参数类型或参数个数,而写多个函数.多个函数用同一个名字,但参数表,即参数的个数和数据类型可以不同.调用的时候,虽然方法名字相同,但根据参数表可 ...