Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 只能从ioremap()内存中读取0_Linux_Linux Device Driver_Xilinx_Spi_Ioremap - Fatal编程技术网

Linux 只能从ioremap()内存中读取0

Linux 只能从ioremap()内存中读取0,linux,linux-device-driver,xilinx,spi,ioremap,Linux,Linux Device Driver,Xilinx,Spi,Ioremap,我正在为linux开发一个简单的驱动程序,它将通过SPI与设备通信。 在我使用request_mem_region和ioremap之后,我可以从返回的地址读取的所有内容都是0 即使我给它写了一个值。偏移量0处的地址应为SPI控制器的控制寄存器(它是Xilinx Zynq SoC)。控制寄存器在引导过程中设置为初始值 代码: int设备_init(){ int ret; ret=注册设备(设备专业、设备名称和fops); 如果(ret

我正在为linux开发一个简单的驱动程序,它将通过SPI与设备通信。 在我使用request_mem_region和ioremap之后,我可以从返回的地址读取的所有内容都是0 即使我给它写了一个值。偏移量0处的地址应为SPI控制器的控制寄存器(它是Xilinx Zynq SoC)。控制寄存器在引导过程中设置为初始值

代码:

int设备_init(){
int ret;
ret=注册设备(设备专业、设备名称和fops);
如果(ret<0){
printk(内核警报“spi:无法获取主编号%d.\n”,设备主编号);
返回ret;
}
if(请求内存区域(SPI地址,SPI大小,“SPI驱动程序”)==NULL)
{
printk(“请求内存区域失败!\n”);
设备_退出();
返回1;
}
spi=ioremap(spi地址、spi大小);
if(spi==NULL)
{
printk(“I/O重新映射失败\n”);
设备_退出();
返回1;
}
printk(“驱动程序初始化完成。映射到地址0x%X\n”,spi);
iowrite32be(0x20000,spi);
printk(“%X\n”,ioread32be(spi));
返回0;
}
插入模块时的输出为:
驱动初始化完成。映射到地址0xE08C2000
0


提前感谢您的帮助。

我想可能就是这个原因,所以我将在回答中说明。我对Xilinx一般都很熟悉,但对SPI核心不太熟悉。我只是看了一眼。第8页的表4汇总了寄存器。基址上没有寄存器。我不知道为什么内核会响应基址,但可能是硬编码为0

无论如何,在
ioremap()之后尝试以下操作:

void *ipier;

ipier = spi + 0x28;
printk("Driver init complete. Mapped to address 0x%X\n", spi);
iowrite32be(0x20000, ipier);
printk("%X\n", ioread32be(ipier));
当然,这是假设由于某种设置,IPIER寄存器没有从IP核心中删除


编辑:
根据Op下面的评论,Op没有使用SPI IP核心,因此这不是问题的答案。

您的问题不太清楚。。!!!请详细说明在上述代码中的
ioremap
步骤之后您想问的问题@jhonnash在使用ioremap()之后,我要做的是读取和写入映射的位置(物理地址0xE0007000-0xE0007FFF)。前4个字节应该有一个在引导期间设置的值,但我从该位置仅读取0,即使我先使用iowrite32写入它,然后尝试使用ioread32读取它。您是否验证了可以使用独立应用程序或XMD写入该寄存器?是的,我有一个裸机应用程序正在工作,我还让它在userspace的/dev/mem上使用mmap。您应该使用
ioremap\u nocache()。此外,我认为Xilinx设备大部分都是big-endian,因此您可能必须使用iowrite32be()。你能不能跟我开个玩笑,在printk()语句之前放一条iowrite32()语句,将其写入spi端口,然后在加载驱动程序后将dmesg的最后几行附加到问题上?谢谢你的回答,但这不是我正在使用的spi控制器。我使用的是集成在Zync XC7Z020 SoC寄存器中的SPI控制器概述,请参见:第1660页。偏移量0处的寄存器应该是配置寄存器。这是我回答以前从未使用过的硬件问题时得到的。不幸的是,我没有看到本文中提到的endian,所以我不能确定Zynq实际上是big-endian还是little-endian。看起来你试图设置第17位,我认为这是一个有效位。即使endianess是向后的,它也将是位9,这也是一个有效位。恐怕我在这件事上帮不了什么忙。在我看来,一切都很好。
void *ipier;

ipier = spi + 0x28;
printk("Driver init complete. Mapped to address 0x%X\n", spi);
iowrite32be(0x20000, ipier);
printk("%X\n", ioread32be(ipier));