LINUX下读写寄存器.doc_第1页
LINUX下读写寄存器.doc_第2页
LINUX下读写寄存器.doc_第3页
LINUX下读写寄存器.doc_第4页
LINUX下读写寄存器.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

arm裸机下读写寄存器很容易,各个寄存器和内存的地址是单一地址空间,他们是用相同的指令进行读写操作的.而在linux下就要复杂很多,因为linux支持多个体系架构的CPU。比如arm和x86就不一样,具体的差别我暂时也说不上来,这个涉及到CPU体系的设计。目前我只关心:linux为了支持多个硬件体系,在IO访问上做了自己的接口。可以通过IO内存和IO端口这两种方式进行IO访问。在LED的例子上给出这两种方式的具体实现: 1.利用IO Port的方式:cpp view plaincopy #include #include #include #include /* printk() */ #include /* kmalloc() */ #include /* everything. */ #include /* error codes */ #include /* size_t */ #include #include /* O_ACCMODE */ #include #include #include #include #include /* cli(), *_flags */ #include /* copy_*_user */ #include #define LED_NUM 4 struct led_dev struct cdev dev; unsigned port; unsigned long offset; ; struct led_dev led4; dev_t dev = 0; static struct resource *led_resource; int led_open(struct inode *inode, struct file *filp) struct led_dev *led; /* device information */ led = container_of(inode-i_cdev, struct led_dev, dev); filp-private_data = led; /* for other methods */ return 0; /* success */ int led_release(struct inode *inode, struct file *filp) return 0; ssize_t led_read(struct file *filp, char _user *buf, size_t count, loff_t *f_pos) return 0; ssize_t led_write(struct file *filp, const char _user *buf, size_t count, loff_t *f_pos) char data; struct led_dev *led; u32 value; printk(KERN_INFO debug by baikal: led dev writen); led = (struct led_dev *)filp-private_data; copy_from_user(&data,buf,count); if(data = 0) printk(KERN_INFO debug by baikal: led offn); value = inl(unsigned)(S3C2410_GPBDAT); outl(value | 1offset,(unsigned)(S3C2410_GPBDAT); /value = ioread32(led-base); /iowrite32( value | 1offset, led-base); else printk(KERN_INFO debug by baikal: led onn); value = inl(unsigned)(S3C2410_GPBDAT); outl(value & (1offset),(unsigned)(S3C2410_GPBDAT); /value = ioread32(led-base); /iowrite32( value & (1offset), led-base); struct file_operations led_fops = .owner = THIS_MODULE, .read = led_read, .write = led_write, /.ioctl = led_ioctl, .open = led_open, .release = led_release, ; static int led_init(void) int result, i; result = alloc_chrdev_region(&dev, 0, LED_NUM,LED); if (result 0) printk(KERN_WARNING LED: cant get major %dn, MAJOR(dev); return result; led_resource = request_region(0x56000014,0x4,led); if(led_resource = NULL) printk(KERN_ERR Unable to register LED I/O addressesn); return -1; for(i = 0; i LED_NUM; i+) cdev_init( &ledi.dev, &led_fops); /ledi.port = ioport_map(0x56000014,0x4); /ledi.base = ioremap(0x56000014,0x4); ledi.offset = i + 5; /leds GPB5678 ledi.dev.owner = THIS_MODULE; ledi.dev.ops = &led_fops; result = cdev_add(&ledi.dev,MKDEV(MAJOR(dev),i),1); if(result 0) printk(KERN_ERR LED: cant add led%dn,i); return result; return 0; static void led_exit(void) int i; release_region(0x56000014,0x4); for( i = 0; i LED_NUM; i+) /iounmap(ledi.base); cdev_del(&ledi.dev); unregister_chrdev_region(dev, LED_NUM); module_init(led_init); module_exit(led_exit); MODULE_AUTHOR(Baikal); MODULE_LICENSE(GPL); MODULE_DESCRIPTION(Simple LED Driver); 2.利用IO Mem的方式:cpp view plaincopy #include #include #include #include /* printk() */ #include /* kmalloc() */ #include /* everything. */ #include /* error codes */ #include /* size_t */ #include #include /* O_ACCMODE */ #include #include #include #include /* cli(), *_flags */ #include /* copy_*_user */ #include #define LED_NUM 4 struct led_dev struct cdev dev; void _iomem *base; unsigned long offset; ; struct led_dev led4; dev_t dev = 0; int led_open(struct inode *inode, struct file *filp) struct led_dev *led; /* device information */ led = container_of(inode-i_cdev, struct led_dev, dev); filp-private_data = led; /* for other methods */ return 0; /* success */ int led_release(struct inode *inode, struct file *filp) return 0; ssize_t led_read(struct file *filp, char _user *buf, size_t count, loff_t *f_pos) return 0; ssize_t led_write(struct file *filp, const char _user *buf, size_t count, loff_t *f_pos) char data; struct led_dev *led; u32 value; printk(KERN_INFO debug by baikal: led dev writen); led = (struct led_dev *)filp-private_data; copy_from_user(&data,buf,count); if(data = 0) printk(KERN_INFO debug by baikal: led offn); value = ioread32(led-base); iowrite32( value | 1offset, led-base); else printk(KERN_INFO debug by baikal: led onn); value = ioread32(led-base); iowrite32( value & (1offset), led-base); struct file_operations led_fops = .owner = THIS_MODULE, .read = led_read, .write = led_write, /.ioctl = led_ioctl, .open = led_open, .release = led_release, ; static int led_init(void) int result, i; result = alloc_chrdev_region(&dev, 0, LED_NUM,LED); if (result 0) printk(KERN_WARNING LED: cant get major %dn, MAJOR(dev); return result; for(i = 0; i LED_NUM; i+) cdev_init( &ledi.dev, &led_fops); request_mem_region(0x56000014,0x4,led); ledi.base = ioremap(0x56000014,0x4); ledi.offset = i + 5; /leds GPB5678 ledi.dev.owner = THIS_MODULE; ledi.dev.ops = &led_fops; result = cdev_add(&ledi.dev,MKDEV(MAJOR(dev),i),1); if(result 0) printk(KERN_ERR LED: cant add led%dn,i); return result; return 0; static void led_exit(void) int i; release_mem_region(0x56000014,0x4); for( i = 0; i LED_NUM; i+) iounm

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论