定义映射布局

本主题使用示例来描述映射的布局定义。
关于此任务

创建布局 XML 文件

在 layout.dtd 文档类型定义 (DTD) 文件中定义了 XML 文件格式,如下所示:

<?xml version="1.0"?>
  <!ELEMENT LAYOUT (FIELD)+>
  <!ATTLIST LAYOUT Header CDATA #REQUIRED length CDATA #REQUIRED>
  <!ELEMENT GROUP EMPTY>
  <!ATTLIST GROUP Name CDATA #REQUIRED>
  <!ELEMENT FIELD (FIELD)*>
  <!ATTLIST FIELD
    Header CDATA #REQUIRED
    Type (16_BIT_INT|16_BIT_UINT|16_BIT_HINT|32_BIT_INT|32_BIT_UINT|32_BIT_HINT|32_BIT_FLOAT|64_BIT_INT|64_BIT_FLOAT|CHARACTER|HEX|ASCII|EBCDIC|STRUCTURE|PADDING|BIT|BITMASK|MAP) #REQUIRED
    length CDATA #REQUIRED
    layout CDATA #IMPLIED
    filename CDATA #IMPLIED
	  Groups CDATA #IMPLIED>

这意味着,XML 布局文件首先指定头(标题)以及后跟子元素 (FIELD) 列表的布局总长度,子元素 (FIELD) 由头(名称)、长度以及用来确定该子元素的缺省表示法的基本类型来描述。

还有下列特殊的子元素类型:

以下示例定义了下列 C 语言结构的布局:

typedef struct {
  char char_val;
  unsigned short ushort_val;
  short short_val;
  unsigned long ulong_val;
  long long_val;
  char string_val[32];
} _test;

以下是对 _test 结构的树形视图进行描述并且符合此格式的 XML 文件:

<?xml version="1.0"?>
  <LAYOUT Header="A Layout" description="Tree view" length="17">
  <FIELD Header="char_val" Type="CHARACTER" length="1"></FIELD>
  <FIELD Header="ushort_val" Type="16_BIT_UINT" length="2"></FIELD>
  <FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD>
  <FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD>
  <FIELD Header="long_val" Type="32_BIT_INT" length="4"></FIELD>
  <FIELD Header="string_val" Type="ASCII" length="32"></FIELD>
  <FIELD Header="hex_val" Type="HEX" length="0x64" offset="300" offset_mode="relative"></FIELD>
</LAYOUT>

可通过用 0x 作为前缀来以十六进制指定字段长度和 offset 属性。

offsetoffset_mode 属性允许您按以下方式指定字段的准确位置:相对于映射的起点 (offset_mode=absolute) 或相对于当前地址 (offset_mode=relative)。在以下示例中,元素 boffset 为 10 并且 offset_mode 定义为 relative。在不使用这些属性的情况下,此元素的偏移量将为 80,但是,因为相对于当前位置的偏移量定义为 10,所以总偏移量为 90。请注意,元素 a 的长度是以十六进制定义的,因为该长度用 0x 作为前缀。元素 c 的偏移量为 4 并且偏移方式为 absolute。这意味着,此元素的偏移量为 4 个字节(距离布局的起点)。字段 a 也涵盖由字段 c 映射的 10 个字节:

<LAYOUT Header="offset_Test" length="80">
  <FIELD Header="a" Type="HEX" length="0x64"></FIELD>
  <FIELD Header="b" description="offset = 90" Type="HEX" length="80" offset="10" offset_mode="relative"></FIELD>
  <FIELD Header="c" Type="HEX" length="10" offset="4" offset_mode="absolute"></FIELD>
</LAYOUT>

定义填充字段

如果决定忽略 long_val 字段,但是要在布局中显示 string_val 类型,那么该 XML 文件将与下面的内容类似:

  <FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD>
  <FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD>
  <FIELD Header="" Type="PADDING" length="4"></FIELD>
  <FIELD Header="string_val" Type="ASCII" length="32"></FIELD>

还可在此处使用 offset 属性来跳过 long_val 字段,方法是将 string_valoffset 指定为 4 并将 offset_mode 指定为 relative

<FIELD Header="short_val" Type="16_BIT_INT" length="2"></FIELD>
<FIELD Header="ulong_val" Type="32_BIT_UINT" length="4"></FIELD>
<FIELD Header="string_val" Type="ASCII" length="32" offset="4" offset_mode="relative"></FIELD>

这意味着,string_val 字段的地址相对于 ulong_val 字段实际上为 4 个字节。

定义 PADDING 子元素的初始目的是为了处理字节对齐的结构,但它也可用来跳过布局中不需要细节化的数据区。

