CAPL语言设计(2)——数据类型

1. 变量的声明与定义

在程序运行过程中,其值可以被改变的量称为变量。变量可以用于保存用户输入的数据,也可以保存程序运行时产生的中间结果或者最终结果。下面将介绍如何定义变量名,以及如何定义全局变量和局部变量。

变量名

变量名的命名规则与C语言类似,必须注意遵循合法性、有效性和易读性的原则。

变量名的合法性

变量名的合法性如下:
(1)在变量名中只能使用字母字符、数字和下划线(_);
(2)变量名的第一个字符不能是数字;
(3)区分大小写字符;
(4)不能将CAPL关键字用作名称;
(5)不能将CAPL的函数名和变量名。

CAPL关键字可以划分为以下几类:

  • 数据类型关键字,如int,byte,long
  • 控制语句关键字,如if,else
  • 存储类型关键字,如static,extern(外部变量声明)
  • 其他关键字,如const,message

举例说明:

int volume;  	// 合法
int Volume;  	//合法
byte resp_code;  //合法
long 123voltage;  //不合法
char byte;        //不合法

虽然函数名和对象名不属于关键字,CAPL也不允许将它们用作变量名,因为使用同一个名称用作函数名和变量名会把编译器搞糊涂。比如abs,它是CAPL的一个库函数,用来返回参数的绝对值,如果在程序中同时定义了一个abs变量,这时编译器无法有效辨别,编译将无法通过。

变量名的有效性

对于有效性,主要指变量名的字符长度最好不要超过32个,编译系统只能识别前32个字符,也就是说,前32个字符相同的两个不同变量将被编译系统认为是同一个变量。

变量名的易读性

对于易读性,主要是指在CAPL编程中提倡使用有一定含义的变量名,能做到“见名知意”。如果变量表示ECU的供电电压,可以将其命名为 ‘voltage_of_power’ 或者 ‘VoltageOfPower’ ,而不要将其命名为 ‘i’ 或者 ‘po’ 。

必须强调的是,与C语言不同,CAPL语言中为例用户使用的方便灵活,编译器不区分CAPL自带的关键字和函数名的大小写,例如DWORD、dword和Dword在代码中使用效果一样,所以用户定义变量时也需要避免此类情况。

这里需要指出的是,以上命名规则同样适用于函数名、数组名、结构体等。

全局变量与局部变量

在CAPL中,全局变量需要被声明在variables部分,同时可以使用直接赋值方法进行初始化。如果没有初始化,编译器会自动执行初始化,默认值为0。全局变量的作用域包括整个CAPL文件以及与此文件有链接的其他CAPL文件。

与C语言不同,局部变量在CAPL中总是被静态地创建。这意味着初始化只在程序体启动时被执行,当再次进入程序时,局部变量被嘉定是上一次跳出程序时的值。局部变量的作用域,仅限于当前函数体范围内,即该函数的大括号范围内。

2. 简单变量

CAPL中最常见、最简单的三种变量类型——整型、字符和浮点数。

整型

整数就是没有小数部分的数字,如3、33、-333和0。根据数值大小的不同,CAPL提供了如表1所示的几种整型。

表1 整数类型
整型有/无符号长度范围备注
byteunsigned1B0~255字节,8位,无符号
wordunsigned2B0~65535字,16位,无符号
dwordunsigned4B0~4294967295双字,32位,无符号
gwordunsigned8B0~18446744073709551615整型,64位,无符号
intsigned2B-32768~32767短整型,16位
longsigned4B-2147483648~2147483647长整型,32位
int64signed8B-9223372036854775808~9223372036854775807整型,64位

字符

与C语言不同,CAPL没有将char类型(长度1B)归至整型中,这是因为在CANoe中提供了byte类型。如果数据是具体数值则应该使用byte,而对于字符,则应用char(字符串使用char数组)。char类型和byte类型之间可以直接转换,例如:

