我有一个数组和一个变量,声明如下
NextPacketRegister : array (1 .. Natural (Size)) of Unsigned_32;
PacketBufferPointer : Unsigned_32;
for PacketBufferPointer'Address use To_Address (SPW_PORT_0_OUT_REG_ADDR);
for NextPacketRegister'Address use To_Address (16#A000_0000# + Integer_Address (PacketBufferPointer));PacketBufferPointer指向硬件寄存器,您可以通过我们主板的PCI访问该寄存器。NextPacketRegister使用此寄存器的值+ 16#A000_0000#
问题是,每次我访问NextPacketRegister时,我都会在后台执行PCI访问,这些访问非常慢,我们正在努力消除这种限制。
但是我似乎找不到一种在运行时修改NextPacketRegister的地址的方法(我想读取一次PacketBufferPointer寄存器,然后只将这个值+ 16#A000_0000#添加一次,这样我就不必每次都执行PCI访问。
我环顾四周,但我不知道如何才能做到这一点。
发布于 2010-11-02 22:17:53
这是正确的;如果您使用for ...'address use覆盖特定地址处的对象,则以后无法更改它。
一般来说,我会尽量避免重叠。你所展示的对他们来说是一个缺点。另一种是,如果对象有任何需要初始化的部分,它们将在每次对象细化时重新初始化。
不过,有一件事我必须事先问一问:这看起来像一个设备驱动程序。如果你不喜欢访问PCI总线的结果,那也没问题。当然,解决问题的明显方法是将对象读取到一个临时变量中,并在不想访问PCI总线时使用它。但很明显,当您这样做时,您不再直接从设备读取数据,因此看不到它对其内存映射寄存器所做的更改(并且您的更改不会直接传递到这些内存映射寄存器)。这就是你想要的,对吧?Ada不包含允许您在不命中PCI总线的情况下将数据进出PCI总线的魔术。
看起来你好像在想这一行:
for NextPacketRegister'Address use To_Address (16#A000_0000# + Integer_Address (PacketBufferPointer));
意思是:“每次我访问NextPacketRegister时,找到PacketBufferPointer的值并将其覆盖到它现在所在的位置”。事实并非如此。当你的声明被处理时,这只会发生一次。此后,每次访问类似NextPacketRegister[12]的内容都将转到同一位置,而不访问任何PacketBufferPointer。
另一种方法是使用指针和Unchecked_Conversion。这通常是我首选的覆盖解决方案。它看起来毛发更多,但你正在做的是毛发,所以它应该看起来是这样的。而且,它不会对覆盖的内存区执行初始化。我想这可能是一件坏事,如果你指望这些的话。当然,如果您愿意,以这种方式覆盖可能会导致对PacketBufferPointer的访问。你可以根据你的编码方式来控制它。
既然您问到了指针,在这种情况下,我认为您有一个非常有效的用例来使用包System.Address_to_Access_Conversions。我手头没有编译器,但我认为它应该是这样的:
type Next_Packet_Array is array (1 .. Natural (Size)) of Unsigned_32;
package Next_Packet_Array_Convert is new System.Address_To_Access_Conversions
(Next_Packet_Array);
Synced_Next_Packet_Address : System.Address;现在,当你“同步”的时候,我猜你会想要点击那个PacketBufferPointer来获得寄存器值(作为一个SYSTEM.ADDRESS),并将它保存到一个变量中以备后用:
Synced_Next_Packet_Address = 16#A000_0000# + Integer_Address (PacketBufferPointer);当您想要访问Next_Packet_Array时,应该是这样的:Next_Packet_Array_Convert.To_Pointer (Synced_Next_Packet_Address).all
发布于 2010-11-08 08:55:09
创建一个结构(缓冲区数组?)这就是您的数据包缓冲区集的外观,并将其放在数组开始处的地址。
从寄存器中读取数组索引。
你可以用任何语言写C,甚至是Ada。
至少它可以工作,并且你得到了一些合理的边界检查。
https://stackoverflow.com/questions/4078462
复制相似问题