I'm*_*gon 23 c linux-device-driver linux-kernel embedded-linux
我正在研究编写嵌入式Linux驱动程序,并决定开发一些GPIO以确保我正确理解本书(LDD3,第9.4.1节).
我可以按照预期控制正确的GPIO引脚(使其高低,我用万用表探测); 但是,我测试了2个代码,一个有request_mem_region(),一个没有.我期待一个没有失败的人,但两个都工作得很好.
代码request_mem_region:
if( request_mem_region( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF,DEVICE_NAME ) == NULL )
{
printk( KERN_ALERT
"GPIO_140_141_conf_phys error:%s: unable to obtain I/O memory address 0x%08llX\n",
DEVICE_NAME, PIN3_CONF_PHYS );
return -EBUSY;
}
pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
//-----------------------------------------------------------------
if( request_mem_region( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5,DEVICE_NAME ) == NULL )
{
printk( KERN_ALERT
"error:%s: unable to obtain I/O memory address 0x%08llX\n",
DEVICE_NAME, GPIO_BANK5_PHYS );
return -EBUSY;
}
gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );
//some iowrite32() functions continue...
Run Code Online (Sandbox Code Playgroud)
代码没有request_mem_region():
pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );
//some iowrite32() functions continue...
Run Code Online (Sandbox Code Playgroud)
我可以从两种情况中看到的唯一区别是做a的结果,cat /proc/iomem带有request_mem_region()显示的附加线的结果49056000-49056097 : GPIO3.
我的问题是为什么request_mem_region()需要,因为我仍然只能与硬件地址通信ioremap()?那么我们什么时候才真正需要使用request_mem_region()?
谢谢你的回复!
Tho*_*oni 39
request_mem_region告诉内核你的驱动程序将使用这一系列的I/O地址,这将阻止其他驱动程序通过相同的区域进行任何重叠调用request_mem_region.这种机制不做任何类型的映射,它是一种纯粹的预留机制,它依赖于所有内核设备驱动程序必须很好的事实,它们必须调用request_mem_region,检查返回值,并在出现错误时正常运行.
所以你的代码没有工作是完全合乎逻辑的,request_mem_region只是它不符合内核编码规则.
但是,您的代码不符合内核编码风格.此外,还有一个现有的基础设施来处理GPIO,名为gpiolib,您应该使用它而不是手动重新映射GPIO bank寄存器.你在做哪个平台?
小智 7
现在已弃用在设备驱动程序中使用request_mem_region()and 。ioremap()您应该使用下面的“托管”函数,这可以简化驱动程序编码和错误处理:
devm_ioremap()
devm_iounmap()
devm_ioremap_resource(), Takes care of both the request and remapping operations
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24415 次 |
| 最近记录: |