LINUX下读写寄存器.docx

上传人:b****5 文档编号:7423449 上传时间:2023-01-23 格式:DOCX 页数:10 大小:16.19KB
下载 相关 举报
LINUX下读写寄存器.docx_第1页
第1页 / 共10页
LINUX下读写寄存器.docx_第2页
第2页 / 共10页
LINUX下读写寄存器.docx_第3页
第3页 / 共10页
LINUX下读写寄存器.docx_第4页
第4页 / 共10页
LINUX下读写寄存器.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

LINUX下读写寄存器.docx

《LINUX下读写寄存器.docx》由会员分享,可在线阅读,更多相关《LINUX下读写寄存器.docx(10页珍藏版)》请在冰豆网上搜索。

LINUX下读写寄存器.docx

LINUX下读写寄存器

arm裸机下读写寄存器很容易,各个寄存器和内存的地址是单一地址空间,他们是用相同的指令进行读写操作的.而在linux下就要复杂很多,因为linux支持多个体系架构的CPU。

比如arm和x86就不一样,具体的差别我暂时也说不上来,这个涉及到CPU体系的设计。

目前我只关心:

linux为了支持多个硬件体系,在IO访问上做了自己的接口。

可以通过IO内存和IO端口这两种方式进行IO访问。

在LED的例子上给出这两种方式的具体实现:

1.利用IOPort的方式:

[cpp]viewplaincopy

#include

#include

#include

#include/*printk()*/

#include/*kmalloc()*/

#include/*everything...*/

#include/*errorcodes*/

#include/*size_t*/

#include

#include/*O_ACCMODE*/

#include

#include

#include

#include

#include/*cli(),*_flags*/

#include/*copy_*_user*/

#include

#defineLED_NUM4

structled_dev

{

structcdevdev;

unsignedport;

unsignedlongoffset;

};

structled_devled[4];

dev_tdev=0;

staticstructresource*led_resource;

intled_open(structinode*inode,structfile*filp)

{

structled_dev*led;/*deviceinformation*/

led=container_of(inode->i_cdev,structled_dev,dev);

filp->private_data=led;/*forothermethods*/

return0;/*success*/

}

intled_release(structinode*inode,structfile*filp)

{

return0;

}

ssize_tled_read(structfile*filp,char__user*buf,size_tcount,loff_t*f_pos)

{

return0;

}

ssize_tled_write(structfile*filp,constchar__user*buf,size_tcount,loff_t*f_pos)