byte data1 = 100;
char ch1 = 'd';
ch1 = b;
data1 = 's';

浮点型

CAPL提供两种浮点型变量:‘float’ 和 ‘double’ ,如表2所示。

表2 浮点型
浮点型长度范围描述
float8B 1.7 × 1 0 − 308 1.7 \times 10^-308 1.7×10308 ~ 1.7 × 1 0 + 308 1.7 \times 10^+308 1.7×10+308单精度
double8B 1.7 × 1 0 − 308 1.7 \times 10^-308 1.7×10308 ~ 1.7 × 1 0 + 308 1.7 \times 10^+308 1.7×10+308双精度

复合类型

CAPL语言除了支持简单变量外,同时也支持复合类型变量,如数组、结构和枚举。它们的生命方法与C语言基本一致。

结构

CAPL中可以简单滴按照C语言的方法来声明结构(struct),但结构名在程序中必须是唯一的。简单类型、枚举类型或者其他的结构都可以作为结构的成员。例如:

struct b {
	struct a a1;
	enum Colors cl;
	int p;
	long l;
};

结构b中包含:一个结构成员a,变量名为a1;一个枚举成员colors,变量名为c1;一个整型变量p;最后还有一个长整型变量l。

用户可以在类型定义时直接声明结构类型的变量,在这种情况下,类型的名称可以省略,也可以直接使用结构的名字来引用类型。例如:

struct Cost myCost;
struct {int Chinese; int Math; int English} Scores;

关于结构初始化,可以在变量声明期间直接初始化结构成员,不需要单独命名单个成员,编译器将按照结构定义的顺序默认初始化它们。例如:

struct Scores myScores = {Chinese = 79, Math = 99, English = 88};
struct Scores myScores = {79, 99, 88};

枚举

枚举(enum)类型的声明也与C语言中的语法完全一致,但需要注意的是,枚举的成员名必须唯一,否则将有可能代替隐藏数据库中同名的报文和信号。如果没有在声明枚举的同时对成员进行赋值,编译器将按照成员声明的顺序对成员进行初始化。即第一个成员被初始化为0,往后依次加1。例如:

enum {Apple, Pear, Banana} Fruit = Apple;
enum Colors {Red = 1, Green = 3, Blue = 9};

数组

数组(Array)作为一种基本的数据结构,也同样被CAPL支持,就像在C语言中一样。但为了方便使用,CAPL支持直接用字符串初始化字符数组的行为。例如:

int a[3] = {1, 2, 3};	// 有效
char b[13] = "Hello World!";	// 有效
long c[] = {999, 888, 777};	// 无效,在CAPL中必须显式定义数组的长度

同样,CAPL也支持多维数组,并且可以通过内建函数elCount(数组名)来获得数组成员的个数。如果数组的索引超出范围,即小于零或者大于等于数组长度,CAPL将会在数组下标前提示错误。例如:

