|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
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 |
|