Linux下SRAM的读写

来源:互联网 发布:bender软件 编辑:程序博客网 时间:2024/04/27 20:43

项目中需要用ARM与FPGA进行通信,通信方式是通过FPGA生成的SRAM作为数据的交换区,ARM9芯片为ATMEL的AT91SAM9260,采用Linux 2.6.19的内核,今天搞了一天,总算是读写成功,下面简要的说明一下。

       ARM中只有I/O内存的没有I/O端口,ARM9运行后默认是开启MMU的,Linux采用虚拟存储管理内存,具体的内存管理方式本文不作展开。所以要使用Linux访问外设必须要先进行内存映射。这里主要涉及两个函数:

Ø         Request_mem_region:该函数检查所需要转换的内存是否被占用,进行合法性检查,有些驱动中没有,个人认为安全性起见还是使用为妙。

Ø         Ioremap:该函数完成物理地址到虚拟地址的映射,映射后的地址才能被Linux内核使用。

下面给出代码:

驱动程序:

view plain
  1. #include <linux/module.h>  
  2. #include <linux/types.h>  
  3. #include <linux/fs.h>  
  4. #include <linux/types.h>  
  5. #include <linux/kernel.h>  
  6. #include <linux/init.h>  
  7. #include <linux/platform_device.h>  
  8. #include <linux/cdev.h>  
  9. #include <linux/ioctl.h>  
  10. #include <linux/gpio.h>  
  11. #include <linux/mm.h>  
  12. #include <linux/errno.h>  
  13. #include <asm/arch/hardware.h>  
  14. #include <asm/arch/gpio.h>  
  15. #include <asm/uaccess.h>  
  16. #include <linux/slab.h> /*for Kmalloc*/  
  17. #include <asm/io.h>/*for virt_to_phys*/  
  18. #include <asm/hardware.h>  
  19. #include <asm/arch/at91_pio.h>  
  20. #include <asm/arch/at91rm9200.h>/*for sram address and size*/  
  21.   
  22. #define SRAM0_PHYADDR 0x300000  
  23. #define SRAM0_SIZE 0x1000  /*4K*/  
  24.   
  25.   
  26. int sram_major = 242;  
  27.   
  28. int sram_open(struct inode *inode,struct file *filp);  
  29. int sram_release(struct inode *inode,struct file *filp);  
  30. int sram_release(struct inode *inode,struct file *filp);  
  31. ssize_t sram_read(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos);  
  32. ssize_t sram_write(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos);  
  33. //int sram_mmap(struct file *filp, struct vm_area_struct *vma );  
  34. //static void sram_setup_cdev(struct sram_dev *dev,int index);  
  35. int sram_init(void);  
  36. void sram_cleanup(void);  
  37.   
  38.   
  39. MODULE_AUTHOR("Cun Tian Rui");  
  40. MODULE_LICENSE("Dual BSD/GPL");  
  41.   
  42.   
  43. struct sram_dev  
  44. {  
  45.     struct cdev cdev;     
  46.     unsigned long startAddr;  
  47.     unsigned long size;  
  48.     char *mapPtr;  
  49. }sram_dev;  
  50.   
  51. struct sram_dev *sramdevp;  
  52.   
  53. struct file_operations sram_fops =   
  54. {  
  55.     .owner = THIS_MODULE,  
  56.    // .ioctl = sram_ioctl,  
  57.     .open  = sram_open,  
  58.     .release = sram_release,  
  59.     .read = sram_read,  
  60.     .write = sram_write,  
  61.    // .mmap = sram_mmap  
  62. };  
  63.   
  64.   
  65.   
  66. int sram_open(struct inode *inode,struct file *filp)  
  67. {  
  68.     struct sram_dev *devp;  
  69.     devp = container_of(inode->i_cdev,struct sram_dev,cdev);  
  70.     filp->private_data = devp;  
  71.       
  72.     return 0;  
  73. }  
  74.   
  75. int sram_release(struct inode *inode,struct file *filp)  
  76. {  
  77.     return 0;      
  78. }  
  79.   
  80. ssize_t sram_read(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos)  
  81. {  
  82.       
  83.     unsigned long p = *f_pos;  
  84.         struct sram_dev *devp = filp->private_data;  
  85.     printk("Driver read function running\n");  
  86.     printk("p is %d\n",p);  
  87.      if (p >= devp->size)  
  88.         return -EINVAL;  
  89.      if (count > devp->size-p)  
  90.          count = devp->size-p;  
  91.      printk("count is %d\n",count);  
  92.          if (copy_to_user(buf, devp->mapPtr+p,count))  
  93.         return -EFAULT;  
  94.         *f_pos+= count;  
  95.     return count;      
  96. }   
  97.   
  98. ssize_t sram_write(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos)  
  99. {  
  100.       
  101.         unsigned long p = *f_pos;  
  102.         printk("Driver write function running\n");  
  103.         printk("p is %d\n",p);  
  104.     struct sram_dev *devp = filp->private_data;  
  105.     if (p >= devp->size)  
  106.         return -EINVAL;  
  107.     if (count > devp->size-p)  
  108.         count = devp->size-p;  
  109.         printk("count is %d\n",count);    
  110.     if (copy_from_user( devp->mapPtr+p,buf,count))  
  111.         return -EFAULT;  
  112.         *f_pos += count;  
  113.     return count;  
  114.       
  115. }  
  116. /* 
  117. int sram_mmap(struct file *filp, struct vm_area_struct *vma ) 
  118. { 
  119.     unsigned long offset = vma->vm_pgoff<<PAGE_SHIFT;  
  120.     unsigned long size = vma->vm_end - vma->vm_start;  
  121.  
  122.     if ( size > SRAM0_SIZE )  
  123.     {  
  124.         printk("size too big\n");  
  125.         return(-ENXIO);  
  126.     }  
  127.  
  128.         offset = offset + SRAM0_PHYADDR;  
  129.      
  130.     vma->vm_flags |= VM_LOCKED;  
  131.     if ( remap_pfn_range(vma,vma->vm_start,offset,size,PAGE_SHARED))  
  132.     {  
  133.         printk("remap page range failed\n");  
  134.         return -ENXIO;  
  135.     }  
  136.  
  137.     return(0);  
  138.  
  139. } 
  140. */  
  141.   
  142. int sram_init(void)  
  143. {  
  144.     int result;  
  145.     int err,ret;  
  146.     int devno = MKDEV(sram_major,0);  
  147.   
  148.     dev_t dev = MKDEV(sram_major,0);  
  149.     if(sram_major)  
  150.     {  
  151.           
  152.         result = register_chrdev_region(dev,1,"SRAM0");  
  153.     }  
  154.   
  155.     if(result < 0)  
  156.     {  
  157.         return result;  
  158.     }  
  159.   
  160.     sramdevp = kmalloc(sizeof(struct sram_dev),GFP_KERNEL);  
  161.     if(!sramdevp)  
  162.     {  
  163.         result = - ENOMEM;  
  164.         goto fail_malloc;  
  165.     }  
  166.   
  167.     memset(sramdevp,0,sizeof(struct sram_dev));  
  168.     //sram_setup_cdev(sramdevp,0);  
  169.       
  170.   
  171.     sramdevp->startAddr = SRAM0_PHYADDR;  
  172.     sramdevp->size = SRAM0_SIZE;  
  173.     ret = request_mem_region(SRAM0_PHYADDR, SRAM0_SIZE, "SRAM0 Region");  
  174.     if(ret==NULL)  
  175.     {  
  176.         printk("Request Memory Region Failed!\n");  
  177.         return -1;  
  178.     }  
  179.     sramdevp->mapPtr = ioremap(SRAM0_PHYADDR,SRAM0_SIZE);  
  180.     cdev_init(&sramdevp->cdev,&sram_fops);  
  181.     sramdevp->cdev.owner = THIS_MODULE;  
  182.     sramdevp->cdev.ops = &sram_fops;  
  183.     err = cdev_add(&sramdevp->cdev,devno,1);  
  184.   
  185.     if(err)  
  186.     {  
  187.         printk(KERN_NOTICE "Error %d adding SRAM%d",err,0);  
  188.     }  
  189.       
  190.     printk( "SRAM0_virt_addr = 0x%lx\n", (unsigned long)sramdevp->mapPtr );    
  191.     return 0;  
  192.   
  193.     fail_malloc:  
  194.         unregister_chrdev_region(dev,sramdevp);  
  195.         kfree(sramdevp);  
  196.     return result;  
  197.       
  198. }  
  199.   
  200. void sram_cleanup(void)  
  201. {  
  202.     cdev_del(&sramdevp->cdev);     
  203.     iounmap(sramdevp->mapPtr);  
  204.     kfree(sramdevp);  
  205.     unregister_chrdev_region(MKDEV(sram_major,0),1);    
  206. }  
  207.   
  208.   
  209.   
  210.   
  211. module_init(sram_init);  
  212. module_exit(sram_cleanup);  


 