定义结构

以下 XML 片段显示用于对嵌套结构进行映射的 STRUCTURE 字段的使用情况。结构的顶级元素不包含关联的值,可以展开它以显示其子元素。虽然 STRUCTURE 字段的长度已添加至 XML 布局的总大小,但是,所包含字段大小仅旨在用于显示。例如,以下结构意味着仅 344 字节超出总布局大小。

<FIELD Header="MACHINE CHECK LOG OUT AREA" Type="STRUCTURE" length="344">
  <FIELD Header="reserved" Type="HEX" length="16"></FIELD>
  <FIELD Header="FLCSID" Type="HEX" length="4"></FIELD>
  <FIELD Header="FLCIOFP" Type="HEX" length="4"></FIELD>
  <FIELD Header="reserved" Type="HEX" length="20"></FIELD>
  <FIELD Header="FLCESAR" Type="HEX" length="4"></FIELD>
  <FIELD Header="FLCCTSA" Type="HEX" length="8"></FIELD>
  <FIELD Header="FLCCCSA" Type="HEX" length="8"></FIELD>
  <FIELD Header="FLCMCIC" Type="HEX" length="8"></FIELD>
  <FIELD Header="reserved" Type="HEX" length="8"></FIELD>
  <FIELD Header="FLCFSA" Type="HEX" length="4"></FIELD>
  <FIELD Header="reserved" Type="HEX" length="4"></FIELD>
  <FIELD Header="FLCFLA" Type="HEX" length="16"></FIELD>
  <FIELD Header="FLCRV110" Type="HEX" length="16"></FIELD>
  <FIELD Header="FLCARSAV" Type="STRUCTURE"length="64">
    <FIELD Header="AR0" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR1" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR2" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR3" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR4" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR5" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR6" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR7" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR8" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR9" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR10" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR11" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR12" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR13" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR14" Type="HEX" length="4"></FIELD>
    <FIELD Header="AR15" Type="HEX" length="4"></FIELD>
  </FIELD>
  <FIELD Header="FLCFPSAV" Type="HEX" length="32"></FIELD>
  <FIELD Header="" Type="PADDING" length="64"></FIELD>
  <FIELD Header="" Type="PADDING" length="64"></FIELD>
</FIELD>

可对布局以内部或外部方式定义结构。通过在结构字段中指定 filename="<file name>",可创建类似于嵌套布局的外部结构,其中 <file name> 引用的文件包含结构的实际定义。

例如,可在映射布局中以外部方式指定 MACHINE CHECK LOG OUT AREA 结构,如下所示:<FIELD Header="MACHINE CHECK LOG OUT AREA" Type="STRUCTURE" length="344" filename="machine.xml"></FIELD>

定义位屏蔽字段

以下 XML 片段是用于描述 BITMASK 字段的样本。BITMASK 的长度以字节指定,并且它包含一组 BIT 字段(这些字段的长度以位指定)。针对 BIT 字段显示的偏移量是 BITMASK 字段内的位偏移量。虽然位屏蔽字段的长度已添加至 XML 布局的总大小,但是,各个 BIT 字段大小仅旨在用于显示。

<FIELD Header="BITMASK" Type="BITMASK" length="1">
  <FIELD Header="BIT 1" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 2" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 3" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 4" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 5" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 6" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 7" Type="BIT" length="1"></FIELD>
  <FIELD Header="BIT 8" Type="BIT" length="1"></FIELD>
</FIELD> 

定义 union

以下示例定义了下列 C 语言 union 的布局:

union my_union {
  int my_intVal;
  double my_doubleVal;
};

以下 XML 样本显示如何描述 union。请注意,在 XML 中,union 的长度为其最大字段的大小:

<LAYOUT Header="UNIONS" length="8">
  <FIELD Header="my_union" Type="UNION" length="8">
    <FIELD Header="my_intVal" Type="HEX" length="4" description="value within the union"></FIELD>
    <FIELD Header="my_doubleVal" Type="HEX" length="8"></FIELD>
  </FIELD>
</LAYOUT> 

定义嵌套布局

通过将 MAP 字段类型与可选布局字段一起使用,可以描述嵌套布局,如以下 DSA 布局示例中所示:

