dma_map_single
是 Linux 内核中用于将单个内存缓冲区映射到 DMA 设备的函数。它用于确保内存可以被 DMA 访问,并返回一个可以在硬件设备上使用的物理地址。
以下是一个使用 dma_map_single
的简单驱动示例:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
struct my_device {
struct device *dev;
void *cpu_addr; // CPU可访问地址
dma_addr_t dma_addr; // DMA可访问地址
};
static int my_probe(struct platform_device *pdev) {
struct my_device *my_dev;
// 分配设备结构体
my_dev = devm_kzalloc(&pdev->dev, sizeof(*my_dev), GFP_KERNEL);
if (!my_dev)
return -ENOMEM;
// 获取设备结构体指针
my_dev->dev = &pdev->dev;
// 分配DMA内存
my_dev->cpu_addr = dma_alloc_coherent(my_dev->dev, PAGE_SIZE,
&my_dev->dma_addr, GFP_KERNEL);
if (!my_dev->cpu_addr) {
dev_err(my_dev->dev, "Failed to allocate coherent memory\n");
return -ENOMEM;
}
printk(KERN_INFO "Allocated DMA memory at CPU address: %p and physical address: %pad\n",
my_dev->cpu_addr, &my_dev->dma_addr);
// 其他初始化代码...
return 0;
}
static int my_remove(struct platform_device *pdev) {
struct my_device *my_dev = platform_get_drvdata(pdev);
// 释放DMA内存
dma_free_coherent(my_dev->dev, PAGE_SIZE, my_dev->cpu_addr,
my_dev->dma_addr);
return 0;
}
static const struct of_device_id my_of_match[] = {
{ .compatible = "example,my-device", },
{},
};
MODULE_DEVICE_TABLE(of, my_of_match);
static struct platform_driver my_driver = {
.driver = {
.name = "my_driver",
.of_match_table = my_of_match,
},
.probe = my_probe,
.remove = my_remove,
};
module_platform_driver(my_driver);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple example of using dma_map_single");
示例解释
设备结构体:定义了一个
my_device
结构,包含了设备指针和分配的内存相关信息。Probe 函数:在驱动加载时调用,分配了用于 DMA 的一致性内存:
- 使用
dma_alloc_coherent
来分配一段与设备兼容的内存。 - 打印出分配的 CPU 地址和相应的物理地址。
- 使用
Remove 函数:当驱动卸载时调用,负责释放之前分配的内存。
Platform Driver 注册:注册平台驱动并提供 probe 和 remove 函数。
请根据你的具体硬件环境进行适当调整。这是一个简化的示例,实际使用中可能还需要考虑更多错误处理和特定条件。
内容由零声教学AI助手提供,问题来源于学员提问