亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 6235 | 回復(fù): 3
打印 上一主題 下一主題

linux驅(qū)動(dòng)中的mmap問(wèn)題 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2014-12-27 12:12 |只看該作者 |倒序?yàn)g覽
您好,我最近在寫Linux下的FPGA驅(qū)動(dòng)程序,想要實(shí)現(xiàn)ARM與FPGA通信,實(shí)現(xiàn)二者之間的數(shù)據(jù)和命令傳輸,ARM芯片的arm920T,arm與fpga之間通過(guò)總線連接,fpga相當(dāng)有掛接在arm片選nGCS2上的寄存器。對(duì)應(yīng)的物理地址為0x10000000
,在內(nèi)核空間,我已經(jīng)通過(guò)測(cè)試了,通過(guò)ioremap內(nèi)存映射,然后利用iowrite等函數(shù)可以對(duì)實(shí)現(xiàn)二者之間的數(shù)據(jù)傳輸。而現(xiàn)在我的問(wèn)題是:在用戶空間操作FPGA,我利用的是mmap函數(shù),通過(guò)系統(tǒng)調(diào)用,在用戶空間通過(guò)操作mmap返回的指針來(lái)實(shí)現(xiàn)通信,可是通過(guò)測(cè)試,發(fā)現(xiàn)數(shù)據(jù)沒(méi)有寫到FPGA中,應(yīng)該是地址出現(xiàn)問(wèn)題了,我有一個(gè)困惑:

如下是LDD3中一段
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
unsigned long physical = simple_region_start + off;
...........
remap_pfn_range(vma, vma_>vm_start, physical, vsize, vma->vm_page_prot);

這里的remap_pfn_range中的第三個(gè)參數(shù)不是pfn頁(yè)幀號(hào)嗎?為啥是物理地址,對(duì)于這個(gè)參數(shù)我一直沒(méi)弄清楚,如果我操作物理設(shè)備,那么這里的pfn 該怎么寫,比如我的物理地址是physical    0x10000000  那么Pfn =physical>> PAGE_SHIFT ,是這樣嗎?
下面是我的驅(qū)動(dòng)程序以及測(cè)試程序,希望大家?guī)臀豢纯矗x謝啦




//s3c2440_fpga.c
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/signal.h>
#include <asm-generic/siginfo.h>
#include <asm/irq.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/hardware.h>
#include <mach/regs-irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>  
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/irqreturn.h>
#include <linux/irqnr.h>
#include <linux/hardirq.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include<linux/mm_types.h>
#include<linux/cdev.h>
#include<linux/io.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>


#define DEVICE_NAME        "FPGA"  
#define FPGA_MAJOR         240  
#define FPGA_ADDR        0x10000000 //物理地址0x10000000 ~  0x18000000   

#define FPGA_NR_DEVS 1
#define FPGA_DEVS_SIZE   4096
#define FPGA_ADDR_SIZE  1024//申請(qǐng)IO內(nèi)存的大小


#define GPACON    (0x56000000)
#define BWSCON    (0x48000000)
#define BANKCON2  (0x4800000C)

static volatile unsigned long *gpacon_addr;
static volatile unsigned long *bwscon_addr;
static volatile unsigned long *bankcon2_addr;
//static volatile unsigned long *FPGA_BASE;
static void __iomem *FPGA_BASE;

static unsigned long reg;
unsigned int ret = 0;
struct cdev cdev;