写SRAM:

view plain
  1. #include<sys/types.h>  
  2. #include<sys/stat.h>  
  3. #include<fcntl.h>  
  4. #include<stdio.h>  
  5. #include<linux/fs.h>  
  6. #include<stdlib.h>  
  7. #include<unistd.h>  
  8. #define SRAM_DEV "/dev/SRAM0"  
  9. int main()  
  10. {  
  11.   int fd;  
  12.    char * data="ctrboss";  
  13.    fd=open(SRAM_DEV,O_WRONLY);  
  14. if(fd<0)  
  15. {  
  16.   printf("Unable to open sram device %s\n",SRAM_DEV);  
  17.   return 0;  
  18. }  
  19.   write(fd,data,sizeof(data));  
  20.   close(fd);  
  21.   return 1;  
  22. }   

读SRAM:

view plain
  1. #include<sys/types.h>  
  2. #include<sys/stat.h>  
  3. #include<fcntl.h>  
  4. #include<stdio.h>  
  5. #include<linux/fs.h>  
  6. #include<stdlib.h>  
  7. #include<unistd.h>  
  8. #define SRAM_DEV "/dev/SRAM0"  
  9. int main()  
  10. {  
  11.   int i,fd;  
  12.   char data[6];  
  13.   fd=open(SRAM_DEV,O_RDONLY);  
  14.   if(fd<0)  
  15.   {  
  16.    printf("Unable to open sram device %s\n",SRAM_DEV);  
  17.    return 0;  
  18.   }  
  19.   read(fd,data,sizeof(data));  
  20.   printf("data is %x\n",data[0]);  
  21.   printf("data is %x\n",data[1]);  
  22.   printf("data is %x\n",data[2]);  
  23.   printf("data is %x\n",data[3]);  
  24.   printf("data is %x\n",data[4]);  
  25.   printf("data is %x\n",data[5]);  
  26.     
  27.   printf("data is %c\n",data[0]);  
  28.   printf("data is %c\n",data[1]);  
  29.   printf("data is %c\n",data[2]);  
  30.   printf("data is %c\n",data[3]);  
  31.   printf("data is %c\n",data[4]);  
  32.   printf("data is %c\n",data[5]);     
  33.   
  34.   close(fd);  
  35.   return 1;  
  36. }    

原创粉丝点击