int v[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int a[3] = {1, 2, 3};
int b = elCount(a);	// b = 3
int c = a[4];		// 错误,超出边界范围

特殊类型

CAPL预定义了一些特有的、针对CANoe仿真的类。

报文

报文(CAN/LIN message)是车载网络最基本的构成部分,CAPL提供了各种网络相对应的报文类。这里主要介绍CAN报文和LIN报文。
使用关键字message来声明一个报文变量,当使用message声明报文变量时,默认变量为CAN报文变量。当有数据库支撑的时候,一个完整的声明应该包括message ID或者message name。使用ID 0xA或者报文名来声明一条数据库中的EngineData报文。例如:

message 0xA m1;	// ID 0xA (hex)
message 100 m2;		// ID 100 (dec)
message EngineData m3;		// name EngineData

以标识符“x”结尾的ID表示这是一个扩展帧ID,例如:100x。
而“*”则表明这条报文在声明时还不含有CAN ID。例如:

on message CAN1.*		// event机制
{
	message *msg;		// 使用“*”声明报文
	if (this.dir!=rx) return;	// 判断条件,只接收RX报文
	msg = this;				// 将RX报文保存下来
}

注意,使用这种方式声明报文时,一定要指定ID后才能将msg发送出去。

CAPL提供了一系列的选择器(Selector)以保证用户能够按照自己的意图去修改CAN message的属性,表3列出了CAN报文属性以及相关信息。

表3 CAN报文属性及相关信息
关键字描述数据类型访问权限
ANCAN报文传输的逻辑通道,有效值范围:1~32word——
MsgChannelCAN报文传输的逻辑通道,有效值范围:1~32word——
IDCAN报文标识符dword——
name报文在dbc文件中的名称char[]readonly
DIR报文的传输方向byte——
RTR远程帧标志位byte——
DLC报文的数据长度,有效值范围:0~15byte——
Byte(x)数据字节位有效值范围:063(863字节仅适用于CAN-FD)byte——

例如,如果需要在CAN1网络上发送一条指定的报文,报文名:magicMessage;报文ID:0x252;包含8个字节0x10 10 20 30 40 00 00 00;可以定义如下:

magicMessage.CAN = 1;
magicMessage.DLC = 8;
magicMessage.Byte(0) = 0x10;
magicMessage.Byte(0) = 0x10;
magicMessage.Byte(0) = 0x20;
magicMessage.Byte(0) = 0x30;
magicMessage.Byte(0) = 0x40;
magicMessage.Byte(0) = 0x00;
magicMessage.Byte(0) = 0x00;
magicMessage.Byte(0) = 0x00;
output(magicMessage);

相应地,CAPL也根据LIN总线的特点提供了LIN报文的选择器,LIN报文属性及相关信息如表4所示。

表4 LIN报文属性及相关信息
关键字描述数据类型访问权限
MsgChannelLIN报文传输逻辑通道,有效值范围:1~32word——
IDLIN报文标识符dword——
DIRLIN报文传输方向bytereadonly
DLC报文的数据长度,有效值范围:0~8byte——
Byte(x)数据字节位,有效值范围:0~7byte——

诊断报文

CAPL通过诊断请求(DiagRequest)和诊断响应(DiagResponse)这两种对象来实现跟ECU之间的诊断服务交互。

通常情况下,诊断服务需要首先对Diagnostic对象声明和初始化。

DiagRequest ServiceQualifier request;
DiagResponse ServiceQualifier response;

上述声明语句分别声明了诊断请求对象“request”和诊断响应对象“response”;并通过给出的诊断服务“ServiceQualifier”进行初始化。这种初始化将在节点仿真开始时被执行一次。

如果使用 * 来代替“ServiceQualifier”,诊断对象将被初始化为未添加诊断描述的空对象,蛋对象的数据必须在发送之前完成设置。

系统变量

系统变量是一种特殊的变量,用来描述某种特殊状态(例如某种事件触发)或者记录测量数据。一般有系统定义和用户自定义两种,它们的作用域都是在各自的命令空间内。
系统变量的数据类型及描述如表5所示。

表5 系统变量类型及描述
整型有/无符号长度范围b>访问权限
Intergersigned32b-2147483648~+214748364732位,有符号
Intergerunsigned32b0~+429496726932位,无符号
Intergersigned64b-9223372036854755808~+922337203685475580764位,有符号
Intergerunsigned64b0~+1844674407370955161664位,有符号
Double——64b——64位,IEEE双精度
String——————字符型
Data——————字节数据
Interger Array——————有符号32位数据数组
Double Array——————64位IEEE双精度数组

定时器

CAPL提供了两种定时器变量:timer 基于秒的时间单位;msTimer 基于毫秒的时间单位,例如:

msTimer myTimer;	// 声明一个毫秒定时器 myTimer
Timer myTimer1;	// 声明一个秒定时器 myTimer1
  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值