当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    详解linux dma驱动编写

    栏目:win服务器问题汇总 时间:2019-11-06 23:52

    linux下面的驱动虽然什么样的情形都有,但是dma驱动却并不少见。dma可以有很多的好处,其中最重要的功能就是能够帮助我们将数据搬来搬去,这个时候cpu就由时间去做别的事情了,提高了设备效率。

    1、dma驱动在什么地方

    drivers/dma 

    2、如何看s3c的dma驱动,先看Kconfig

    config S3C24XX_DMAC 
      bool "Samsung S3C24XX DMA support" 
      depends on ARCH_S3C24XX || COMPILE_TEST 
      select DMA_ENGINE 
      select DMA_VIRTUAL_CHANNELS 
      help 
       Support for the Samsung S3C24XX DMA controller driver. The 
       DMA controller is having multiple DMA channels which can be 
       configured for different peripherals like audio, UART, SPI. 
       The DMA controller can transfer data from memory to peripheral, 
       periphal to memory, periphal to periphal and memory to memory. 
    

    3、发现s3c只依赖于S3C24XX_DMAC,这样可以接着看Makefile

    obj-$(CONFIG_S3C24XX_DMAC) += s3c24xx-dma.o 

    4、确认驱动文件为s3c24xx-dma.c,了解基本结构

    static struct platform_driver s3c24xx_dma_driver = { 
      .driver   = { 
        .name  = "s3c24xx-dma", 
      }, 
      .id_table  = s3c24xx_dma_driver_ids, 
      .probe   = s3c24xx_dma_probe, 
      .remove   = s3c24xx_dma_remove, 
    }; 
     
    module_platform_driver(s3c24xx_dma_driver); 
    

    5、驱动为基本的platform driver,接着就可以了解probe函数了

    /* Initialize memcpy engine */ 
    dma_cap_set(DMA_MEMCPY, s3cdma->memcpy.cap_mask); 
    dma_cap_set(DMA_PRIVATE, s3cdma->memcpy.cap_mask); 
    s3cdma->memcpy.dev = &pdev->dev; 
    s3cdma->memcpy.device_free_chan_resources = 
            s3c24xx_dma_free_chan_resources; 
    s3cdma->memcpy.device_prep_dma_memcpy = s3c24xx_dma_prep_memcpy; 
    s3cdma->memcpy.device_tx_status = s3c24xx_dma_tx_status; 
    s3cdma->memcpy.device_issue_pending = s3c24xx_dma_issue_pending; 
    s3cdma->memcpy.device_config = s3c24xx_dma_set_runtime_config; 
    s3cdma->memcpy.device_terminate_all = s3c24xx_dma_terminate_all; 
    s3cdma->memcpy.device_synchronize = s3c24xx_dma_synchronize; 
     
    /* Initialize slave engine for SoC internal dedicated peripherals */ 
    dma_cap_set(DMA_SLAVE, s3cdma->slave.cap_mask); 
    dma_cap_set(DMA_CYCLIC, s3cdma->slave.cap_mask); 
    dma_cap_set(DMA_PRIVATE, s3cdma->slave.cap_mask); 
    s3cdma->slave.dev = &pdev->dev; 
    s3cdma->slave.device_free_chan_resources = 
            s3c24xx_dma_free_chan_resources; 
    s3cdma->slave.device_tx_status = s3c24xx_dma_tx_status; 
    s3cdma->slave.device_issue_pending = s3c24xx_dma_issue_pending; 
    s3cdma->slave.device_prep_slave_sg = s3c24xx_dma_prep_slave_sg; 
    s3cdma->slave.device_prep_dma_cyclic = s3c24xx_dma_prep_dma_cyclic; 
    s3cdma->slave.device_config = s3c24xx_dma_set_runtime_config; 
    s3cdma->slave.device_terminate_all = s3c24xx_dma_terminate_all; 
    s3cdma->slave.device_synchronize = s3c24xx_dma_synchronize; 
    s3cdma->slave.filter.map = pdata->slave_map; 
    s3cdma->slave.filter.mapcnt = pdata->slavecnt; 
    s3cdma->slave.filter.fn = s3c24xx_dma_filter;