基于can总线的A2L文件解析(2)

文章目录

  • 前言
  • Version
    • ASAP2_Version
    • A2ML_Version
  • Project
    • HEADER
      • VERSION
      • PROJECT_NO
    • Module
      • A2ML
        • Protocol_Layer
        • DAQ
        • DAQ_LIST
        • EVENT
        • PAG
        • CAN_Parameters
  • 总结

前言

在上一篇关于A2L的文章中,主要介绍了数据区(标定量,观测量等)的格式和数据,知道了变量在ECU中的地址,在程序运行过程中,通过XCP协议读写对应地址,即可实现标定和测量过的过程。

本文将继续介绍A2L中的协议区,详细介绍基于CAN的XCP协议是如何在A2L中表现的。

基于can总线的A2L文件解析(2)_第1张图片
按A2L文件结构,分Version,Project,Module,及Module下的Keyword.

Version

Version包括两个版本,一个ASAP2版本,一个A2ML版本。

ASAP2_Version

该版本号有两个uint数,表示为VersionNo和UpgradeNo,其中’ VersionNo ‘表示主版本号,’ UpgradeNo '表示升级号(版本号的小数部分)。如果ASAM MCD-2MC标准实现了额外的功能,但对现有应用程序没有影响(兼容修改),则UpgradeNo将增加。如果不兼容的修改,VersionNo将增加。
示例:

ASAP2_VERSION  1   60    /* Version 1.60 */ 

A2ML_Version

该版本号和ASAP2版本号格式相同。A2ML版本是可选的,如果省略了该关键字,或者版本号低于1.31,则使用旧的BLOB格式。当A2ML版本号为1.31时,必须生成新的格式。

Project

一个A2L文件中必须包含一个Project.包含了项目信息。一般一个A2L中也就包含一个项目。

/begin PROJECT MyProject  
  "This is my Project" 
 /begin HEADER "This is Header" 
  VERSION "BG5.0815" 
  PROJECT_NO M4711Z1 
 /end HEADER 
...
/end PROJECT 
/begin 

Project必须包含的参数有名称和描述。HEADER是可选的。一个Project还必须至少包含一个Module,一个Module即表示一个ECU。

HEADER

HEADER包含Comment(描述信息),VERSION(版本)和PROJECT_NO(项目号)是可选的。

VERSION

项目版本,如"BG5.0815",最多MAX_STRING个字符。

PROJECT_NO

项目号,如M4711Z1,最多MAX_IDENT个字符

Module

MODULE关键字描述一个完整的ECU或设备,包括所有可标定和测量的对象、转换方法和功能。为此,需要增加ECU接口相关参数的格式说明。

在第一节中介绍的内容都属于该关键字中。

注意:在同一个模块中可以有相同名称的测量对象和计算方法。在同一个模块中,不能有相同名称的测量对象和标定对象

Module首先包含名称和描述,如:

/begin MODULE MyModule "This is my Module"
...
/end MODULE

A2ML

该关键字是接口相关参数的格式说明,是Module的第一个且非常重要的关键字。

Protocol_Layer

该协议接口在ASAP-XCP-Part2中可以找到

/*********************** start of PROTOCOL_LAYER ****************************/ 
 
struct Protocol_Layer {     /* At MODULE */ 
 
  uint;                                /* XCP protocol layer version */ 
                                         /* e.g. "1.0" = 0x0100            */ 
 
  uint;                               /* T1 [ms] */ 
  uint;                               /* T2 [ms] */ 
  uint;                               /* T3 [ms] */ 
  uint;                               /* T4 [ms] */ 
  uint;                               /* T5 [ms] */ 
  uint;                               /* T6 [ms] */ 
  uint;                               /* T7 [ms] */ 
 
  uchar;                               /* MAX_CTO */ 
  uint;                                  /* MAX_DTO */ 
 
