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