因此,当涉及到内核驱动程序时,我完全是新手,我有一个关于ioremap函数的问题。
我正在编写一个驱动程序,用于访问定义在带有ARM、Cortex-M3和FPGA结构的SoC上的自定义VHDL-模块中的一些寄存器。看一下示例,我想我应该使用ioremap,但是由于Cortex-M3没有MMU,所以我并不真正理解其中的意义,如下例所示:
/* Physical addresses */
static u32* rcu_trig_recv_physaddr = ((u32 *) 0x50040000);
static int rcu_trig_recv_size = 0x10; // size of 16 for testing
/* Virtual addresses */
static u32* rcu_trig_recv_virtbase = NULL;
/*removed code not relevant for the question*/
static int __init rcumodule_init(void)
{
int iResult = 0; // holding result of operations
u32 buffer;
// Register the driver
iResult = register_chrdev(rcuc_majorID, "rcuc", &rcuc_fops);
if (iResult < 0) {
printk(KERN_INFO "module init: can't register driver\n");
}
else{
printk(KERN_INFO "module init: success!\n");
}
// Map physical address to virtual address
if(rcu_trig_recv_size){
rcu_trig_recv_virtbase = (u32*) ioremap_nocache( (u32 *)rcu_trig_recv_physaddr, rcu_trig_recv_size );
printk("Remapped TRGRECV from 0x%p to 0x%p\n", rcu_trig_recv_physaddr, rcu_trig_recv_virtbase);
}
// try to read some stuff, expecting 0x17240f09
buffer = readl(rcu_trig_recv_virtbase);
printk("read %lx, at 0x%p\n", buffer, rcu_trig_recv_virtbase);
return iResult;
}然后,当我让司机感到不舒服的时候,这个就回来了:
# insmod trigger.ko
module init: success!
Remapped TRGRECV from 0x50040000 to 0x50040000
read 17240f09, at 0x50040000根据这一点,我最好还是读一下物理地址。或者这是个坏主意,我应该用更好的方式处理我的录音机吗?
发布于 2014-07-14 22:49:58
如果您知道您的代码永远不需要在另一个设备上使用,那么您就有可能摆脱这种情况,但是坚持使用ioremap()要安全得多。将代码建立在获取和使用内存映射IO提供的指针的基础上,将使您的代码比使用硬编码的物理地址更易于移植和维护。
即使您不打算将此代码带到另一台设备上,只要简单地升级到同一行较新的芯片,使用物理地址也可能会破坏您的代码。
https://stackoverflow.com/questions/20442663
复制相似问题