  enum {                               /* BYTE_ORDER */ 
    "BYTE_ORDER_MSB_LAST"  = 0, 
    "BYTE_ORDER_MSB_FIRST" = 1 
  }; /* BYTE_ORDER: BYTE_ORDER_MSB_LAST = Intel, BYTE_ORDER_MSB_FIRST = Motorola*/
  enum {
            "ADDRESS_GRANULARITY_BYTE" = 1,
            "ADDRESS_GRANULARITY_WORD" = 2,
            "ADDRESS_GRANULARITY_DWORD" = 4
          };  /*The address granularity indicates the size of an element contained at a single address.*/

T1:此参数指定用于Xcp主机进行一般响应超时处理的超时值,如CONNECT

T2:此参数指定Xcp主机用于生成校验和响应超时处理的超时值

T3:此参数指定用于Xcp主机编程准备响应超时处理的超时值,如PROGRAM_START, PROGRAM_VERIFY, PROGRAM_PREPARE

T4:此参数指定Xcp主机用于程序清除响应超时处理的超时值,PROGRAM_CLEAR
T5:此参数指定Xcp主机用于编程的响应超时处理的超时值,PROGRAM, PROGRAM_RESET, PROGRAM_MAX

T6:此参数指定Xcp主机用于用户定义的连接响应超时处理的超时值

T7:此参数指定用于等待Xcp主机发出多个命令的预操作的超时值

MAX_CTO:Maximum size of Command Transfer Objects (e.g. for polling)CTO的最大数量

MAX_DTO:Maximum size of Data Transfer Objects (e.g. for DAQ)DTO的最大数量

BYTE_ORDER:字节顺序,BYTE_ORDER_MSB_LAST(高位在后,Inter格式),BYTE_ORDER_MSB_FIRST(高位在前,Motorola格式)

由于CAN data中定义的数据位没有跨字节的,其实Intel和Motorola没有区别

address granularity:表示单个地址中包含的元素的大小

taggedstruct { /* optional */ 
 
 ("OPTIONAL_CMD" enum { /* XCP-Code of optional command */ 
 /* supported by the slave */ 
 "GET_COMM_MODE_INFO" = 0xFB, 
 "GET_ID" = 0xFA, 
 "SET_REQUEST" = 0xF9, 
 "GET_SEED" = 0xF8, 
 "UNLOCK" = 0xF7, 
 "SET_MTA" = 0xF6, 
 "UPLOAD" = 0xF5, 
 "SHORT_UPLOAD" = 0xF4, 
 "BUILD_CHECKSUM" = 0xF3, 
 "TRANSPORT_LAYER_CMD" = 0xF2, 
 "USER_CMD" = 0xF1, 
 "DOWNLOAD" = 0xF0, 
 "DOWNLOAD_NEXT" = 0xEF, 
 "DOWNLOAD_MAX" = 0xEE, 
 "SHORT_DOWNLOAD" = 0xED, 
 "MODIFY_BITS" = 0xEC, 
 "SET_CAL_PAGE" = 0xEB, 
 "GET_CAL_PAGE" = 0xEA, 
 "GET_PAG_PROCESSOR_INFO" = 0xE9, 
 "GET_SEGMENT_INFO" = 0xE8, 
 "GET_PAGE_INFO" = 0xE7, 
 "SET_SEGMENT_MODE" = 0xE6, 
 "GET_SEGMENT_MODE" = 0xE5, 
 "COPY_CAL_PAGE" = 0xE4, 
 "CLEAR_DAQ_LIST" = 0xE3, 
 "SET_DAQ_PTR" = 0xE2, 
 "WRITE_DAQ" = 0xE1, 
 "SET_DAQ_LIST_MODE" = 0xE0, 
 "GET_DAQ_LIST_MODE" = 0xDF, 
 "START_STOP_DAQ_LIST" = 0xDE, 
 "START_STOP_SYNCH" = 0xDD, 
 "GET_DAQ_CLOCK" = 0xDC, 
 "READ_DAQ" = 0xDB, 
 "GET_DAQ_PROCESSOR_INFO" = 0xDA, 
 "GET_DAQ_RESOLUTION_INFO" = 0xD9, 
 "GET_DAQ_LIST_INFO" = 0xD8, 
 "GET_DAQ_EVENT_INFO" = 0xD7, 
 "FREE_DAQ" = 0xD6, 
 "ALLOC_DAQ" = 0xD5, 
 "ALLOC_ODT" = 0xD4, 
 "ALLOC_ODT_ENTRY" = 0xD3,
 "PROGRAM_START" = 0xD2, 
 "PROGRAM_CLEAR" = 0xD1, 
 "PROGRAM" = 0xD0, 
 "PROGRAM_RESET" = 0xCF, 
 "GET_PGM_PROCESSOR_INFO" = 0xCE, 
 "GET_SECTOR_INFO" = 0xCD, 
 "PROGRAM_PREPARE" = 0xCC,
 "PROGRAM_FORMAT" = 0xCB,
 "PROGRAM_NEXT" = 0xCA, 
 "PROGRAM_MAX" = 0xC9, 
 "PROGRAM_VERIFY" = 0xC8, 
 "WRITE_DAQ_MULTIPLE" = 0xC7 
 })*; 

上面是命令的定义。实际使用需要看配置

“COMMUNICATION_MODE_SUPPORTED” taggedunion { /* optional modes supported */ 
 “ BLOCK” taggedstruct { 
 "SLAVE"; /* Slave Block Mode supported */ 
 "MASTER" struct { /* Master Block Mode supported */ 
 uchar; /* MAX_BS */ 
 uchar; /* MIN_ST */ 
 }; 
 }; 
 "INTERLEAVED" uchar; /* QUEUE_SIZE */ 
 }; 
 "SEED_AND_KEY_EXTERNAL_FUNCTION" char[256]; /* Name of the Seed&Key function */ 
 /* including file extension */ 
 /* without path */ 
  "MAX_DTO_STIM" uint;  /* overrules MAX_DTO see above for STIM use case */
 };
 }; 
}; /********************* end of PROTOCOL_LAYER *****************************/ 