{

chardata;

structled_dev*led;

u32value;

printk(KERN_INFO"debugbybaikal:

leddevwrite\n");

led=(structled_dev*)filp->private_data;

copy_from_user(&data,buf,count);

if(data=='0')

{

printk(KERN_INFO"debugbybaikal:

ledoff\n");

value=inl((unsigned)(S3C2410_GPBDAT));

outl(value|1<offset,(unsigned)(S3C2410_GPBDAT));

//value=ioread32(led->base);

//iowrite32(value|1<offset,led->base);

}

else

{

printk(KERN_INFO"debugbybaikal:

ledon\n");

value=inl((unsigned)(S3C2410_GPBDAT));

outl(value&~(1<offset),(unsigned)(S3C2410_GPBDAT));

//value=ioread32(led->base);

//iowrite32(value&~(1<offset),led->base);

}

}

structfile_operationsled_fops={

.owner=THIS_MODULE,

.read=led_read,

.write=led_write,

//.ioctl=led_ioctl,

.open=led_open,

.release=led_release,

};

staticintled_init(void)

{

intresult,i;

result=alloc_chrdev_region(&dev,0,LED_NUM,"LED");

if(result<0){

printk(KERN_WARNING"LED:

can'tgetmajor%d\n",MAJOR(dev));

returnresult;

}

led_resource=request_region(0x56000014,0x4,"led");

if(led_resource==NULL)

{

printk(KERN_ERR"UnabletoregisterLEDI/Oaddresses\n");

return-1;

}

for(i=0;i

{

cdev_init(&led[i].dev,&led_fops);

//led[i].port=ioport_map(0x56000014,0x4);

//led[i].base=ioremap(0x56000014,0x4);

led[i].offset=i+5;//ledsGPB5\6\7\8

led[i].dev.owner=THIS_MODULE;

led[i].dev.ops=&led_fops;

result=cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);

if(result<0)

{

printk(KERN_ERR"LED:

can'taddled%d\n",i);

returnresult;

}

}

return0;

}

staticvoidled_exit(void)

{

inti;

release_region(0x56000014,0x4);

for(i=0;i

{

//iounmap(led[i].base);

cdev_del(&led[i].dev);

}

unregister_chrdev_region(dev,LED_NUM);

}

module_init(led_init);

module_exit(led_exit);

MODULE_AUTHOR("Baikal");

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("SimpleLEDDriver");

 

2.利用IOMem的方式:

[cpp]viewplaincopy

#include

#include

#include

#include/*printk()*/

#include/*kmalloc()*/

#include/*everything...*/

#include/*errorcodes*/

#include/*size_t*/

#include

#include/*O_ACCMODE*/

#include

#include

#include

#include/*cli(),*_flags*/

#include/*copy_*_user*/

#include

#defineLED_NUM4

structled_dev

{

structcdevdev;

void__iomem*base;

unsignedlongoffset;

};

structled_devled[4];

dev_tdev=0;

intled_open(structinode*inode,structfile*filp)

{

structled_dev*led;/*deviceinformation*/

led=container_of(inode->i_cdev,structled_dev,dev);

filp->private_data=led;/*forothermethods*/

return0;/*success*/

}

intled_release(structinode*inode,structfile*filp)

{

return0;

}

ssize_tled_read(structfile*filp,char__user*buf,size_tcount,loff_t*f_pos)

{

return0;

}

ssize_tled_write(structfile*filp,constchar__user*buf,size_tcount,loff_t*f_pos)

{

chardata;

structled_dev*led;

u32value;

printk(KERN_INFO"debugbybaikal:

leddevwrite\n");

led=(structled_dev*)filp->private_data;

copy_from_user(&data,buf,count);

if(data=='0')

{

printk(KERN_INFO"debugbybaikal:

ledoff\n");

value=ioread32(led->base);

iowrite32(value|1<offset,led->base);

}

else

{

printk(KERN_INFO"debugbybaikal:

ledon\n");

value=ioread32(led->base);

iowrite32(value&~(1<offset),led->base);

}

}

structfile_operationsled_fops={

.owner=THIS_MODULE,

.read=led_read,

.write=led_write,

//.ioctl=led_ioctl,

.open=led_open,

.release=led_release,

};

staticintled_init(void)

{

intresult,i;

result=alloc_chrdev_region(&dev,0,LED_NUM,"LED");

if(result<0){

printk(KERN_WARNING"LED:

can'tgetmajor%d\n",MAJOR(dev));

returnresult;

}

for(i=0;i

{

cdev_init(&led[i].dev,&led_fops);

request_mem_region(0x56000014,0x4,"led");

led[i].base=ioremap(0x56000014,0x4);

led[i].offset=i+5;//ledsGPB5\6\7\8

led[i].dev.owner=THIS_MODULE;

led[i].dev.ops=&led_fops;

result=cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);

if(result<0)

{

printk(KERN_ERR"LED:

can'taddled%d\n",i);

returnresult;

}

}

return0;

}

staticvoidled_exit(void)

{

inti;

release_mem_region(0x56000014,0x4);

for(i=0;i

{

iounmap(led[i].base);

cdev_del(&led[i].dev);

}

unregister_chrdev_region(dev,LED_NUM);

}

module_init(led_init);

module_exit(led_exit);

MODULE_AUTHOR("Baikal");

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("SimpleLEDDriver");

 

目前,对于具体体系上的linux在移植过程中如何实现这两种方式的方法还不清楚,现在只是会用。

等以后有机会了再慢慢理清楚。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1