日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發布時間:2024/7/19 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux at24测试程序,linux 2.6下eeprom at24c08 i2c设备驱动(new style probe方式) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 修改bsp_以便支持probe

1.1 AT24C08地址的確定

原理圖上將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

總結

以上是生活随笔為你收集整理的linux at24测试程序,linux 2.6下eeprom at24c08 i2c设备驱动(new style probe方式)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。