MAX_BS:表示允许的最大块大小,即块序列中连续命令包的数量

MIN_ST:表示从主设备到从设备的块传输数据包之间所需的最小间隔时间,单位为100毫秒

QUEUE_SIZE:表示主机可以发送到从机接收队列的最大连续命令数据包数


SEED_AND_KEY_EXTERNAL_FUNCTION:Seed&Key函数名
MAX_DTO_STIM:覆盖STIM中的MAX_DTO

DAQ

该接口在ASAP-XCP-Part2中可以找到

/***************************** start of DAQ *********************************/ 
struct Daq { /* DAQ supported, at MODULE*/ 
 enum { /* DAQ_CONFIG_TYPE */ 
 "STATIC" = 0, 
 "DYNAMIC" = 1 
 }; 
 uint; /* MAX_DAQ */
 uint; /* MAX_EVENT_CHANNEL */ 
 uchar; /* MIN_DAQ */ 
 enum { /* OPTIMISATION_TYPE */ 
 "OPTIMISATION_TYPE_DEFAULT" = 0, 
 "OPTIMISATION_TYPE_ODT_TYPE_16" = 1, 
 "OPTIMISATION_TYPE_ODT_TYPE_32" = 2, 
 "OPTIMISATION_TYPE_ODT_TYPE_64" = 3, 
 "OPTIMISATION_TYPE_ODT_TYPE_ALIGNMENT" = 4, 
 "OPTIMISATION_TYPE_MAX_ENTRY_SIZE" = 5 
 }; 
 enum { /* ADDRESS_EXTENSION */ 
 "ADDRESS_EXTENSION_FREE" = 0, 
 "ADDRESS_EXTENSION_ODT" = 1, 
 "ADDRESS_EXTENSION_DAQ" = 3 
 }; 

DAQ_CONFIG_TYPE:DAQ类型,静态0或动态1

MAX_DAQ:可用DAQ列表的总数

MAX_EVENT_CHANNEL:可用事件通道总数

MIN_DAQ:预定义DAQ列表的总数

OPTIMISATION_TYPE:指出主机最好使用的优化方法类型

ADDRESS_EXTENSIO:该标志指示一个ODT内或一个DAQ内所有条目的地址扩展必须相同

enum { /* IDENTIFICATION_FIELD */ 
 "IDENTIFICATION_FIELD_TYPE_ABSOLUTE" = 0, 
 "IDENTIFICATION_FIELD_TYPE_RELATIVE_BYTE" = 1, 
 "IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD" = 2, 
 "IDENTIFICATION_FIELD_TYPE_RELATIVE_WORD_ALIGNED" = 3 
 }; 
 enum { /* GRANULARITY_ODT_ENTRY_SIZE_DAQ */ 
 "GRANULARITY_ODT_ENTRY_SIZE_DAQ_BYTE" = 1,
 "GRANULARITY_ODT_ENTRY_SIZE_DAQ_WORD" = 2, 
 "GRANULARITY_ODT_ENTRY_SIZE_DAQ_DWORD" = 4, 
 "GRANULARITY_ODT_ENTRY_SIZE_DAQ_DLONG" = 8 
 }; 
 uchar; /* MAX_ODT_ENTRY_SIZE_DAQ */ 
 enum { /* OVERLOAD_INDICATION */ 
 "NO_OVERLOAD_INDICATION" = 0, 
 "OVERLOAD_INDICATION_PID" = 1, 
 "OVERLOAD_INDICATION_EVENT" = 2 
 }; 

IDENTIFICATION_FIELD:将DAQ数据包传输到主机时,从机将使用的标识字段类型

GRANULARITY_ODT_ENTRY_SIZE_DAQ :指示由DAQ的DaqListType的ODT条目描述的元素的大小

MAX_ODT_ENTRY_SIZE_DAQ:Maximum size of ODT entry for DAQ

OVERLOAD_INDICATION:OVERLOAD_INDICATION_PID:这意味着当过载发生时,PID中设置最高位 OVERLOAD_INDICATION_EVENT:这意味着当发生过载时,将设置一个事件

taggedstruct { /* optional */ 
 "DAQ_ALTERNATING_SUPPORTED" uint; /* Display_Event_Channel_Number */ 
 "PRESCALER_SUPPORTED"; 
 "RESUME_SUPPORTED"; 
 "STORE_DAQ_SUPPORTED"; 
 block "STIM" struct { /* STIM supported */ 
 enum { /* GRANULARITY_ODT_ENTRY_SIZE_STIM */ 
 "GRANULARITY_ODT_ENTRY_SIZE_STIM_BYTE" = 1, 
 "GRANULARITY_ODT_ENTRY_SIZE_STIM_WORD" = 2, 
 "GRANULARITY_ODT_ENTRY_SIZE_STIM_DWORD" = 4, 
 "GRANULARITY_ODT_ENTRY_SIZE_STIM_DLONG" = 8 
 }; 
 uchar; /* MAX_ODT_ENTRY_SIZE_STIM */ 
 taggedstruct { /* bitwise stimulation */ 
 "BIT_STIM_SUPPORTED"; 
 “MIN_ST_STIM” uchar; /* separation time between DTOs */ 
 /* time in units of 100 microseconds */ 
 }; 
 }; 

block表示是子关键字,定义时会生成 /begin STIM
DAQ_ALTERNATING_SUPPORTED:该标志选择交替显示模式

PRESCALER_SUPPORTED:该标志表示所有DAQ列表都支持预分频器以缩短传输周期
RESUME_SUPPORTED:此标志表示可以将所有DAQ列表置于RESUME模式。
STORE_DAQ_SUPPORTED:该标志表示从设备可以存储DAQ配置

GRANULARITY_ODT_ENTRY_SIZE_STIM:指示由stim的DaqListType的ODT条目描述的元素的大小

MAX_ODT_ENTRY_SIZE_STIM:Maximum size of ODT entry for STIM

BIT_STIM_SUPPORTED:该标志指示是否支持通过WRITE_DAQ 中的BIT_OFFSET进行逐位数据仿真

MIN_ST_STIM:STIM DTO时间之间的间隔时间,单位为100微秒

block "TIMESTAMP_SUPPORTED" struct { 
 uint; /* TIMESTAMP_TICKS */ 
 enum { /* TIMESTAMP_SIZE */ 
 "NO_TIME_STAMP" = 0, 
 "SIZE_BYTE" = 1, 
 "SIZE_WORD" = 2, 
 "SIZE_DWORD" = 4 
 };
 enum { /* RESOLUTION OF TIMESTAMP */ 
 "UNIT_1NS" = 0, 
 "UNIT_10NS" = 1, 
 "UNIT_100NS" = 2, 
 "UNIT_1US" = 3, 
 "UNIT_10US" = 4, 
 "UNIT_100US" = 5, 
 "UNIT_1MS" = 6, 
 "UNIT_10MS" = 7, 
 "UNIT_100MS" = 8, 
 "UNIT_1S" = 9, 
 “UNIT_1PS” = 10, 
 “UNIT_10PS” = 11, 
 “UNIT_100PS” = 12 
 }; 
 taggedstruct { 
 "TIMESTAMP_FIXED"; 
 }; 
 }; 
 "PID_OFF_SUPPORTED"; 

TIMESTAMP_TICKS:timestamp将按每个单位的TIMESTAMP_TICKS刻度递增

TIMESTAMP_SIZE:XCP消息中用于timestamp字段的字节数。如果是No_TIME_STAMP,则timestamp字段不可用

RESOLUTION OF TIMESTAMP:每个TICKS的时间

TIMESTAMP_FIXED:如果启用,从设备始终以timestamp模式发送数据传输对象(DTO)数据包。否则,将为每个DAQ列表分别动态启用timestamp。

PID_OFF_SUPPORTED:DAQ_PROPERTIES中的标志表示可以在没有标识字段的情况下传输DTO数据包

DAQ_LIST

一般都用动态list。所以list配置基本用不到

/************************ start of DAQ_LIST *************************/ 
 (block "DAQ_LIST" struct { /* DAQ_LIST */ 
 /* multiple possible */ 
 uint; /* DAQ_LIST_NUMBER */ 
 taggedstruct { /* optional */ 
 "DAQ_LIST_TYPE" enum { 
 "DAQ" = 1, /* DIRECTION = DAQ only */ 
 "STIM" = 2, /* DIRECTION = STIM only */ 
 "DAQ_STIM" = 3 /* both directions possible */ 
 /* but not simultaneously */ 
 }; 
 "MAX_ODT" uchar; /* MAX_ODT */ 
 "MAX_ODT_ENTRIES" uchar; /* MAX_ODT_ENTRIES */ 
 "FIRST_PID" uchar; /* FIRST_PID for this DAQ_LIST */ 
 "EVENT_FIXED" uint; /* this DAQ_LIST always */ 
 /* in this event */
 block "PREDEFINED" taggedstruct { /* predefined */ 
 /* not configurable DAQ_LIST */ 
 (block “ODT” struct { 
 uchar; /* ODT number */ 
 taggedstruct { 
 (“ODT_ENTRY” struct { 
 uchar; /* ODT_ENTRY number */ 
 ulong; /* address of element */ 
 uchar; /* address extension of element */ 
 uchar; /* size of element [AG] */ 
 uchar; /* BIT_OFFSET */ 
 })*; 
 }; /* end of ODT_ENTRY */ 
 })*; /* end of ODT */ 
 }; /* end of PREDEFINED */ 
 }; 
 })*;/********************* end of DAQ_LIST ***************************/ 

EVENT

 /************************* start of EVENT ****************************/ 
 
 (block "EVENT" struct { /* EVENT */ 
 /* multiple possible */ 
 char[101]; /* EVENT_CHANNEL_NAME 事件长名*/ 
 char[9]; /* EVENT_CHANNEL_SHORT_NAME 事件短名*/  
 uint; /* EVENT_CHANNEL_NUMBER 事件通道*/ 
 
 enum { 
 "DAQ" = 1, /* only DAQ_LISTs */ 
 /* with DIRECTION = DAQ */ 
 "STIM" = 2, /* only DAQ_LISTs */ 
 /* with DIRECTION = STIM */ 
 "DAQ_STIM" = 3 /* both kind of DAQ_LISTs
 数据传输类型 DAQ是从ECU到上位机,STIM是从上位机到ECU */ 
 }; 
 
 uchar; /* MAX_DAQ_LIST 最大DAQ LIST数量*/ 
 uchar; /* EVENT_CHANNEL_TIME_CYCLE 事件循环周期*/ 
 uchar; /* EVENT_CHANNEL_TIME_UNIT 事件时间单位*/ 
 uchar; /* EVENT_CHANNEL_PRIORITY 事件优先级*/ 
 taggedstruct { /* optional */ 
 “COMPLEMENTARY_BYPASS_EVENT_CHANNEL_NUMBER” uint; 
 //该关键字用于组合两个事件通道,构建BYPASS
 “CONSISTENCY” enum { 
 “DAQ” = 0,
 “EVENT” = 1
 }; //通过该关键字,从机可以指示在该事件中处理数据时存在何种数据一致性
 }; 
 
 })*;/******************** end of EVENT ********************************/ 
 }; /*end of optional at DAQ */ 
}; /************************* end of DAQ *************************************/ 

