如何为pcf8563增加alarm功能呢?驱动该怎么写呢?
时间:2010-07-15
来源:互联网
内核驱动里有实现rtc功能的pcf8563的驱动,但是没有实现alarm功能。
我想在用户空间通过一设备文件来控制pcf8563的alarm功能,驱动应该怎么写呢?
可以按照rtc里pcf8563的实现再创建一个pcf8563的i2c_client吗?
还是可以利用现有的i2c资源(rtc pcf8563已经插入内核),获取pcf8563这个i2c_client,然后在这个之上再扩展功能?
对驱动这块不是太了解,所以想听听大家的意见。
谢谢!
作者: jetking 发布时间: 2010-07-15
在rtc_pcf8563.c中,,,
static const struct rtc_class_ops pcf8563_rtc_ops = {
.read_time = pcf8563_rtc_read_time,
.set_time = pcf8563_rtc_set_time,
};现在只是定义了read_time和set_time,,
那要增加alarm功能怎么办?
先看看struct rtc_class_ops 是如何定义的
struct rtc_class_ops {
int (*open)(struct device *);
void (*release)(struct device *);
int (*ioctl)(struct device *, unsigned int, unsigned long);
int (*read_time)(struct device *, struct rtc_time *);
int (*set_time)(struct device *, struct rtc_time *);
int (*read_alarm)(struct device *, struct rtc_wkalrm *);
int (*set_alarm)(struct device *, struct rtc_wkalrm *);
int (*proc)(struct device *, struct seq_file *);
int (*set_mmss)(struct device *, unsigned long secs);
int (*irq_set_state)(struct device *, int enabled);
int (*irq_set_freq)(struct device *, int freq);
int (*read_callback)(struct device *, int data);
};
其中的两个函数指针read_alarm和set_alarm就是用来实现alarm功能的,,LZ只需要添加这两个回调函数就可以了。。。
至于这两个函数是如何被调用到的,,这就涉及到字符驱动的东西了,,在 drivers/rtc/rtc-dev.c中的一个函数rtc_dev_ioctl()
这个函数就是设备的ioctl接口了,在这个函数中可以配置RTC的所有功能,,,,LZ可以跟踪一下流程,还是很简单的。
作者: wmmy2008 发布时间: 2010-07-15
这个做法是重新实现pcf8563的rtc驱动。
我把pcf8563编译进内核了。所以现有的设备没有办法使用新的驱动。
后来找到一个办法:
在驱动里,通过 i2c_get_adapter得到adapter,然后通过list_for_each 每个adapter的client,比较每个client->driver->id来获取pcf8563的i2c client, id号见“include/linux/i2c-id.h”这样我就可以在我自己的驱动里实现timer和alarm功能。
作者: jetking 发布时间: 2010-07-16
如果是那样的话,LZ根本就不需要自己写模块驱动了。。只需要在userspace 直接open这个i2c设备,然后直接读写time, alarm设备地址即可,LZ可以看看
drivers/i2c/i2c-dev.c 文件定义的open ,read,write;不过这样用户用起来很不爽,所以要在pcf8563.c中定义read_time和set_time方法,这种接口用户读写时间会
很方便。
作者: wmmy2008 发布时间: 2010-07-16
回复 jetking
刚才还没注意,其实你这种做法是不行的。。。
首先你可以用 i2c_get_adapter找到设备对应的adapter ,,但是你是一定找不到i2c_client的,,
你看看i2c_client的定义:
struct i2c_client {
unsigned short flags; /* div., see below */
unsigned short addr; /* chip address - NOTE: 7bit */
/* addresses are stored in the */
/* _LOWER_ 7 bits */
char name[I2C_NAME_SIZE];
struct i2c_adapter *adapter; /* the adapter we sit on */
struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */
int irq; /* irq issued by device */
struct list_head list; /* DEPRECATED */
struct completion released;
};
所以就算你晓得i2c_adapter 也找不到i2c_client 。。
还有i2c_client 是在i2cdev_open()的时候在动态建立的,在i2cdev_release()就释放掉了,,也就是说在设备open的时候创建,在设备close的时候销毁...
那么请问你是如何得到i2c_client呢?
作者: wmmy2008 发布时间: 2010-07-16
i2c_adatper一直存在,我是一个嵌入式设备,实现的是cpu上的i2c,该驱动是编译进kernel的。i2c_client表示i2c设备,在i2c_adapter结构中是以链表来组织的,具体楼上可以看一下i2c_adapter的结构。
例如rtc pcf8563的模块插入的时候,i2c_adapter就会加入一个pcf8563的i2c_client,生存周期我认为是伴随该模块的。无论你open or close /dev/i2c/0,总是能通过hwclock来操作该rtc设备。
你说i2c_client在i2cdev_open时动态建立,我猜测是用户空间操作i2c设备时,内核需要一个i2c_client来承载对于指定地址的i2c设备的操作。
例如我在用户空间里对地址0x51(pcf8563的i2c地址)发送数据,i2cdev实现部分会生成一个i2c_client实例来操作,但不影响原来rtc pcf8562的这个i2c_client。应该说是不同的功能生成了不同的i2c_client,但却指向了同一个设备。
我只是从你的话中猜测内核的做法,有空我去看一实现。
欢迎讨论!
谢谢!
作者: jetking 发布时间: 2010-07-16
不好意思,很久以前看过的I2C架构了,有些忘了。。
刚才又简单看了一下,这两个client确实用处不一样,在i2c_attach_client()函数中有个函数list_add_tail(&client->list, &adapter->clients);
所以是可以先找到的adapter,然后遍历下面挂的所有client,这是可以的。。
但是我觉得你这样子做有点绕,,因为I2C架构已经为我们提供了设备操作方法接口,你可以看看 drivers/i2c/i2c-dev.c 上面我们可以read,write,ioctl配置读写地址等很多功能,,如果你再去实现这些东西就没的好大的意思了,有现成的直接用好些。。
作者: wmmy2008 发布时间: 2010-07-16
作者: jetking 发布时间: 2010-07-17
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28