linux at24测试程序,linux 2.6下eeprom at24c08 i2c设备驱动(new style probe方式)

1 修改bsp_以便支持probe

1.1 AT24C08地址的确定

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png原理图上将A2、A1、A0都接地了,所以地址是0x50。

注意到是7位(bit).

1.2 修改bsp

采用友善之臂的, 2.6.32.2内核

[root@localhost mach-s3c2440]# vim

/opt/FriendlyARM/mini2440/linux-2.6.32.2/arch/arm/mach-s3c2440/mach-mini2440.c

#include

static struct platform_device *mini2440_devices[] __initdata =

{

&s3c_device_usb,

&s3c_device_rtc,

&s3c_device_lcd,

&s3c_device_wdt,

&s3c_device_i2c0, //没有修改

&s3c_device_iis,

&mini2440_device_eth,

&s3c24xx_uda134x,

&s3c_device_nand,

&s3c_device_sdi,

&s3c_device_usbgadget,

}; //这里没有修改

static struct at24_platform_data at24c08 = {

.byte_len = SZ_8K / 8,

.page_size = 16,

}; //add

static struct i2c_board_info i2c_devices[] __initdata = {

{ I2C_BOARD_INFO("at24c08b", 0x50),

.platform_data = &at24c08, //不可少的

},

}; //add

#if 0

static struct i2c_board_info i2c_devices[] __initdata = {

{ I2C_BOARD_INFO("at24c08b", 0x50),

.irq=43, //不用.platform_data = &at24c08, 用这个也行

//从cat /proc/interrupt中可知

},

}; //TESTED BY awaken_ing#163

#endif

static void __init mini2440_machine_init(void)

{

i2c_register_board_info(0,i2c_devices,ARRAY_SIZE(i2c_devices));

//add

#if defined (LCD_WIDTH)

s3c24xx_fb_set_platdata(&mini2440_fb_info);

#endif

s3c_i2c0_set_platdata(NULL);

s3c2410_gpio_cfgpin(S3C2410_GPC(0), S3C2410_GPC0_LEND);

s3c_device_nand.dev.platform_data =

&friendly_arm_nand_info;

s3c_device_sdi.dev.platform_data =

&mini2440_mmc_cfg;

platform_add_devices(mini2440_devices,

ARRAY_SIZE(mini2440_devices));

s3c_pm_init();

}

然后make -j2 (传说的多任务, 这里是2个任务, 速度快点)进行编译内核

1.3 编译内核, 然后u-boot部分

#/opt/study_arm/u-boot-2009.11_ok_no_nand/tools/mkimage -A arm -O

linux -T kernel -C none -a 30008000 -e 30008040 -n linux_awaken -d

/opt/FriendlyARM/mini2440/linux-2.6.32.2/arch/arm/boot/zImage

/opt/study_arm/uImage_mini_2.img

#nfs 30008000

192.168.0.9:/opt/study_arm/uImage_mini_2.img

#setenv bootargs noinitrd root=/dev/nfs rw

nfsroot=192.168.0.9:/opt/FriendlyARM/mini2440/rootfs_qtopia_qt4/

ip=192.168.0.2:192.168.0.1::255.255.255.0 console=ttySAC0,115200

init=/linuxrc mem=64M

#bootm 0x30008000

1.4 启动linux后

[root@FriendlyARM /home]# ls /dev|grep i2

i2c

这是原先的

[root@FriendlyARM /home]# mknod /dev/at24c08b c 250 0

要mknod的, 不是insmod后产生的, (我傻傻地在这折腾了好久)

[root@FriendlyARM /home]# ls /dev|grep 24

at24c08b

tty24

2 驱动程序

#include #include

#include

#include

#include

#include

#include

#include

#include#include

#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 intat24c08b_open (struct inode *inode, struct file

*file)

{

file->private_data =

at24c08b_devp;

return

0;}

static ssize_tat24c08b_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;

if