PAG

/**************************** start of PAG ***********************************/ 
struct Pag { /* PAG supported, at MODULE */ 
 uchar; /* MAX_SEGMENTS */ 
 taggedstruct { /* optional */ 
 "FREEZE_SUPPORTED"; 
 }; 
}; /************************* end of PAG *************************************/

MAX_SEGMENTS: 从机中的段总数

FREEZE_SUPPORTED:该标志表示所有段都可以冻结

CAN_Parameters

CAN_Parameters是CAN xpc的参数设置,包括ID。波特率等

struct CAN_Parameters { /* At MODULE */ 
 uint; /* XCP on CAN version 版本号*/ 
 /* e.g. "1.0" = 0x0100 */ 
 taggedstruct { /* optional */ 
 “CAN_ID_BROADCAST” ulong; /* Auto detection CAN-ID 自动检测CAN ID*/ 
 /* master -> slaves 主机->从机*/ 
 /* Bit31= 1: extended identifier */ 
 “CAN_ID_MASTER” ulong; /* CMD/STIM CAN-ID 主机CAN ID*/ 
 /* master -> slave */ 
 /* Bit31= 1: extended identifier */ 
 "CAN_ID_MASTER_INCREMENTAL"; /* master uses range of CAN-IDs 主机使用范围内的CAN ID*/ 
 /* start of range = CAN_ID_MASTER */ 
 /* end of range = CAN_ID_MASTER+MAX_BS(_PGM)-1 */ 
 “CAN_ID_SLAVE” ulong; /* RES/ERR/EV/SERV/DAQ CAN-ID 从机CAN ID*/ 
 /* slave -> master */ 
 /* Bit31= 1: extended identifier */ 
 “BAUDRATE” ulong; /* BAUDRATE [Hz] 总线波特率*/ 
 "SAMPLE_POINT" uchar; /* sample point 采样点*/ 
 /* [% complete bit time] */
  “SAMPLE_RATE” enum { 
 "SINGLE" = 1, /* 1 sample per bit 采样率*/ 
 "TRIPLE" = 3 /* 3 samples per bit */ 
 }; 
 "BTL_CYCLES" uchar; /* BTL_CYCLES 每个bit的slot数*/ 
 /* [slots per bit time] */ 
 "SJW" uchar; /* length synchr. segment 同步段长度*/ 
 /* [BTL_CYCLES] */ 
 "SYNC_EDGE" enum { 
 "SINGLE" = 1, /* on falling edge only 下降沿同步*/ 
 "DUAL" = 2 /* on falling and rising edge 下降沿和上升沿同步*/ 
 }; 
 “MAX_DLC_REQUIRED”; /* master to slave frames 主从机的DLC始终为8*/ 
 /* always to have DLC = MAX_DLC = 8 */ 
 //以下用的不多
 (block “DAQ_LIST_CAN_ID” struct { /* At IF_DATA DAQ */ 
 uint; /* reference to DAQ_LIST_NUMBER */ 
 taggedstruct { /* exclusive tags */ 
 /* either VARIABLE or FIXED */ 
 "VARIABLE"; 
 "FIXED" ulong; /* this DAQ_LIST always */ 
 /* on this CAN_ID */ 
 }; 
 })*; 
 }; 
 };/************************* end of CAN ***********************************/

总结

以上,常用的接口就介绍完了,还有一些不常用的没有列出来。可以参考ASAM XCP。后面介绍实际的数据定义。主要跟配置相关。

若你觉得本文对你有帮助,欢迎点赞,关注,收藏,转发~~~

你的鼓励是对小弟的最大支持~~~

建了一个WX公众号,《汽车电子学习笔记》感兴趣可以关注一下~~~文章都会同步更新~

你可能感兴趣的:(Autosar笔记,autosar,xcp,A2L)