<?xml version="1.0"?>
<!DOCTYPE LAYOUT SYSTEM "Layout.dtd">
<LAYOUT Header="DSA" length="72">
  <FIELD Header="FLAGS" Type="HEX" length="2"></FIELD>
  <FIELD Header="junk" Type="HEX" length="2"></FIELD>
  <FIELD Header="Back Chain" Type="MAP" length="4" layout="dsa.xml"></FIELD>
  <FIELD Header="Forward Chain" Type="MAP" length="4" layout="dsa.xml"></FIELD>
  <FIELD Header="R14" Type="HEX" length="4"></FIELD>
  <FIELD Header="R15" Type="HEX" length="4"></FIELD>
  <FIELD Header="R0" Type="HEX" length="4"></FIELD>
  <FIELD Header="R1" Type="HEX" length="4"></FIELD>
  <FIELD Header="R2" Type="HEX" length="4"></FIELD>
  <FIELD Header="R3" Type="HEX" length="4"></FIELD>
  <FIELD Header="R4" Type="HEX" length="4"></FIELD>
  <FIELD Header="R5" Type="HEX" length="4"></FIELD>
  <FIELD Header="R6" Type="HEX" length="4"></FIELD>
  <FIELD Header="R7" Type="HEX" length="4"></FIELD>
  <FIELD Header="R8" Type="HEX" length="4"></FIELD>
  <FIELD Header="R9" Type="HEX" length="4"></FIELD>
  <FIELD Header="R10" Type="HEX" length="4"></FIELD>
  <FIELD Header="R11" Type="HEX" length="4"></FIELD>
  <FIELD Header="R12" Type="HEX" length="4"></FIELD>
</LAYOUT>

此格式正确的 XML 布局存储在称为 DSA.XML 的文件中。由于已知字段 3 和 4 包含指向不同 DSA 结构的指针,所以您会添加两个嵌套布局定义。

注: 仅当第一次展开布局元素以防止递归展开布局时,才执行该布局的实际内存映射。

定义组

借助组语法,可以将映射布局中的字段分为若干组,以便它们更容易使用。要定义组,需将 <GROUP Name="groupName"></GROUP> 放置在布局文件的顶部。然后,通过指定以下内容来指示字段属于预定义的组:<FIELD Header="RESERVED" Type="HEX" length="12" Groups="groupName"></FIELD>

一个字段可以属于多个组。要定义多个组,请在 Groups 属性中通过以逗号分隔的列表来指定这些组。Groups 属性中的每个组都必须已在布局中通过使用 <GROUP> 标记来定义。

名称为 ALL 的组是特殊组。在某个字段中指定此名称将使该字段属于所有组,并且该字段在所有组中都将可视。以下代码样本包含组:

<?xml version="1.0"?>
<!DOCTYPE LAYOUT SYSTEM "Layout.dtd">
<LAYOUT Header="GROUP_EXAMPLE" length="32">
  <GROUP Name="GroupA"></GROUP>
  <GROUP Name="GroupB"></GROUP>
  <FIELD Header="FIELD_A" Type="HEX" length="8" Groups="GroupA"></FIELD>
  <FIELD Header="FIELD_B" Type="HEX" length="8" Groups="GroupB"></FIELD>
  <FIELD Header="FIELD_AB" Type="HEX" length="8" Groups="GroupA,GroupB"></FIELD>
  <FIELD Header="FIELD_ALL" Type="HEX" length="8" Groups="ALL"></FIELD>
</LAYOUT>

定义 ORG 组

可以使用 ORG_GROUP 标记来定义内存的先前所定义部分的布局。这类似于汇编程序中的 ORG 指令的行为。可以使用 FIELD 属性来指定新布局的起始位置。在简单情况下,FIELD 属性的值可以是映射中先前所定义字段的名称。还可使用 *NONE* 作为值,这意味着布局用于内存中的当前位置。Header 属性只是新布局的名称。

<LAYOUT Header="SW00SR" length="271">
   <ORG_GROUP FIELD="*NONE" Header="ORG_GROUP1">
    <FIELD Header="A" length="4" Type="HEX"></FIELD>
    <FIELD Header="B" length="4" Type="HEX"></FIELD>
    <FIELD Header="c" length="4" Type="HEX"></FIELD>
  </ORG_GROUP>
   <ORG_GROUP FIELD="A" Header="my_custom_header">
    <FIELD Header="F" length="4" Type="HEX" description="address of F == address of A"></FIELD>
    <FIELD Header="G" length="4" Type="HEX"></FIELD>
    <FIELD Header="H" length="4" Type="HEX"></FIELD>
    <ORG_GROUP FIELD="*+4" Header="another_org">
      <FIELD Header="J" length="2" Type="HEX" description="address of J = current location + 4"></FIELD>
    </ORG_GROUP>
  </ORG_GROUP>
  <FIELD Header="R" length="4" Type="HEX"></FIELD>
  <FIELD Header="Z" length="4" Type="HEX"></FIELD>
</LAYOUT> 

其中:


反馈