Linux下SRAM的读写

9 篇文章 0 订阅
5 篇文章 0 订阅
 

项目中需要用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内核使用。

下面给出代码:

驱动程序:

#include <linux/module.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/gpio.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <asm/arch/hardware.h>
#include <asm/arch/gpio.h>
#include <asm/uaccess.h>
#include <linux/slab.h> /*for Kmalloc*/
#include <asm/io.h>/*for virt_to_phys*/
#include <asm/hardware.h>
#include <asm/arch/at91_pio.h>
#include <asm/arch/at91rm9200.h>/*for sram address and size*/

#define SRAM0_PHYADDR 0x300000
#define SRAM0_SIZE 0x1000  /*4K*/


int sram_major = 242;

int sram_open(struct inode *inode,struct file *filp);
int sram_release(struct inode *inode,struct file *filp);
int sram_release(struct inode *inode,struct file *filp);
ssize_t sram_read(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos);
ssize_t sram_write(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos);
//int sram_mmap(struct file *filp, struct vm_area_struct *vma );
//static void sram_setup_cdev(struct sram_dev *dev,int index);
int sram_init(void);
void sram_cleanup(void);


MODULE_AUTHOR("Cun Tian Rui");
MODULE_LICENSE("Dual BSD/GPL");


struct sram_dev
{
	struct cdev cdev;	
	unsigned long startAddr;
	unsigned long size;
	char *mapPtr;
}sram_dev;

struct sram_dev *sramdevp;

struct file_operations sram_fops = 
{
    .owner = THIS_MODULE,
   // .ioctl = sram_ioctl,
    .open  = sram_open,
    .release = sram_release,
    .read = sram_read,
    .write = sram_write,
   // .mmap = sram_mmap
};



int sram_open(struct inode *inode,struct file *filp)
{
    struct sram_dev *devp;
    devp = container_of(inode->i_cdev,struct sram_dev,cdev);
    filp->private_data = devp;
    
    return 0;
}

int sram_release(struct inode *inode,struct file *filp)
{
    return 0;    
}

ssize_t sram_read(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos)
{
	
	unsigned long p = *f_pos;
        struct sram_dev *devp = filp->private_data;
	printk("Driver read function running\n");
	printk("p is %d\n",p);
	 if (p >= devp->size)
  		return -EINVAL;
	 if (count > devp->size-p)
 		 count = devp->size-p;
	 printk("count is %d\n",count);
         if (copy_to_user(buf, devp->mapPtr+p,count))
  		return -EFAULT;
        *f_pos+= count;
 	return count;	 
} 

ssize_t sram_write(struct file *filp , char __user *buf ,size_t count,loff_t *f_pos)
{
	
        unsigned long p = *f_pos;
        printk("Driver write function running\n");
        printk("p is %d\n",p);
	struct sram_dev *devp = filp->private_data;
	if (p >= devp->size)
  		return -EINVAL;
 	if (count > devp->size-p)
  		count = devp->size-p;
        printk("count is %d\n",count);  
 	if (copy_from_user( devp->mapPtr+p,buf,count))
  		return -EFAULT;
 		*f_pos += count;
 	return count;
	
}
/*
int sram_mmap(struct file *filp, struct vm_area_struct *vma )
{
	unsigned long offset = vma->vm_pgoff<<PAGE_SHIFT; 
	unsigned long size = vma->vm_end - vma->vm_start; 

	if ( size > SRAM0_SIZE ) 
	{ 
		printk("size too big\n"); 
		return(-ENXIO); 
	} 

        offset = offset + SRAM0_PHYADDR; 
	
	vma->vm_flags |= VM_LOCKED; 
	if ( remap_pfn_range(vma,vma->vm_start,offset,size,PAGE_SHARED)) 
	{ 
		printk("remap page range failed\n"); 
		return -ENXIO; 
	} 

	return(0); 

}
*/

int sram_init(void)
{
    int result;
    int err,ret;
    int devno = MKDEV(sram_major,0);

    dev_t dev = MKDEV(sram_major,0);
    if(sram_major)
    {
        
        result = register_chrdev_region(dev,1,"SRAM0");
    }

    if(result < 0)
    {
        return result;
    }

    sramdevp = kmalloc(sizeof(struct sram_dev),GFP_KERNEL);
    if(!sramdevp)
    {
        result = - ENOMEM;
        goto fail_malloc;
    }

    memset(sramdevp,0,sizeof(struct sram_dev));
    //sram_setup_cdev(sramdevp,0);
    

    sramdevp->startAddr = SRAM0_PHYADDR;
    sramdevp->size = SRAM0_SIZE;
    ret = request_mem_region(SRAM0_PHYADDR, SRAM0_SIZE, "SRAM0 Region");
    if(ret==NULL)
	{
		printk("Request Memory Region Failed!\n");
		return -1;
	}
    sramdevp->mapPtr = ioremap(SRAM0_PHYADDR,SRAM0_SIZE);
    cdev_init(&sramdevp->cdev,&sram_fops);
    sramdevp->cdev.owner = THIS_MODULE;
    sramdevp->cdev.ops = &sram_fops;
    err = cdev_add(&sramdevp->cdev,devno,1);

    if(err)
    {
        printk(KERN_NOTICE "Error %d adding SRAM%d",err,0);
    }
    
    printk( "SRAM0_virt_addr = 0x%lx\n", (unsigned long)sramdevp->mapPtr );  
    return 0;

    fail_malloc:
		unregister_chrdev_region(dev,sramdevp);
		kfree(sramdevp);
    return result;
    
}

void sram_cleanup(void)
{
    cdev_del(&sramdevp->cdev);   
    iounmap(sramdevp->mapPtr);
    kfree(sramdevp);
    unregister_chrdev_region(MKDEV(sram_major,0),1);  
}




module_init(sram_init);
module_exit(sram_cleanup);


 

写SRAM:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<linux/fs.h>
#include<stdlib.h>
#include<unistd.h>
#define SRAM_DEV "/dev/SRAM0"
int main()
{
  int fd;
   char * data="ctrboss";
   fd=open(SRAM_DEV,O_WRONLY);
if(fd<0)
{
  printf("Unable to open sram device %s\n",SRAM_DEV);
  return 0;
}
  write(fd,data,sizeof(data));
  close(fd);
  return 1;
} 

读SRAM:

#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
#include<linux/fs.h>
#include<stdlib.h>
#include<unistd.h>
#define SRAM_DEV "/dev/SRAM0"
int main()
{
  int i,fd;
  char data[6];
  fd=open(SRAM_DEV,O_RDONLY);
  if(fd<0)
  {
   printf("Unable to open sram device %s\n",SRAM_DEV);
   return 0;
  }
  read(fd,data,sizeof(data));
  printf("data is %x\n",data[0]);
  printf("data is %x\n",data[1]);
  printf("data is %x\n",data[2]);
  printf("data is %x\n",data[3]);
  printf("data is %x\n",data[4]);
  printf("data is %x\n",data[5]);
  
  printf("data is %c\n",data[0]);
  printf("data is %c\n",data[1]);
  printf("data is %c\n",data[2]);
  printf("data is %c\n",data[3]);
  printf("data is %c\n",data[4]);
  printf("data is %c\n",data[5]);	

  close(fd);
  return 1;
}   


 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值