简体   繁体   中英

Mapping chunk of shared memory for reading/writing in Ada

I have a chunk (1024 bytes) of shared memory between two processes for which I have an address pointing to. I want to copy some data to this shared memory, and read it on the other process. Coming from a C background, it seems easiest to map a record to this address, and then write to the record, but it does not seem to be copying correctly.

Currently, I am trying to convert the pointer to a pointer-to-record type using an Unchecked Conversion, and copy to the record, but I am seeing differences in the data when I compare the original payload with the one received in the second process.

Is this the proper way of doing this?:

type Payload_Array_Type is array (1..255) of Integer_32;

type Common_Buffer_Type is
  record
    Size : Integer_32;
    Payload : Payload_Array_Type;
  end record;

type Common_Buffer_Ptr_Type is access Common_Buffer_Type;

function Convert_Common_Memory_Ptr is new Unchecked_Conversion (
    Source => System.Address,
    Target => Common_Buffer_Ptr_Type);

Common_Memory_Ptr : System.Address;

procedure Copy_To_Common_Buffer
(
    Size : Integer_32;
    Payload : Payload_Array_Type
) is
    Common_Buffer_Ptr : Common_Buffer_Ptr_Type;
begin
    Common_Buffer_Ptr := Convert_Common_Memory_Ptr(Common_Memory_Ptr);
    Common_Buffer_Ptr.Size := Size;
    Common_Buffer_Ptr.Payload(1..255) := Payload(1..255);    
end Copy_To_Common_Buffer;

I would try to do it this way:

procedure Payload is 

   type Payload_Array_Type is array (1..255) of Integer_32;

   type Common_Buffer_Type is record
      Size : Integer_32;
      Payload : Payload_Array_Type;
   end record;
   for Common_Buffer_Type use record -- representation clause should be common to both processes
      Size    at 0 range 0 .. 31;
      Payload at 0 range 32 .. 1023;
   end record;
   for Common_Buffer_Type'Size use 1024; -- check this is also used in the other process.

   type Common_Buffer_Ptr_Type is access Common_Buffer_Type;

   Common_Memory_Ptr : System.Address; -- assuming this is where the shared object resides with a real address, possibly make it constant

   procedure Copy_To_Common_Buffer (Size    : in Integer_32;
                    Payload : in Payload_Array_Type) is
      Common_Buffer : Common_Buffer_Type;
      for Common_Buffer'Address use Common_Memory_Ptr; -- address overlay
   begin
      Common_Buffer := (Size => Size,
            Payload => Payload);
   end Copy_To_Common_Buffer;

begin

   Copy_To_Common_Buffer (9,(others => 876));

end Payload;

The type definitions should be common to the two processes, and note I've used a representation clause to specify where the components go.

I've used an address overlay to specify the location of where I'm writing, and written the whole record in one go.

Also look up usage of pragma volatile as @Brian Drummond suggests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM