ZBLOG

dma_alloc_contiguous驱动接口的使用示例

dma_alloc_contiguous 是一个用于在 Linux 内核中分配连续 DMA 物理内存的接口。它主要用于设备驱动程序,以确保为设备分配的内存是物理上连续的,从而满足某些硬件对内存地址的要求。

下面是 dma_alloc_contiguous 的使用示例,适用于 Linux 驱动开发。

示例代码

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>

struct my_device {
    void *virt_addr;       // 虚拟地址
    dma_addr_t phys_addr;  // 物理地址
    size_t size;           // 分配大小
};

static struct my_device *my_dev;

static int __init my_driver_init(void) {
    // 分配设备结构体
    my_dev = kmalloc(sizeof(struct my_device), GFP_KERNEL);
    if (!my_dev) {
        pr_err("Failed to allocate memory for device structure\n");
        return -ENOMEM;
    }

    // 设置要分配的DMA缓冲区大小(例如:1MB)
    my_dev->size = 1024 * 1024;

    // 分配连续DMA内存
    my_dev->virt_addr = dma_alloc_coherent(NULL, my_dev->size,
                                            &my_dev->phys_addr,
                                            GFP_KERNEL);
    
    if (!my_dev->virt_addr) {
        pr_err("Failed to allocate DMA coherent memory\n");
        kfree(my_dev);
        return -ENOMEM;
    }

    pr_info("Allocated %zu bytes of DMA memory at virtual address: %p, physical address: %pad\n",
            my_dev->size, my_dev->virt_addr, &my_dev->phys_addr);

    return 0;
}

static void __exit my_driver_exit(void) {
    if (my_dev && my_dev->virt_addr) {
        // 释放DMA内存
        dma_free_coherent(NULL, my_dev->size,
                          my_dev->virt_addr,
                          my_dev->phys_addr);
        
        pr_info("Freed DMA memory\n");
    }
    
    kfree(my_dev);
}

module_init(my_driver_init);
module_exit(my_driver_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A simple example of using dma_alloc_coherent");
MODULE_AUTHOR("Your Name");

代码说明

  1. 包含必要的头文件:包括了所需的库,例如 module.hdma-mapping.h

  2. 定义设备结构体:包含虚拟地址、物理地址和分配大小等信息。

  3. 初始化函数 (my_driver_init)

    • 首先分配设备结构体。
    • 然后设置要分配的DMA缓冲区大小。
    • 使用 dma_alloc_coherent() 函数申请连续的DMA内存,并获取其虚拟地址和物理地址。如果失败,则清理并返回错误。
  4. 退出函数 (my_driver_exit)

    • 在模块卸载时,释放已分配的DMA内存和设备结构体。
  5. 模块宏:使用 module_init()module_exit() 宏来指定模块的入口和出口点。

注意事项

  • 确保在你的系统上编译这个模块时,相关驱动框架已经正确安装。
  • 上述代码中的 NULL 参数传递给 dma_alloc_coherent() 表示没有特定于设备上下文。在实际情况中,应该传入与硬件相关的信息,例如相应的设备结构指针。
  • 请根据具体需求调整缓冲区大小和其它参数。这只是一个基本示例,用于展示如何调用这个接口。


    内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=6267

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?