/************open***************/
static int fpga_open(struct inode *inode, struct file *file)
{
      printk("virt_addr = 0x%lx\n",(unsigned long)FPGA_BASE);
      printk("FPGA opened\n";   
      return 0;
}

/************read***************/
static ssize_t fpga_read(struct file *file, char __user *buffer, size_t size, loff_t *ppos)
{
       reg=readl(FPGA_BASE+24);
       printk("0x%lx\n",reg);
       return ret;

}
/************write***************/
static ssize_t fpga_write(struct file *file,const char __user *buffer, size_t size, loff_t *ppos)
{

        iowrite16(0x456, FPGA_BASE+0x00000030);
       //writel(0x456, FPGA_BASE+12);
        return ret;
}



static struct file_operations s3c2440_fpga_fops = {
          .owner = THIS_MODULE,
          .read  =fpga_read,
          .write =fpga_write,
          .open  =fpga_open,
};

static int __init s3c2440_fpga_init(void)
{
          int ret;
          struct resource *fpga_res;
          ret = register_chrdev(FPGA_MAJOR,DEVICE_NAME,& s3c2440_fpga_fops);
           if (ret < 0) {
              printk(DEVICE_NAME " can't register major number\n";
              return ret;
          }

/**************************** 申請(qǐng)I/O內(nèi)存 *******************************/
         fpga_res=request_mem_region(FPGA_ADDR,FPGA_ADDR_SIZE,DEVICE_NAME);
          if(fpga_res==NULL)
          {
            printk("request io memery fail\n";
            ret =-EINVAL;
            goto fail_request_mem;
         }
//×××××××××××××××××××I/O內(nèi)存映物理地址映射到虛擬地址××××××××××××××××××××××××××××××××//
         FPGA_BASE=(volatile unsigned long *)ioremap(FPGA_ADDR,FPGA_ADDR_SIZE);
          if(!FPGA_BASE)
           {
           printk("remap address fail\n";
           ret = -ENOMEM;
           goto fail_ioremap;

           }

//×××××××××××××××××××配置I/O寄存器設(shè)置時(shí)序和位寬以及片選nGCS2××××××××××××××××××××××××××××××//
         gpacon_addr=(volatile unsigned long *)ioremap_nocache(GPACON,0x0000004);
         bwscon_addr=(volatile unsigned long *)ioremap_nocache(BWSCON,0x0000004);
         bankcon2_addr=(volatile unsigned long *)ioremap_nocache(BANKCON2,0x0000004);     
     
         writel( readl(gpacon_addr)|(0x01<<13),gpacon_addr);
         writel( (readl(bwscon_addr)&~(0xF<<)|(0XE<<,bwscon_addr);
         writel( (readl(bankcon2_addr)&~(0x8003)),bankcon2_addr);
         writel( (readl(bankcon2_addr)&~(0x03)),bankcon2_addr);
        
         /*cdev結(jié)構(gòu)分配,注冊(cè),初始化,與linux內(nèi)核之間傳參數(shù),涉內(nèi)*/
         cdev_init(&cdev, &s3c2440_fpga_fops);
         cdev.owner = THIS_MODULE;
         cdev.ops = &s3c2440_fpga_fops;
         cdev_add(&cdev,MKDEV(FPGA_MAJOR,0), FPGA_NR_DEVS);//注冊(cè)字符設(shè)備
         return 0;

        fail_request_mem:unregister_chrdev_region(MKDEV(FPGA_MAJOR,0),FPGA_NR_DEVS);
                          return ret;
        fail_ioremap: release_mem_region(FPGA_ADDR,FPGA_ADDR_SIZE); //釋放IO內(nèi)存
                     unregister_chrdev_region(MKDEV(FPGA_MAJOR,0), FPGA_NR_DEVS);
                     return ret;
}

static void __exit s3c2440_fpga_exit(void)
{
        unregister_chrdev(FPGA_MAJOR, DEVICE_NAME);
        iounmap(FPGA_BASE);
        iounmap(gpacon_addr);
        iounmap(bwscon_addr);
        iounmap(bankcon2_addr);
        release_mem_region(FPGA_ADDR,FPGA_ADDR_SIZE); //釋放IO內(nèi)存   
        cdev_del(&cdev);

}

MODULE_LICENSE("GPL";
module_init(s3c2440_fpga_init);
module_exit(s3c2440_fpga_exit);



//fpga_test.c

#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/mman.h>
#include<string.h>
#define FPGA_Address 0x10000000
#define SIZE (100)
typedef struct  
{
  unsigned long   r_MemUnit1[65536];  //32位無(wú)符號(hào)數(shù)據(jù)     Total Size:1MB Address Space
}MEMUNIT;
int main(void)
    {        
        int fd,i;
        MEMUNIT record, *addrs;
        char *buf="butterfly!";
        fd = open("/dev/FPGA",O_RDWR);
        if(fd == -1)
        {
            printf("Error!!\n";
            exit(-1);
        }
       // addrs =( MEMUNIT *)mmap(NULL,SIZE* sizeof(record),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
        addrs =( MEMUNIT *)mmap(NULL,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
        if(addrs==MAP_FAILED)
        {
          printf("mmap error!!!\n";
          exit(-1);
        }
        addrs->r_MemUnit1[12]=12;
        msync((void *)addrs,4096, MS_ASYNC);
        printf("addrs[12]:0x%lx\n",addrs);
        printf("addrs[12]:0x%lx\n",addrs->r_MemUnit1[0]);
        printf("addrs[12]:0x%lx\n",addrs->r_MemUnit1[1]);
        printf("addrs[12]:0x%lx\n",addrs->r_MemUnit1[2]);
        printf("addrs[12]:0x%x\n",addrs->r_MemUnit1[12]);
      /*  while(1)
        {
         read(fd,buf,3);
        }*/
        munmap((void *)addrs,4096);
        close(fd);
        exit(0);

}

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2014-12-28 16:34 |只看該作者
難道大家都沒(méi)寫過(guò)類似的程序嗎?我只想實(shí)現(xiàn)在用戶空間操作設(shè)備,給FPGA發(fā)送命令以及接收從FPGA端FIFO傳過(guò)來(lái)的數(shù)據(jù),希望有人可以幫我解答一下,mmap映射后,直接操作地址指針就可以操作FPGA嗎?那么讀寫信號(hào),片選信號(hào),怎么控制,)  

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2015-01-26 14:33 |只看該作者
個(gè)人認(rèn)為,對(duì)于FPGA的讀寫操作可以通過(guò)該FPGA的文件句柄來(lái)進(jìn)行操作,控制的話需要在該驅(qū)動(dòng)中添加關(guān)于IOCTL控制代碼,這樣才能夠?qū)崿F(xiàn)控制操作。

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2015-03-18 15:46 |只看該作者
你在用戶空間調(diào)用了mmap但是的驅(qū)動(dòng)里面卻沒(méi)有實(shí)現(xiàn)mmap接口???請(qǐng)仔細(xì)看下內(nèi)核里面的代碼
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP