在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!)    创芯人才网--重磅上线啦!
查看: 7545|回复: 13

[原创] 求助:我自己写的arm9与FPGA之间的驱动,怎么也调不好。来大侠帮忙看看啊

[复制链接]
发表于 2011-3-20 11:35:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/devfs_fs_kernel.h>
#include "FPGAdev.h"
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_ts_dir, devfs_tsraw;
#endif

const char FPGA_NAME[] ="fpgadrv";   //定义模块名
static int test_major = 0;

unsigned char *fpga_sendvbuf_addr;
unsigned char *fpga_readvbuf_addr;
int maxreadsize =1024;
int maxsendsize = 1024;
int send_num=0;
typedef struct fpgainfo
{
char flagr;
char flagw;
        char flags;
unsigned char memsend[1024];
unsigned char memread[1024];
}fpgainfo_t;
fpgainfo_t  *datastruct;
/* virtual address */
AT91PS_SYS sys = (AT91PS_SYS) AT91C_VA_BASE_SYS;
static int fpga_open(struct inode *inode, struct file *file);
static int fpga_release(struct inode *inode, struct file *file);
static int fpga_read(struct file *file, char *buf, size_t len, loff_t *f_pos);
static int fpga_write(struct file *file,const char *buf, size_t count, loff_t *f_pos);
static struct file_operations fpga_fops =
{
        open       : fpga_open,
        read        : fpga_read,
        write : fpga_write,
        release   : fpga_release,
};

static int fpga_read(struct file *file, char *buf,size_t len, loff_t *fpga_fops)
{
              printk("program has enter read\n");
               memcpy_fromio(datastruct->memread,fpga_readvbuf_addr,maxreadsize);
           printk("datastruct->memread : %s\n",datastruct->memread);   
        datastruct->flagr = 1;
    printk("memcpy_fromio is over\n");
      if(copy_to_user(buf,datastruct->memread,len))
        {
         printk("copy to user error.\n");
         return -EFAULT;
        }
        printk("copy_to_user over : %s\n", buf);
       datastruct->flagr=0;
memset(datastruct->memread,0,sizeof(datastruct->memread));
        return len;

}
static int fpga_write(struct file *file, const char *buf, size_t count, loff_t *fpga_fops)
{
          printk("program has enter write\n");
        datastruct->flags=0;
            if(copy_from_user(datastruct->memsend,buf,count))
                {
              printk("copy from user error.\n");
              return -EFAULT;
                }
if(count==maxsendsize)   
  {
   send_num = 1024;
   datastruct->flagw=0;
  }
        memcpy_toio(fpga_sendvbuf_addr,datastruct->memsend,send_num);
     datastruct->flagw=1;
       memset(datastruct->memsend,0,sizeof(datastruct->memsend));
          send_num=0;

return count;
}

static int fpga_open(struct inode *inode, struct file *file)
{
printk("program has enter open\n");
datastruct=(fpgainfo_t*)kmalloc(sizeof(fpgainfo_t),GFP_KERNEL);
if(datastruct!=NULL) memset(datastruct,0,sizeof(fpgainfo_t));
else
  {
   printk("cannot allocate datastruct .\n");
   return -ENOMEM;
  }

fpga_sendvbuf_addr = (unsigned char*)ioremap(0x30000400,maxsendsize);
fpga_readvbuf_addr = (unsigned char*)ioremap(0x30000800,maxreadsize);

printk("ioremap is over : %s\n", fpga_readvbuf_addr);

MOD_INC_USE_COUNT;
printk("open fpga is over\n");
return(0);
}

static int fpga_release(struct inode *inode, struct file *file)
{
printk("program has enter release\n");
    MOD_DEC_USE_COUNT;
    kfree(datastruct);

  iounmap(fpga_sendvbuf_addr);
iounmap(fpga_readvbuf_addr);
return(0);
}
static int __init fpga_init(void)
{
int ret;
printk("program has enter init\n");
sys->EBI_SMC2_CSR[2] = 0x12003182;
      
   ret = register_chrdev(0, FPGA_NAME, &fpga_fops);
if (ret < 0)
   {
    printk("can't register fpga major number\n");
    return ret;
   }
if(test_major==0)
test_major =ret;

#ifdef CONFIG_DEVFS_FS
devfs_ts_dir = devfs_mk_dir(NULL, FPGA_NAME, NULL);
devfs_tsraw = devfs_register(devfs_ts_dir, "0", DEVFS_FL_DEFAULT,test_major, 0, S_IFCHR | S_IRUSR | S_IWUSR,&fpga_fops, NULL);
#endif
printk("register fpga device OK!\n");
return 0;
}

static void __exit fpga_exit(void)
{
printk("program has enter exit\n");
#ifdef CONFIG_DFVFS_FS
devfs_remove("/dev/fpgadrv/0");
#endif
  printk("fpga is used\n");
  unregister_chrdev(test_major,FPGA_NAME);
  printk("fpga exit!");
}
module_init(fpga_init);
module_exit(fpga_exit);
MODULE_LICENSE("GPL");
-----------------------------------------------------------上面是源码------------------------------------------------------
没有中断,只是简单的读写功能,fpga里面 先写了一个小的验证电路,很简单,就是给它一个地址,它就发出一个数来验证read功能。然后在测试程序里面调用read,但就是出不来预先设定的数。。。FPGA片选信号 为 2,arm用的是 ATMEL 的9200
 楼主| 发表于 2011-3-20 11:36:37 | 显示全部楼层
[root@AT91RM9200DK /root]$chmod 777 test_drv
[root@AT91RM9200DK /root]$./test_drv
0000000ioremap is over : open fpga is over000000000
datastruct->memread : 


2222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222222222222222222222memcpy_fromio is
over
Unable to handle kernel NULL pointer dereference at virtual address 00000001
mm = c0015220 pgd = c1610000
*pgd = 20a66801, *pmd = 20a66801, *pte = 00000000, *ppte = 00000000
Internal error: Oops: 0
CPU: 0
pc : [<c0133734>]    lr : [<c01343bc>]    Not tainted
sp : c11ebed4  ip : c11ebee4  fp : c11ebee0
r10: 00000000  r9 : c11ebf58  r8 : ffffffff
r7 : c0168764  r6 : 60000013  r5 : 00000001  r4 : c0168750
r3 : c014b6e0  r2 : 00000001  r1 : fffffffe  r0 : 00000001
Flags: Nzcv  IRQs off  FIQs on  Mode SVC_32  Segment user
Control: C000317F  Table: 21610000  DAC: 00000015
Process test_drv (pid: 122, stack limit = 0xc11ea374)
Stack: (0xc11ebed4 to 0xc11ec000)
bec0:                                              c11ebf2c c11ebee4 c01343bc
bee0: c0133728 c0027150 00002227 c11ebf14 fffffbeb c0168b4f 00000400 c0168750
bf00: c2811599 c0168750 bffffd18 60000013 00000000 bffffd18 c11ea000 4012fae8
bf20: c11ebf4c c11ebf30 c0027440 c0133fd8 00000000 bffffd18 00000003 00000000
bf40: c11ebf78 c11ebf60 c2811100 c00273e8 c2811584 00000001 00000003 00000001
bf60: 00000003 c1182640 ffffffea c11ebfa4 c11ebf7c c00476f8 c281105c c0024138
bf80: c0156040 bffffda4 00000001 4000c380 00000003 c001c684 00000000 c11ebfa8
bfa0: c001c4e0 c004762c bffffda4 c0023e18 00000003 bffffd18 00000003 bffffd18
bfc0: bffffda4 00000001 4000c380 00008328 00008624 0000849c 4012fae8 bffffd68
bfe0: 400dc1f0 bffffd14 00008558 400dc1f4 20000010 00000003 9a7a5a1d 54f4b43b
Backtrace:
Function entered at [<c0133718>] from [<c01343bc>]
Function entered at [<c0133fc8>] from [<c0027440>]
Function entered at [<c00273d4>] from [<c2811100>]
r3 = 00000001  r2 = 00000003  r1 = 00000001  r0 = C2811584
r7 = 00000000  r6 = 00000003  r5 = BFFFFD18  r4 = 00000000
Function entered at [<c281104c>] from [<c00476f8>]
r6 = FFFFFFEA  r5 = C1182640  r4 = 00000003
Function entered at [<c004761c>] from [<c001c4e0>]
r8 = C001C684  r7 = 00000003  r6 = 4000C380  r5 = 00000001
r4 = BFFFFDA4
Code: e1a02000 e2411001 e3710001 0a000009 (e5d23000)
Segmentation fault
 楼主| 发表于 2011-3-20 11:39:45 | 显示全部楼层
这个是 运行后的信息。。。。。。。有没有大侠来帮帮忙啊 。。。。郁闷了好几天了,连个最简单的读写功能都调不出来。。。还不知道错在哪里。。。。或者有没有大侠给 指点一下 怎么调试驱动。我只会用printk。。
 楼主| 发表于 2011-3-20 11:49:17 | 显示全部楼层
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
//#include <memory.h>



int main(void)
{
       
          int i;

        int read_from_fpga[16];  
int fdfpga;
      
      for(i=0;i<16;i++)
        {
        read_from_fpga[i]=0;
        printf("%d",read_from_fpga[i]);
        }
      printf("\n");


        if((fdfpga=open("/dev/fpgadrv/0",O_RDWR))==-1)
        {
                printf("open fpgadrv error\n");
                return -1;
        }
        if(read(fdfpga,read_from_fpga,3)==-1)
        {
          printf("read error\n");
          }
    for(i=0; i<16; i++)   printf("%d",read_from_fpga[i]);
        close(fdfpga);
        return 0;
}
这个是我的测试代码。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
发表于 2011-3-25 11:31:20 | 显示全部楼层
一般这种问题,难说,因为跨平台东西,应该把方案说一下。
发表于 2011-4-13 15:37:49 | 显示全部楼层
ccccfff
发表于 2011-4-15 13:55:05 | 显示全部楼层
很厉害啊。看不懂。
发表于 2011-4-15 15:34:15 | 显示全部楼层
回复 8# cxs2002


    路过
发表于 2012-1-10 09:28:01 | 显示全部楼层
发表于 2012-1-10 10:21:38 | 显示全部楼层
帮顶帮顶
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-16 13:48 , Processed in 0.038142 second(s), 10 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表