下面是一个示例,展示了如何使用 dma_alloc_coherent
分配内存并进行读写操作。在这个示例中,我们将为一个假设的设备分配 DMA 一致性内存,然后执行一些简单的读写操作。
示例代码
#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 *buf; // 用于保存DMA缓冲区指针
dma_addr_t dma_handle; // DMA地址
};
static struct my_device *dev;
static int __init my_driver_init(void)
{
// 分配并初始化设备结构
dev = kmalloc(sizeof(struct my_device), GFP_KERNEL);
if (!dev) {
pr_err("Failed to allocate device structure\n");
return -ENOMEM;
}
// 分配DMA一致性内存
dev->buf = dma_alloc_coherent(NULL, 1024, &dev->dma_handle, GFP_KERNEL);
if (!dev->buf) {
pr_err("Failed to allocate coherent DMA memory\n");
kfree(dev);
return -ENOMEM;
}
pr_info("Allocated coherent DMA memory at address: %p\n", dev->buf);
// 写入数据到DMA缓冲区
memset(dev->buf, 0, 1024); // 清空缓冲区
for (int i = 0; i < 256; i++) {
((int *)dev->buf)[i] = i; // 向缓冲区写入数据
}
pr_info("Data written to DMA buffer:\n");
for (int i = 0; i < 10; i++) { // 打印前10个值作为示例
pr_info("%d ", ((int *)dev->buf)[i]);
}
pr_info("\n");
return 0;
}
static void __exit my_driver_exit(void)
{
// 打印读取的数据(可选)
if (dev && dev->buf) {
pr_info("Data read from DMA buffer:\n");
for (int i = 0; i < 10; i++) {
pr_info("%d ", ((int *)dev->buf)[i]);
}
// 释放DMA一致性内存
dma_free_coherent(NULL, 1024, dev->buf, dev->dma_handle);
pr_info("Freed coherent DMA memory\n");
}
kfree(dev);
}
module_init(my_driver_init);
module_exit(my_driver_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Example of using dma_alloc_coherent with read/write operations");
MODULE_AUTHOR("Your Name");
使用说明
模块初始化:
- 我们首先分配了一个设备结构体,并通过
dma_alloc_coherent()
分配了一块大小为1024字节的连续内存。 - 然后使用
memset
清空该内存区域,以确保没有残留数据。 - 接着,向这块内存中写入了一些整数(从0到255)作为示例。
- 我们首先分配了一个设备结构体,并通过
数据打印:
- 在写入数据后,我们打印了前10个值,以确认数据已经正确地写入到DMA缓冲区。
模块退出:
- 在
my_driver_exit()
中,我们也可以选择打印这些数据来确认它们在驱动卸载时依然存在(在某些场景下会需要)。 - 最后,调用
dma_free_coherent()
来释放之前分配的DMA一致性内存。
- 在
注意事项
- 请确保你的模块具有适当的权限和上下文,这样才能正确访问硬件资源。
- 本代码仅用于演示,实际开发时要根据具体情况处理错误和边界条件。
- 确保对共享资源进行适当的同步,以避免竞争条件。
内容由零声教学AI助手提供,问题来源于学员提问