将固定大小的数组转换为相同大小的记录

时间:2018-01-25 20:42:55

标签: arrays type-conversion record ada

这可能是一个nobrainer但作为一个新手,我无法理解它。

我有一个返回固定大小数组的函数。我试图将此数组转换为相同大小的记录

函数签名是这样的:

@staticmethod
def generate_email(prefix='huks214+', domain='gmail.com'):

我试图将两个字节(UInt8)放入记录Contro_Status_Bytes中,其定义如下:

type Control is new UInt8_Array (1 .. 2);
function readControl (Command : Control) return Control;

我认为必须可以将数组转换为记录,反之亦然,而不进行未经检查的转换。但目前我遗失了一些东西。

更新:这可能是我在阅读@Simons答案后提出的有效答案/方法。

 type Control_Status_MSB is
  record
     RES_UP     : Boolean;
     QMAX_UP    : Boolean;
     BCA        : Boolean;
     CCA        : Boolean;
     CALMODE    : Boolean;
     SS         : Boolean;
     WDRESET    : Boolean;
     SHUTDOWNEN : Boolean;
  end record;

for Control_Status_MSB use
  record
     RES_UP     at 0 range 0 .. 0;
     QMAX_UP    at 0 range 1 .. 1;
     BCA        at 0 range 2 .. 2;
     CCA        at 0 range 3 .. 3;
     CALMODE    at 0 range 4 .. 4;
     SS         at 0 range 5 .. 5;
     WDRESET    at 0 range 6 .. 6;
     SHUTDOWNEN at 0 range 7 .. 7;
  end record;


type Control_Status_LSB is
  record
     VOK       : Boolean;
     RUP_DIS   : Boolean;
     LDMD      : Boolean;
     SLEEP     : Boolean;
     HIBERNATE : Boolean;
     INITCOMP  : Boolean;
  end record;

for Control_Status_LSB use
  record
     VOK at 0 range 1 .. 1;
  end record;

type Control_Status_Bytes is
  record
     HighByte : Control_Status_MSB;
     LowByte  : Control_Status_LSB;
  end record;

3 个答案:

答案 0 :(得分:3)

未经检查的转化是常用方法。

但是对于MCU中的I / O端口和外设寄存器(Atmel AVR,MSP430等),它们可以作为数字或布尔数组(或可能是记录)来解决,这是一个黑客......

   p1in                   : constant unsigned_8;     --  Port 1 Input 
   Pragma Volatile(p1in);
   Pragma Import(Ada, p1in);      -- see ARM C.6 (13)
   For p1in'Address use   16#20#;

   p1in_bits              : constant Byte;           --  Port 1 Input  Bits
   Pragma Volatile(p1in_bits);
   Pragma Import(Ada, p1in_bits);
   For p1in_bits'Address use   16#20#;

这将来自I / O端口1的输入映射到同一地址,可以是8位无符号或字节(8个布尔数组)。

在你的情况下等价物就像是

For Control_Status_Record'Address use Control_Status_Array`Address;

请注意,您可能需要在这两个视图中附加“pragma volatile”,这样就不会丢失对一个视图的更改,因为另一个视图会缓存在寄存器中。

总而言之,我推荐使用Unchecked_Conversion这种方法。它专为工作而设计,避免搞乱挥发。

答案 1 :(得分:1)

它必须取决于readControl内发生的事情,但是你不能让它直接返回你想要的类型吗?

function readControl (Command : Control) return Control_Status_Bytes;

(我希望Command实际上也有一些结构?)。

顺便说一下,你只在VOK中定义了一个组件(Control_Status_LSB)的位置,剩下的就是编译器了。

答案 2 :(得分:1)

@Simon Wright的暗示使我指出了正确的方向。

这是现在使用的,它有效:

function convert (ResponseArray : Control) return Control_Status_Bytes is
   Result : Control_Status_Bytes with
     Import, Convention => Ada, Address => ResponseArray'Address;
begin
   return Result;
end convert;