首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 驱动开发 >

请问:linux下DMA操作,死机

2012-03-24 
请教:linux下DMA操作,死机简介:采用DMA控制器实现s3c2440与外部FPGA通信,以FIFO为桥梁。以字符型设备的方式

请教:linux下DMA操作,死机
简介:采用DMA控制器实现s3c2440与外部FPGA通信,以FIFO为桥梁。
以字符型设备的方式编写DMA驱动程序(驱动程序如下),驱动成功挂载,应用程序也能成功运行,但是执行应用程序后ARM会死机,无法进行任何操作(现象如下);
问题:请问为什么会死机,一般linux开发时导致死机的原因有哪些?小弟比较急,谢谢回复!
现象:
[root@FriendlyARM plg]# ./dma_app

。(省略)

hello buff
[root@FriendlyARM plg]# (在此处死机,无法进行任何操作)

驱动程序:#include <linux/module.h>  
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h> //copy_to_use, copy_from_user  
#include <linux/serial_core.h>  
//#include <asm/plat-s3c/regs-serial.h>  
#include <asm/io.h> //readl, readb, writel, writeb 
#include <asm-arm/s3c2440-dma.h>
//#include <plat/dma-plat.h>
#include <mach/map.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <plat/regs-dma.h>
#include <linux/device.h>

#define XDREQ0_MAJOR 239
#define XDREQ0_MINOR 0
#define dma_base S3C2410_VA_DMA
#define DMA_DISRC0 (dma_base+S3C2410_DMA_DISRC)
#define DMA_DISRCC0 (dma_base+S3C2410_DMA_DISRCC)
#define DMA_DIDST0 (dma_base+S3C2410_DMA_DIDST)
#define DMA_DIDSTC0 (dma_base+S3C2410_DMA_DIDSTC)
#define DMA_DCON0 (dma_base+S3C2410_DMA_DCON)
#define DMA_DSTAT0 (dma_base+S3C2410_DMA_DSTAT)
#define DMA_DCSRC0 (dma_base+S3C2410_DMA_DCSRC)
#define DMA_DCDST0 (dma_base+S3C2410_DMA_DCDST)
#define DMA_DMASKTRIG (dma_base+S3C2410_DMA_DMASKTRIG)

#define mydma_channel 0
#define dma_devaddr 0x55000010

MODULE_AUTHOR("hankle");  
MODULE_DESCRIPTION("s3c2440 dma driver");  
MODULE_LICENSE("GPL"); 
struct device *my_cdev;
struct class *my_class;
/*open*/
int fifo_dma_open(struct inode * inode,struct file * filp)
{
  printk("dma is open\n");
  //MOD_INC_USE_COUNT;
  return 0;
}
int fifo_dma_release(struct inode * inode,struct file * filp)
{
  printk("dma is released!\n");
  //MOD_DEC_USE_COUNT;
  //s3c2410_free_dma(mydma_channel);
  //writel(((0<<1)+0),DMA_DMASKTRIG);
  return 0;
}
/*interrupt */
/*static void dma_irq_handler(int irq, void *dev_id,struct pt_regs *regs)
{
  printk(KERN_ALERT"interrupt generated!\n");
  dma_done = 1;
}
*/

void regs_init(unsigned int dstaddr,unsigned int srcaddr)
{
  unsigned int a,b,c,d;
  writel(srcaddr,DMA_DISRC0);
  writel(((1<<1)+0),DMA_DISRCC0);
  writel(dstaddr,DMA_DIDST0);
  writel( 0 ,DMA_DIDSTC0);
  writel(((0<<31)|(0<<30)|(0<<29)|(0<<28)|(0<<27)|(0<<24)|(1<<23)|(1<<22)|(1<<20)|(640)),DMA_DCON0);  
  a = readl(DMA_DISRC0);
  b = readl(DMA_DISRCC0);
  c = readl(DMA_DIDST0);
  d = readl(DMA_DIDSTC0);
  //printk(KERN_ALERT"DISRC0 is %x,DISRCC0 is %x,DIDIST0 is %x,DIDSTC0 is %x \n",a,b,c,d);
}

ssize_t fifo_dma_read(struct file *filp, char *buff,size_t count,loff_t *f_ops)
{
  printk("fifo_dma_read start\n");
  dma_addr_t *dma_buf_virt;
  unsigned int dma_buf_phy;
  dma_buf_virt = kmalloc(count,GFP_DMA);
  dma_buf_phy = virt_to_bus(dma_buf_virt);
  printk(KERN_ALERT"distbuf address is %lx \n",dma_buf_phy);
  regs_init(dma_buf_phy,0);


  writel(((1<<1)+0),DMA_DMASKTRIG);
  if(copy_to_user(buff,dma_buf_virt,count)<0)
  {
printk("copy_to_user failed\n");
  return -EFAULT;
  }
  else printk("copy_to_user successed!");
  kfree(dma_buf_virt);
  return count;
}
struct file_operations XDREQ0_fops ={
  .owner = THIS_MODULE,
  .open = fifo_dma_open,
  .read = fifo_dma_read,
  .release = fifo_dma_release,
};
static int __init fifo_dma_init(void)
{
  int result;
  result = register_chrdev(XDREQ0_MAJOR,"XDREQ0",&XDREQ0_fops);
 if(result<0)
  { printk("error register device XDREQ0");
  return -1;
  }

  my_class = class_create(THIS_MODULE,"my_class");
  if(IS_ERR(my_class)) {
  printk("Err: failed in creating class.\n");
  return -1;
  }
  device_create(my_class,NULL,MKDEV(XDREQ0_MAJOR,0),NULL,"XDREQ0");
  return 0;  
}
void __exit fifo_dma_exit(void)  
{  

  device_destroy(my_class,MKDEV(XDREQ0_MAJOR,XDREQ0_MINOR));
  class_destroy(my_class);

  unregister_chrdev(XDREQ0_MAJOR,"XDREQ0");
  //free_irq(IRQ_DMA0,dma_irq_handler);
  writel(((0<<1)+0),DMA_DMASKTRIG);
  printk("serial module exit!/n");  

module_init(fifo_dma_init);
module_exit(fifo_dma_exit);

应用程序:
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#define DATASIZE 128
int main(/*int argc, char* argv[]*/)
{
  printf("1111\n");
  int fd,ret;
  char buff[DATASIZE];
  fd = open("/dev/XDREQ0",O_RDWR);
  if(fd<0)
  {printf("open failed\n");
  return 1;
  }
  else
  printf("read buff start\n");
  memset(buff,0,sizeof(buff));
  printf("DATASIZE is %d ",DATASIZE);
  ret= read(fd,buff,DATASIZE);
  if(ret<0)
  {printf("read failed\n");
return 2;
}
  else
  printf("read buff successed\n");
  if(buff[1] != '\0')
  {printf("%s\n",buff);
  printf("hello buff \n");
}
  else
  printf("buff is 0\n");
return 0;
}


[解决办法]
是那一句死机?
你先定位下,可以用打印语句看看,找到死机的地方就好办了

热点排行