树莓派GPIO上下拉配置代码移植到Linux内核时如何替换mmap功能
解决方案
内核态访问物理GPIO寄存器不需要复用用户态的mmap+/dev/mem逻辑,内核提供了专门的物理地址映射接口ioremap,直接替换即可:
- 新增必要头文件
引入ioremap/iounmap对应的头文件:
#include <linux/io.h>
- 重写
getBase函数
删除原有的filp_open打开/dev/mem、调用mmap的逻辑,直接映射物理寄存器地址:
static volatile uint32_t *getBase(uint32_t reg_base) { // 映射4KB大小的GPIO寄存器物理地址到内核虚拟地址空间 return (volatile uint32_t *)ioremap(reg_base, 0x1000); }
你之前查到的int (*mmap) (struct file *filp, struct vm_area_struct *vma)是Linux内核文件操作结构体struct file_operations里的回调函数,是驱动开发时用于给用户态程序提供mmap访问能力的接口,和你当前需要在内核态直接映射物理地址的场景无关,不需要使用。
3. 补充地址释放逻辑
内核虚拟地址使用完毕后需要主动释放,避免资源泄漏,修改setGpioPull函数:
static int setGpioPull(uint32_t gpio, int pull) { bool error; uint32_t reg_base; volatile uint32_t *base; reg_base = getGpioRegBase(&error); if (error) return -1; base = getBase(reg_base); if (base == NULL) return -1; setPull(base, gpio, pull); // 释放映射的内核虚拟地址 iounmap(base); return 0; }
内容的提问来源于stack exchange,提问作者miranda1000
相关产品推荐
相关产品推荐