(i2c_check_functionality

(dev->client->adapter,

I2C_FUNC_SMBUS_READ_BYTE_DATA))

{

while

(transferred <

count)

{

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_tat24c08b_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)

{

ret =i2c_smbus_write_byte_data

(dev->client,

dev->current_pointer +

i,

my_buf[i]);

i += 1;

transferred += 1;

}

dev->current_pointer +=

transferred;

}

return

transferred;}

static intat24c08b_ioctl (struct inode *inodep, struct file *file, unsigned

int cmd, unsigned long arg)

{

return

0;}

static intat24c08b_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 voidat24c08b_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);}

static int __devinitat24c08b_probe (struct i2c_client *client, const struct

i2c_device_id *id)

{

int

ret;

printk

(KERN_NOTICE "at24c08b probe is

start\n"); //调试用,看是否执行了probe 函数 dev_t 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;}

static int __devexitat24c08b_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 __initat24c08b_init (void)

{

printk

(KERN_NOTICE "at24c08b is

insmod\n");

return

i2c_add_driver

(&at24c08b_driver);}

voidat24c08b_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 "); //不是我, 我是awaken_inghttp://blog.163.com/awaken_ing/MODULE_VERSION ("V1.0");

module_param (at24c08b_major, int, S_IRUGO);

module_init (at24c08b_init);module_exit (at24c08b_exit);

3 用户程序

#include #include

#include

#include

#include#include

int main(int argc, char **argv){

int i;

unsigned int value[512];

value[0] = 0x12;

value[1] = 0x23;

value[2] = 0x34;

value[3] = 0x45;

value[4] = 0x56; value[5] = 0x67;

int fd;fd = open("/dev/at24c08b",

O_RDWR);

if(fd < 0)

{

printf("Open at24c08b Device

Faild!\n");

exit(1); }

write(fd, value, 6);for(i = 0; i < 6;

i++)

printf("write reg[%d] data: %x to at24c08\n", i,

value[i]);

printf("#########################################\n"); sleep(1);

read(fd, value, 6);for(i = 0; i < 6;

i++) printf("read reg[%d] data: %x to at24c08\n", i, value[i]);

close(fd);return

0;}

4 makefile

#Makefile#变量APP、DEV分别用于配置用户程序/驱动程序

*文件名*

APP=app_i2c

DEV=i2c_no_fops

ifneq ($(KERNELRELEASE),)

#call from kernel build

system

obj-m:=$(DEV).o

else

KERNELDIR

?=/opt/FriendlyARM/mini2440/linux-2.6.32.2

PWD :=$(shell pwd)

default:

$(MAKE) -C

$(KERNELDIR) M=$(PWD)

modules

cp $(DEV).ko

/opt/FriendlyARM/mini2440/rootfs_qtopia_qt4/home

#for

app,根据变量APP是否为空来处理

ifneq ($(APP),)

arm-linux-gcc -Wall $(APP).c -o

$(APP)

cp $(APP)

/opt/FriendlyARM/mini2440/rootfs_qtopia_qt4/home

endifendif

clean:rm -rf

*.ko

rm -rf

*.o rm -rf *.mod.*

#注意到$(APP).c会正确得到解析.

5 测试

[root@FriendlyARM /home]# mknod /dev/at24c08b c 250 0

[root@FriendlyARM /home]# insmod dev_i2c.ko

at24c08b is insmod

at24c08b probe is start

[root@FriendlyARM /home]# ./app_i2c

write reg[0] data: 12 to at24c08

write reg[1] data: 23 to at24c08

write reg[2] data: 34 to at24c08

write reg[3] data: 45 to at24c08

write reg[4] data: 56 to at24c08

write reg[5] data: 67 to at24c08

#########################################

read reg[0] data: 12 to at24c08

read reg[1] data: 23 to at24c08

read reg[2] data: 34 to at24c08

read reg[3] data: 45 to at24c08

read reg[4] data: 56 to at24c08

read reg[5] data: 67 to at24c08

参考文章

linux文档 Documentation/i2c/upgrading-clients

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/486157.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中注释的使用

如何在Java中使用注释 在编写程序时&#xff0c;经常需要添加一些注释&#xff0c;用以描述某段代码的作用。 一般来说&#xff0c;对于一份规范的程序源代码而言&#xff0c;注释应该占到源代码的 1/3 以上。因此&#xff0c;注释是程序源代码的重要组成部分&#xff0c;一定要…

关于动态规划,你想知道的都在这里了!

作者 | Your DevOps Guy翻译| 火火酱~&#xff0c;责编 | 晋兆雨出品 | AI科技大本营头图 | 付费下载于视觉中国什么是动态规划&#xff1f;它又有什么重要的呢&#xff1f;在本文中&#xff0c;我将介绍由Richard Bellman在20世纪50年代提出的动态规划&#xff08;dynamic pro…

linux修改永久ip地址,centos设置IP地址,永久修改ipv4

# ifconfig #查看下本机的IP地址。eth0Link encap:Ethernet HWaddr 00:50:56:0A:0B:0Cinet addr:192.168.0.3 Bcast:192.168.0.255 Mask:255.255.255.0inet6 addr: fe80::250:56ff:fe0a:b0c/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:172220…

详细介绍MySQL/MariaDB的锁

官方手册&#xff1a;https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-transaction-model.html 1.事务提交的方式 在MariaDB/MySQL中有3种事务提交的方式。 1.显式开启和提交。 使用begin或者start transaction来显式开启一个事务&#xff0c;显式开启的事务必须使用c…

美国专利商标局发布人工智能专利扩散分析报告

以下文章来源&#xff1a;中科院知识产权信息&#xff0c;2020-11-23报告显示&#xff0c;从2002到2018年&#xff0c;美国人工智能专利的年申请量增长超过100%&#xff0c;从每年3万件增加到6万多件&#xff0c;含人工智能的专利申请所占份额从9%上升到近16%。同时&#xff0c…

java 开发环境的搭建

这里主要说的是在windows 环境下怎么配置环境。 1.首先安装JDK java的sdk简称JDK &#xff0c;去其官方网站下载最近的JDK即可。。http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html点击下载好的exe文件安装即可。 2.接下来我们需要配置环…

linux内核等价多路径路由,Linux内核分析 - 网络[四]:路由表

路由表的创建inet_init() -> ip_init() -> ip_fib_init() -> fib_net_init() -> ip_fib_net_init()[net\ipv4\fib_frontend.c]首先为路由表分配空间&#xff0c;这里的每个表项hlist_head实际都会链接一个单独的路由表&#xff0c;FIB_TABLE_HASHSZ表示了分配多少个…

2017级面向对象程序设计 作业二

以下均以扫描方式为例&#xff0c;即电梯只会在最底层和最高层选择掉头&#xff0c;路途中遇到路径方向相同的乘客将他带上电梯。 文字描述面向过程实现的步骤&#xff1a; 一. 定义有关电梯的变量&#xff0c;如&#xff1a;1.电梯当前所在楼层.&#xff0c;2. 电梯内的人数&a…

新型支架状电极允许人类思想操作计算机

Illustration: Synchron来源&#xff1a;IEEE电气电子工程师据悉&#xff0c;两名患有神经肌肉疾病的澳大利亚人在他们的大脑中植入了支架状的电极&#xff0c;使他们能够利用自己的思想操作电脑&#xff0c;从而恢复了一些个人独立性。据发明者介绍&#xff0c;这是这种被称为…

java中的foreach

foreach 并不是java中的关键字&#xff0c;是for语句的特殊简化版&#xff0c;在比那里数组&#xff0c;集合时&#xff0c;foreach更加简单快捷&#xff0c;从字面上的意思理解 foreach 也就是 “ for每一个 ”的意思&#xff0c;那么到底怎么使用 foreach语句呢&#xff1f; …

ACM数论-素数

ACM数论——素数 素数定义&#xff1a; 质数&#xff08;prime number&#xff09;又称素数&#xff0c;有无限个。质数定义为在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数&#xff0c;这样的数称为质数。例 子&#xff1a;2、3、5、7、11、13、17、19。&am…

机器视觉中彩色成像必须考虑的十个问题

来源&#xff1a;Imagination Tech在为你的产品开发最适合的机器视觉系统时&#xff0c;需要考虑很多因素&#xff0c;以下列出开发过程中需要考虑的一些问题&#xff1a;颜色准确性/差异化首先要考虑的是应用程序所需的颜色精度和差异程度。在某些应用中&#xff0c;机器视觉相…

嫦娥“挖土”归来有多难?看看中国首颗返回式卫星的故事

本文转载自“科技日报&#xff08;kjrbwx&#xff09;”&#xff0c;原标题《嫦娥“挖土”归来有多难&#xff1f;看看中国首颗返回式卫星的故事》&#xff0c;作者 | 吕炳宏 付毅飞2020年11月30日&#xff0c;嫦娥五号探测器在环月轨道上&#xff0c;成功实施着陆器上升器组合…

重磅,2020年度第十届吴文俊人工智能科学技术奖获奖名单公示

来源&#xff1a;科奖圈根据《吴文俊人工智能科学技术奖励条例》和《吴文俊人工智能科学技术奖励实施细则》相关规定&#xff0c;经全国各地方人工智能学会、协会及联盟&#xff0c;各高校及科研&#xff08;院&#xff09;所&#xff0c;学会各专业委员会及工作委会&#xff0…

理解 %IOWAIT (%WIO)

%iowait 是 “sar -u” 等工具检查CPU使用率时显示的一个指标&#xff0c;在Linux上显示为 %iowait&#xff0c;在有的Unix版本上显示为 %wio&#xff0c;含义都是一样的。这个指标常常被误读&#xff0c;很多人把它当作I/O问题的征兆&#xff0c;我自己每隔一段时间就会遇到对…

自由意志不存在?神经科学能证明不?

来源&#xff1a; 神经现实本文经授权摘自《认知科学对当代哲学的挑战》作者&#xff1a;李恒威神经科学能说明自由意志不存在吗?里贝特是人类意识和自由意志的实验研究领域的先驱性神经科学家&#xff0c;但驱使他开展意识的实证研究的根本动因是回应意识科学研究中的本体论问…

MySQL数据库order by 奇慢无比

今天遇到个奇葩的问题&#xff0c; sql 数据量很大 有where 和order by&#xff0c;不加order by 速度很快&#xff0c;加了就很慢 一、首先我们对这条sql执行查询计划&#xff1a; explain select t.order_id from book_order t ORDER BY t.order_id desc explain select t.…

PNAS “深度学习的科学”论文合集导读

来源&#xff1a;混沌巡洋舰今天的科学家对于机器可以学习做什么的想法与我们10年前完全不同。在图像处理、语音和视频处理、机器视觉、自然语言处理和经典的双人游戏中&#xff0c;特别是在过去的十年中&#xff0c;随着在一系列公共组织的挑战问题&#xff08;例如围棋&#…

s3c6410 jpeg编码 linux,S3C6410 裸机硬件JPEG解码

主函数的部分代码/**************************************************************************************************************************函数 : static PIC_ERROR OpenPictureFile(const char *FileName,u8 *buff,u32 FileMaxSize)*功能 : 打开一张…

注解原理

学习spring时&#xff0c;大量使用了注解&#xff0c;但一直对其底层实现机制不得其解&#xff1a; ref&#xff1a;http://www.cnblogs.com/Johness/archive/2013/04/17/3026689.html ref&#xff1a;https://www.jianshu.com/p/28edf5352b63 ref&#xff1a;http://www.cnblo…