登录
注册
一键加入QQ群
友善之臂官方网站
首 页
联系我们
淘宝店铺
维基教程
固件下载
资料汇总
搜索帖子!
NanoPC 系列:
NanoPC-T2
NanoPC-T3 Plus
NanoPC-T4
NanoPC-T6
NanoPC-T6 Plus
NanoPi 系列:
NanoPi-NEO
NEO Core
NEO Air
M1 Plus
Duo2
NEO3
NEO4
M4B
M5
M6
M6V2
核心板:
Smart4418
Core4418
Smart6818
Core6818
SOM-RK3399V2
CM3588
CM3588 Plus
迷你R系列:
NanoPi-R1
R1S
R2S
R2S Plus
Zero2
R3S
R76S
R4S
R5S
R5C
R6C
R6S
热门版块:
开发板销售中心
开发板硬件讨论区
硬软DIY及开发
嵌入式交流与讨论
友友粉丝快线
Ubuntu技术交流区
默认风格
用户中心首页
编辑个人资料
查看个人资料
好友列表
用户权限查看
积分管理
积分转换
特殊组购买
收藏夹
我的主题
基本统计信息
到访IP统计
管理团队
管理统计
在线统计
会员排行
版块排行
帖子排行
个人首页
我的收藏
好友近况
Linux技术交流区
加载I2C总线驱动为什么看不到主设备号
友友粉丝快线
开发板销售中心
嵌入式最新资讯
友善之臂最新动态
友善之臂官方客服中心
开发板实战手册及教程
应用方案和定制开发
NanoPi 交流与讨论
NanoPi 玩家交流区
ROM发布区
硬软DIY及开发
嵌入式交流与讨论
Android技术交流区
Linux技术交流区
U-boot技术交流区
WinCE技术交流区
Ubuntu技术交流区
裸机程序和微型OS
OpenWRT讨论区
开发板硬件讨论区
相关资料下载及使用技巧
站点服务
二手交易区
我的论坛我的贴
站务管理与公告
上一主题
下一主题
新 帖
主题 : 加载I2C总线驱动为什么看不到主设备号
复制链接
|
浏览器收藏
|
打印
sanmaoljh
因为这个舞台,我们相聚在一起!
级别: 侠客
作者资料
发送短消息
加为好友
QQ联系
UID:
2527
精华:
1
发帖:
91
金钱:
505 两
威望:
101 点
综合积分:
202 分
注册时间:
2008-11-22
最后登录:
2015-06-08
楼主
发表于: 2013-04-07 14:01
只看楼主
|
小
中
大
加载I2C总线驱动为什么看不到主设备号
/********************************************
编译环境:linux 2.6.29内核
********************************************/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/kdev_t.h>
#define AT24C08B_MAJOR 250
static int at24c08b_major = AT24C08B_MAJOR;
struct at24c08b_dev
{
struct i2c_client *client;
char name[30];
unsigned short current_pointer;
struct cdev cdev;
};
struct at24c08b_dev *at24c08b_devp;
static int at24c08b_open (struct inode *inode, struct file *file)
{
/*将设备描述结构指针赋值给文件私有数据指针*/
file->private_data = at24c08b_devp;
return 0;
}
static ssize_t at24c08b_read (struct file *file, char *buf, size_t count, loff_t * ppos)
{
int i = 0;
int transferred = 0;
int ret, my_buf[512];
struct at24c08b_dev *dev = (struct at24c08b_dev *) file->private_data;
dev->current_pointer = *ppos;
/* Return 1 if adapter supports everything we need, 0 if not. */
if (i2c_check_functionality (dev->client->adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA))
{
while (transferred < count)
{
//SMBus "read byte" protocol
ret =i2c_smbus_read_byte_data (dev->client,
dev->current_pointer + i);
my_buf[i++] = (unsigned short) ret;
transferred += 1;
}
/*读数据到用户空间*/
copy_to_user (buf, (void *) my_buf, transferred);
dev->current_pointer += transferred;
}
return transferred;
}
static ssize_t at24c08b_write (struct file *file, char *buf, size_t count, loff_t * ppos)
{
int i = 0;
int transferred = 0;
int ret, my_buf[512];
struct at24c08b_dev *dev = (struct at24c08b_dev *) file->private_data;
dev->current_pointer = *ppos;
if (i2c_check_functionality(dev->client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
{
/*从用户空间写入数据*/
copy_from_user (my_buf, buf, count);
while (transferred < count)
{
//SMBus "write byte" protocol
ret =i2c_smbus_write_byte_data (dev->client,
dev->current_pointer + i,
my_buf
);
i += 1;
transferred += 1;
}
dev->current_pointer += transferred;
}
return transferred;
}
static int at24c08b_ioctl (struct inode *inodep, struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
static int at24c08b_release (struct inode *inodep, struct file *file)
{
file->private_data = NULL;
return 0;
}
static const struct file_operations at24c08b_fops = {
.owner = THIS_MODULE,
.open = at24c08b_open,
.read = at24c08b_read,
.write = at24c08b_write,
.ioctl = at24c08b_ioctl,
.release = at24c08b_release,
};
//初始化字符设备,注册字符设备到系统
static void at24c08b_setup_cdev (struct at24c08b_dev *dev, int index)
{
int err, devnum = MKDEV (at24c08b_major, index);
cdev_init (&dev->cdev, &at24c08b_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add (&dev->cdev, devnum, 1);
if (err)
printk (KERN_NOTICE "Error %d adding at24c08b %d", err, index);
}
#if 1
static int __devinit at24c08b_probe (struct i2c_client *client, const struct i2c_device_id *id)
{
int ret;
dev_t devnum;
printk (KERN_NOTICE "at24c08b probe is start\n"); //调试用,看是否执行了probe 函数
//dev_t devnum = MKDEV(at24c08b_major, 0);
devnum = MKDEV(at24c08b_major, 0);
if (at24c08b_major) //静态申请设备号
ret = register_chrdev_region(devnum, 1, "at24c08b");
else
{ //动态分配设备号
ret = alloc_chrdev_region(&devnum, 0, 1, "at24c08b");
at24c08b_major = MAJOR (devnum);
}
if (ret < 0)
return ret;
at24c08b_devp = kmalloc(sizeof (struct at24c08b_dev), GFP_KERNEL);
if (!at24c08b_devp)
{
ret = -ENOMEM;
goto fail_malloc;
}
memset (at24c08b_devp, 0, sizeof (struct at24c08b_dev));
at24c08b_devp->client = client;
at24c08b_setup_cdev (at24c08b_devp, 0); //注册字符设备到系统
return 0;
fail_malloc:
unregister_chrdev_region (devnum, 1); //注销设备号
return ret;
}
#endif
static int __devexit at24c08b_remove (struct i2c_client *client)
{
cdev_del (&at24c08b_devp->cdev);
kfree (at24c08b_devp);
unregister_chrdev_region (MKDEV(at24c08b_major, 0), 1);
return 0;
}
static const struct i2c_device_id at24c08b_id[] = {
{"at24c08b", 0}, //这个0是不是有点奇怪啊, 呵呵
{}
};
MODULE_DEVICE_TABLE (i2c, at24c08b_id);
static struct i2c_driver at24c08b_driver = {
.driver = {
.name = "at24c08b",
.owner = THIS_MODULE,
},
.probe = at24c08b_probe,
.remove = __devexit_p (at24c08b_remove),
.id_table = at24c08b_id,
};
static int __init at24c08b_init (void)
{
int result;
printk (KERN_NOTICE "at24c08b is insmod\n");
//return i2c_add_driver (&at24c08b_driver);
result = i2c_add_driver (&at24c08b_driver);
printk (KERN_NOTICE "at24c08b is %d\n",result);
return result;
}
void at24c08b_exit (void)
{
printk (KERN_NOTICE "at24c08b is rmmod\n");
i2c_del_driver (&at24c08b_driver);
}
MODULE_DESCRIPTION ("at24c08b eeprom driver");
MODULE_LICENSE ("Dual BSD/GPL");
MODULE_AUTHOR ("Weimeng Li <
pursuitxh@163.com
>");
MODULE_VERSION ("V1.0");
module_param (at24c08b_major, int, S_IRUGO);
module_init (at24c08b_init);
module_exit (at24c08b_exit);
//-----------------------------------------------------------------------
串口打印信息如下:
# lsmod
# insmod at24c08-driver.ko
at24c08b is insmod
at24c08b is 0
# lsmod
at24c08_driver 3752 0 - Live 0xbf000000
# cat /proc/devices
Character devices:
1 mem
4 /dev/vc/0
4 tty
5 /dev/tty
5 /dev/console
5 /dev/ptmx
7 vcs
10 misc
13 input
14 sound
29 fb
81 video4linux
90 mtd
116 alsa
128 ptm
136 pts
180 usb
188 ttyUSB
189 usb_device
204 s3c2410_serial
253 usb_endpoint
254 rtc
Block devices:
259 blkext
7 loop
8 sd
31 mtdblock
65 sd
66 sd
67 sd
68 sd
69 sd
70 sd
71 sd
128 sd
129 sd
130 sd
131 sd
132 sd
133 sd
134 sd
135 sd
179 mmc
#
//----------------------------------------------------------------------------------------
加载内核后i2c_add_driver函数成功返回为0,但是在打印cat /proc/devices
没有找到i2c驱动的主设备编号250
分析串口打印信息中得知,说明没有调用probe函数,但设备名(at24c08b)与驱动名(at24c08b)只要匹配成功,
就应当调用probe函数,为什么这里没有调用probe函数?谢谢。
蜗牛
顶端
回复
引用
分享
kasim
*無鈳取玳
级别: 论坛版主
作者资料
发送短消息
加为好友
QQ联系
UID:
27
精华:
12
发帖:
5398
金钱:
40120 两
威望:
17929 点
综合积分:
11036 分
注册时间:
2008-01-16
最后登录:
2014-11-22
1楼
发表于: 2013-04-07 20:51
只看该作者
|
小
中
大
回 楼主(sanmaoljh) 的帖子
分析串口打印信息中得知,说明没有调用probe函数,但设备名(at24c08b)与驱动名(at24c08b)只要匹配成功,
匹配的前提是有一个名字为"at24c08b"的i2c device注册到i2c bus上。也就是说,你在/sys/bus/i2c/devices下应该能看到一个X-00YY的链接指向这个设备的属性文件。其中,X是I2C Controller的编号,YY是at24c08b的7bit I2C地址。
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
顶端
回复
引用
分享
上一主题
下一主题
Linux技术交流区
http://121.40.142.80
访问内容超出本站范围,不能确定是否安全
继续访问
取消访问