• dma 测试例子



    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/sched.h>
    #include <linux/mman.h>
    #include <linux/init.h>
    #include <linux/dma-mapping.h>
    #include <linux/fs.h>
    #include <linux/version.h>
    #include <linux/delay.h>
    #include <mach/dma.h>

    #include <linux/dmaengine.h>
    #include <linux/device.h>

    #include <linux/io.h>
    #include <linux/delay.h>

    static int gMajor; /* major number of device */
    static struct class *dma_tm_class;
    u32 *wbuf, *wbuf2, *wbuf3;
    u32 *rbuf, *rbuf2, *rbuf3;
    u32 *rxbuf,*txbuf;
    struct dma_chan *dma_m2m_chan_rx,*dma_m2m_chan_tx;

    struct completion dma_m2m_ok;

    struct scatterlist sg_rx[1],sg_tx[1],sg[3], sg2[3];

    #define SDMA_BUF_SIZE  1024



    static bool dma_m2m_filter(struct dma_chan *chan, void *param)
    {
            if (!imx_dma_is_general_purpose(chan))
                    {
            printk("I ################# ");
                    return false;
            }
            chan->private = param;
            return true;
    }
    static void dma_m2m_callback(void *data)
    {
            printk("in %s ",__func__);
            complete(&dma_m2m_ok);
            return ;
    }
    static int imx_fpga_dma_init()
    {

            dma_cap_mask_t dma_m2m_mask;
            struct imx_dma_data m2m_dma_data = {0};
            struct dma_slave_config dma_m2m_config;
            init_completion(&dma_m2m_ok);

            dma_cap_zero(dma_m2m_mask);
            dma_cap_set(DMA_SLAVE, dma_m2m_mask);
            m2m_dma_data.peripheral_type = IMX_DMATYPE_EXT;
            m2m_dma_data.priority = DMA_PRIO_HIGH;

            dma_m2m_chan_rx = dma_request_channel(dma_m2m_mask, dma_m2m_filter, &m2m_dma_data);
            dma_m2m_config.direction = DMA_FROM_DEVICE;
            dma_m2m_config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
           dma_m2m_config.src_addr =0x74000000;
            dmaengine_slave_config(dma_m2m_chan_rx, &dma_m2m_config);
            rxbuf=kzalloc(SDMA_BUF_SIZE, GFP_DMA);
            /* tx*/
            dma_m2m_chan_tx = dma_request_channel(dma_m2m_mask, dma_m2m_filter, &m2m_dma_data);
            dma_m2m_config.direction = DMA_TO_DEVICE;
            dma_m2m_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
            dma_m2m_config.dst_addr =0x74000000;
            dmaengine_slave_config(dma_m2m_chan_tx, &dma_m2m_config);
            
            txbuf=kzalloc(SDMA_BUF_SIZE, GFP_DMA);

    }
    static int start_rx_dma()
    {
            int ret;
            struct dma_async_tx_descriptor *desc;
            sg_init_table(sg_rx, 1);
            sg_set_buf(&sg_rx[0],rxbuf,SDMA_BUF_SIZE);
            ret = dma_map_sg(NULL, sg_rx, 1, DMA_FROM_DEVICE);
            if (ret == 0) {
                    pr_err("DMA mapping error for RX. ");
                    return -EINVAL;
            }
            desc = dma_m2m_chan_rx->device->device_prep_slave_sg(dma_m2m_chan_rx,
                                    sg_rx, 1, DMA_FROM_DEVICE, 0);
            if (!desc) {
                    pr_err("We cannot prepare for the RX slave dma! ");
                    return -EINVAL;
            }
            desc->callback = dma_m2m_callback;
            dmaengine_submit(desc);

            dmaengine_submit(desc);
            dma_unmap_sg(NULL, sg_rx, 1, DMA_FROM_DEVICE);
            return 0;
    }
    static int start_tx_dma()
    {
            int ret;
            struct dma_async_tx_descriptor *desc;
            memset(txbuf,0x33,SDMA_BUF_SIZE);
            sg_init_table(sg_tx, 1);
            sg_set_buf(&sg_tx[0],txbuf,SDMA_BUF_SIZE);
            ret = dma_map_sg(NULL, sg_tx, 1, DMA_TO_DEVICE);
            desc = dma_m2m_chan_tx->device->device_prep_slave_sg(dma_m2m_chan_tx,
                                    sg_tx, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT| DMA_COMPL_SKIP_DEST_UNMAP);
            if (!desc) {
                    pr_err("We cannot prepare for the tX slave dma! ");
                    return -EINVAL;
            }
            desc->callback = dma_m2m_callback;
            dmaengine_submit(desc);

            dmaengine_submit(desc);
            dma_unmap_sg(NULL, sg_tx, 1, DMA_TO_DEVICE);
            
            return 0;
    }

    int sdma_open(struct inode * inode, struct file * filp)
    {        
             imx_fpga_dma_init();
          
            return 0;
    }

    int sdma_release(struct inode * inode, struct file * filp)
    {
            dma_release_channel(dma_m2m_chan_rx);
            dma_m2m_chan_rx = NULL;
            dma_release_channel(dma_m2m_chan_tx);
            dma_m2m_chan_tx = NULL;
    /*        kfree(wbuf);
            kfree(wbuf2);
            kfree(wbuf3);
            kfree(rbuf);
            kfree(rbuf2);
            kfree(rbuf3);*/
            return 0;
    }

    ssize_t sdma_read (struct file *filp, char __user * buf, size_t count,
                                                                    loff_t * offset)
    {
            //start_rx_dma();
       
            return 0;
    }



    ssize_t sdma_write(struct file * filp, const char __user * buf, size_t count,
                                                                    loff_t * offset)
    {
            start_tx_dma();
          
            return 0;
    }

    struct file_operations dma_fops = {
            open:                sdma_open,
            release:        sdma_release,
            read:                sdma_read,
            write:                sdma_write,
    };

    int __init sdma_init_module(void)
    {
    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
            struct device *temp_class;
    #else
            struct class_device *temp_class;
    #endif
            int error;

            /* register a character device */
            error = register_chrdev(0, "sdma_test", &dma_fops);
            if (error < 0) {
                    printk("SDMA test driver can't get major number ");
                    return error;
            }
            gMajor = error;
            printk("SDMA test major number = %d ",gMajor);

            dma_tm_class = class_create(THIS_MODULE, "sdma_test");
            if (IS_ERR(dma_tm_class)) {
                    printk(KERN_ERR "Error creating sdma test module class. ");
                    unregister_chrdev(gMajor, "sdma_test");
                    return PTR_ERR(dma_tm_class);
            }

    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
            temp_class = device_create(dma_tm_class, NULL,
                                       MKDEV(gMajor, 0), NULL, "sdma_test");
    #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
            temp_class = device_create(dma_tm_class, NULL,
                                       MKDEV(gMajor, 0), "sdma_test");
    #else
            temp_class = class_device_create(dma_tm_class, NULL,
                                                 MKDEV(gMajor, 0), NULL,
                                                 "sdma_test");
    #endif
            if (IS_ERR(temp_class)) {
                    printk(KERN_ERR "Error creating sdma test class device. ");
                    class_destroy(dma_tm_class);
                    unregister_chrdev(gMajor, "sdma_test");
                    return -1;
            }

            printk("SDMA test Driver Module loaded ");
            return 0;
    }

    static void sdma_cleanup_module(void)
    {
            unregister_chrdev(gMajor, "sdma_test");
    #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
            device_destroy(dma_tm_class, MKDEV(gMajor, 0));
    #else
            class_device_destroy(dma_tm_class, MKDEV(gMajor, 0));
    #endif
            class_destroy(dma_tm_class);

            printk("SDMA test Driver Module Unloaded ");
    }


    module_init(sdma_init_module);
    module_exit(sdma_cleanup_module);

    MODULE_AUTHOR("Freescale Semiconductor");
    MODULE_DESCRIPTION("SDMA test driver");
    MODULE_LICENSE("GPL");

  • 相关阅读:
    SpringBoot项目启动遇到的问题记录
    关于点击按钮提交前进行数据校验
    idea插件的位置
    sqlite
    xamarin.forms 使用依赖注入
    vs2019查找替换,使用正则表达式功能
    EFCore 事务提交
    windows磁盘【文件和文件夹遇到-打不开or不能删除or损坏】的解决方式
    xamarin.forms 中使用Forms9Patch插件来显示图片遇到的问题
    net5 依赖注入的时候,遇到的问题:Cannot consume scoped service from singleton IHostedService
  • 原文地址:https://www.cnblogs.com/zym0805/p/7661182.html
Copyright © 2020-2023  润新知