佚名通过本文主要向大家介绍了am335x gpmc,am335x adc驱动,am335x驱动开发,am335x驱动目录,am335x led驱动等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: 关于AM335x上GPMC驱动程序的问题
描述:
就是我写的FPGA_gpmc驱动程序,,加载后没有问题,但是当应用程序调用read函数的时候,就会出现系统碰亏的情况,终端显示如下:

驱动详细代码见附件
#include <linux/init.h>
....
#include "asm/atomic.h"
#define USER_BUFF_SIZE 128
struct fpga_dev {
dev_t devt;
struct cdev cdev;
struct semaphore sem;
struct class *class;
char *user_buff;
unsigned int addr;
unsigned int data;
};
static struct fpga_dev fpga_dev;
unsigned long mem_base;
static void __iomem *fpga_base;
static void __iomem *gpmc_base;
/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
#define GPMC_IRQSTATUS 0x18
#define GPMC_IRQENABLE 0x1C
#define GPMC_TIMEOUT_CONTROL 0x40
#define GPMC_ERR_ADDRESS 0x44
#define GPMC_ERR_TYPE 0x48
#define GPMC_CONFIG 0x50
#define GPMC_STATUS 0x54
#define GPMC_PREFETCH_CONFIG1 0x1E0
#define GPMC_PREFETCH_CONFIG2 0x1E4
#define GPMC_PREFETCH_CONTROL 0x1EC
#define GPMC_PREFETCH_STATUS 0x1F0
#define GPMC_ECC_CONFIG 0x1F4
#define GPMC_ECC_CONTROL 0x1F8
#define GPMC_ECC_SIZE_CONFIG 0x1FC
#define GPMC_ECC1_RESULT 0x200
#define GPMC_ECC_BCH_RESULT_0 0x240
#define GPMC_BASE_ADDR 0x50000000
#define GPMC_CS 2
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
#define STNOR_GPMC_CONFIG1 0x28601000
#define STNOR_GPMC_CONFIG2 0x00011001
#define STNOR_GPMC_CONFIG3 0x00020201
#define STNOR_GPMC_CONFIG4 0x08031003
#define STNOR_GPMC_CONFIG5 0x000F1111
#define STNOR_GPMC_CONFIG6 0x0F030080
static const u32 gpmc_nor[7] = {
STNOR_GPMC_CONFIG1,
STNOR_GPMC_CONFIG2,
STNOR_GPMC_CONFIG3,
STNOR_GPMC_CONFIG4,
STNOR_GPMC_CONFIG5,
STNOR_GPMC_CONFIG6,
0
};
int fpga_ioctl(struct file *flip,unsigned int cmd,unsigned int arg)
{
ssize_t status;
char write_buff[]="the gpmc driver is OK!";
switch(cmd)
{
case 0:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
fpga_dev.addr=arg;
printk("*******write address is 0x%x********\n",fpga_dev.addr);
//up(&fpga_dev.sem);
break;
case 1:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
fpga_dev.data=arg;
printk("*******write data is 0x%x********\n",fpga_dev.data);
//up(&fpga_dev.sem);
break;
default:
return ENOTTY;
}
read_done_xd:
{
printk("ioctl done!\n\r");
up(&fpga_dev.sem);
}
return status;
}
static ssize_t fpga_write(struct file *flip,const char __user *buff,size_t count,loff_t *f_pos)
{
ssize_t status;
size_t len = USER_BUFF_SIZE - 1;
int i,tmp;
if(count == 0)
return 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if(len > count)
len = count;
memset(fpga_dev.user_buff,0,USER_BUFF_SIZE);
if(copy_from_user(fpga_dev.user_buff,buff,len))
{
status = -EFAULT;
goto fpga_write_done;
}
/* do something with the user data */
printk("fpga_write\n");
int address = 0;
address = fpga_base+fpga_dev.addr;
tmp = fpga_dev.data;
writew(tmp,address);
printk("address = 0x%x,data=0x%x\n ",address,tmp);
fpga_write_done:
up(&fpga_dev.sem);
return status;
}
static ssize_t fpga_read(struct file *flip,char __user *buff,size_t count,loff_t *offp)
{
ssize_t status;
size_t len = USER_BUFF_SIZE - 1;
int tmp;
if(count == 0)
return 0;
if(*offp > 0)
return 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
// strcpy(fpga_dev.user_buff,"fpga driver data goes here\n");
// len = strlen(fpga_dev.user_buff);
if(len > count)
len = count;
memset(fpga_dev.user_buff,0,USER_BUFF_SIZE);
printk("**********before readb********\n");
tmp = readw(fpga_base+fpga_dev.addr);
printk("fpga_read_data = 0x%x\n",tmp);
if(copy_to_user(buff,fpga_dev.user_buff,len))
{
status = -EFAULT;
goto fpga_read_done;
}
fpga_read_done:
printk("fpga_read_done_xd\n");
up(&fpga_dev.sem);
return status;
}
static int fpga_open(struct inode *inode,struct file *flip)
{
int status = 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if(!fpga_dev.user_buff)
{
fpga_dev.user_buff = kmalloc(USER_BUFF_SIZE,GFP_KERNEL);
if(!fpga_dev.user_buff)
{
printk(KERN_ALERT "fpga_open:user_buff alloc failed\n");
status = -ENOMEM;
}
}
up(&fpga_dev.sem);
return status;
}
static const struct file_operations fpga_fops = {
.owner = THIS_MODULE,
.open = fpga_open,
.read = fpga_read,
.write = fpga_write,
.unlocked_ioctl = fpga_ioctl,
};
static int __init fpga_init_cdev(void)
{
int error;
u32 val;
fpga_dev.devt = MKDEV(251,0);
error = alloc_chrdev_region(&fpga_dev.devt,0,1,"fpga");
if(error){
printk(KERN_ALERT "alloc_chrdev_region() failed:%d\n",error);
return error;
}
cdev_init(&fpga_dev.cdev,&fpga_fops);
fpga_dev.cdev.owner = THIS_MODULE;
error = cdev_add(&fpga_dev.cdev,fpga_dev.devt,1);
if(error){
printk(KERN_ALERT "cdev_add() failed:%d\n",error);
unregister_chrdev_region(fpga_dev.devt,1);
return error;
}
printk("Getting Chip Select\n");
//close CS//////////////////////
val=gpmc_cs_read_reg(GPMC_CS,GPMC_CS_CONFIG7);
val &= ~GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(GPMC_CS,GPMC_CS_CONFIG7,val);
////////////////////////////////
val = gpmc_read_reg(GPMC_REVISION);
printk(KERN_ALERT "GPMC revision %d.%d\n",(val>>4)&0x0f,val&0x0f);
gpmc_write_reg(GPMC_IRQENABLE,0);<
描述:
kernel调试终端应用程序
你好,最精调试GPMC的时候出现了一个问题,想请教一下:就是我写的FPGA_gpmc驱动程序,,加载后没有问题,但是当应用程序调用read函数的时候,就会出现系统碰亏的情况,终端显示如下:

驱动详细代码见附件
#include <linux/init.h>
....
#include "asm/atomic.h"
#define USER_BUFF_SIZE 128
struct fpga_dev {
dev_t devt;
struct cdev cdev;
struct semaphore sem;
struct class *class;
char *user_buff;
unsigned int addr;
unsigned int data;
};
static struct fpga_dev fpga_dev;
unsigned long mem_base;
static void __iomem *fpga_base;
static void __iomem *gpmc_base;
/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
#define GPMC_IRQSTATUS 0x18
#define GPMC_IRQENABLE 0x1C
#define GPMC_TIMEOUT_CONTROL 0x40
#define GPMC_ERR_ADDRESS 0x44
#define GPMC_ERR_TYPE 0x48
#define GPMC_CONFIG 0x50
#define GPMC_STATUS 0x54
#define GPMC_PREFETCH_CONFIG1 0x1E0
#define GPMC_PREFETCH_CONFIG2 0x1E4
#define GPMC_PREFETCH_CONTROL 0x1EC
#define GPMC_PREFETCH_STATUS 0x1F0
#define GPMC_ECC_CONFIG 0x1F4
#define GPMC_ECC_CONTROL 0x1F8
#define GPMC_ECC_SIZE_CONFIG 0x1FC
#define GPMC_ECC1_RESULT 0x200
#define GPMC_ECC_BCH_RESULT_0 0x240
#define GPMC_BASE_ADDR 0x50000000
#define GPMC_CS 2
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
#define STNOR_GPMC_CONFIG1 0x28601000
#define STNOR_GPMC_CONFIG2 0x00011001
#define STNOR_GPMC_CONFIG3 0x00020201
#define STNOR_GPMC_CONFIG4 0x08031003
#define STNOR_GPMC_CONFIG5 0x000F1111
#define STNOR_GPMC_CONFIG6 0x0F030080
static const u32 gpmc_nor[7] = {
STNOR_GPMC_CONFIG1,
STNOR_GPMC_CONFIG2,
STNOR_GPMC_CONFIG3,
STNOR_GPMC_CONFIG4,
STNOR_GPMC_CONFIG5,
STNOR_GPMC_CONFIG6,
0
};
int fpga_ioctl(struct file *flip,unsigned int cmd,unsigned int arg)
{
ssize_t status;
char write_buff[]="the gpmc driver is OK!";
switch(cmd)
{
case 0:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
fpga_dev.addr=arg;
printk("*******write address is 0x%x********\n",fpga_dev.addr);
//up(&fpga_dev.sem);
break;
case 1:
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
fpga_dev.data=arg;
printk("*******write data is 0x%x********\n",fpga_dev.data);
//up(&fpga_dev.sem);
break;
default:
return ENOTTY;
}
read_done_xd:
{
printk("ioctl done!\n\r");
up(&fpga_dev.sem);
}
return status;
}
static ssize_t fpga_write(struct file *flip,const char __user *buff,size_t count,loff_t *f_pos)
{
ssize_t status;
size_t len = USER_BUFF_SIZE - 1;
int i,tmp;
if(count == 0)
return 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if(len > count)
len = count;
memset(fpga_dev.user_buff,0,USER_BUFF_SIZE);
if(copy_from_user(fpga_dev.user_buff,buff,len))
{
status = -EFAULT;
goto fpga_write_done;
}
/* do something with the user data */
printk("fpga_write\n");
int address = 0;
address = fpga_base+fpga_dev.addr;
tmp = fpga_dev.data;
writew(tmp,address);
printk("address = 0x%x,data=0x%x\n ",address,tmp);
fpga_write_done:
up(&fpga_dev.sem);
return status;
}
static ssize_t fpga_read(struct file *flip,char __user *buff,size_t count,loff_t *offp)
{
ssize_t status;
size_t len = USER_BUFF_SIZE - 1;
int tmp;
if(count == 0)
return 0;
if(*offp > 0)
return 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
// strcpy(fpga_dev.user_buff,"fpga driver data goes here\n");
// len = strlen(fpga_dev.user_buff);
if(len > count)
len = count;
memset(fpga_dev.user_buff,0,USER_BUFF_SIZE);
printk("**********before readb********\n");
tmp = readw(fpga_base+fpga_dev.addr);
printk("fpga_read_data = 0x%x\n",tmp);
if(copy_to_user(buff,fpga_dev.user_buff,len))
{
status = -EFAULT;
goto fpga_read_done;
}
fpga_read_done:
printk("fpga_read_done_xd\n");
up(&fpga_dev.sem);
return status;
}
static int fpga_open(struct inode *inode,struct file *flip)
{
int status = 0;
if(down_interruptible(&fpga_dev.sem))
return -ERESTARTSYS;
if(!fpga_dev.user_buff)
{
fpga_dev.user_buff = kmalloc(USER_BUFF_SIZE,GFP_KERNEL);
if(!fpga_dev.user_buff)
{
printk(KERN_ALERT "fpga_open:user_buff alloc failed\n");
status = -ENOMEM;
}
}
up(&fpga_dev.sem);
return status;
}
static const struct file_operations fpga_fops = {
.owner = THIS_MODULE,
.open = fpga_open,
.read = fpga_read,
.write = fpga_write,
.unlocked_ioctl = fpga_ioctl,
};
static int __init fpga_init_cdev(void)
{
int error;
u32 val;
fpga_dev.devt = MKDEV(251,0);
error = alloc_chrdev_region(&fpga_dev.devt,0,1,"fpga");
if(error){
printk(KERN_ALERT "alloc_chrdev_region() failed:%d\n",error);
return error;
}
cdev_init(&fpga_dev.cdev,&fpga_fops);
fpga_dev.cdev.owner = THIS_MODULE;
error = cdev_add(&fpga_dev.cdev,fpga_dev.devt,1);
if(error){
printk(KERN_ALERT "cdev_add() failed:%d\n",error);
unregister_chrdev_region(fpga_dev.devt,1);
return error;
}
printk("Getting Chip Select\n");
//close CS//////////////////////
val=gpmc_cs_read_reg(GPMC_CS,GPMC_CS_CONFIG7);
val &= ~GPMC_CONFIG7_CSVALID;
gpmc_cs_write_reg(GPMC_CS,GPMC_CS_CONFIG7,val);
////////////////////////////////
val = gpmc_read_reg(GPMC_REVISION);
printk(KERN_ALERT "GPMC revision %d.%d\n",(val>>4)&0x0f,val&0x0f);
gpmc_write_reg(GPMC_IRQENABLE,0);<