CAPL學習之路-信息、類的實例化、數組、結構體、枚舉、字典


1.獲取工程信息

  • %NODE_NAME%  仿真節點名稱
  • on key 'a'
    {
      write("the node name: %NODE_NAME%");
    } 
    
  • %CHANNEL% 仿真節點分配的通道
  • %NETWORK_NAME% 仿真節點分配的網絡名稱
  • %FILE_NAME% 源文件名稱
  • %FILE_NAME_NO_EXT%   源文件名稱(沒有擴展名)
  • %BASE_FILE_NAME_NO_EXT% 編譯的文件名稱(沒有擴展名)

2.%FILE_NAME%獲取源文件的名稱,%BASE_FILE_NAME%獲取編譯的文件名稱,這兩者有何區別?

 

 

 

對於網絡節點,只有加載的capl文件才是主文件,而這個capl文件又可能引用多個capl文件

%FILE_NAME%是獲取所在文件的名稱,而%BASE_FILE_NAME%只會獲取主文件的名稱

3.類得實例化

  1. capl雖然無法自定義類,然后通過實例化的方式調用類中的方法
  2. 可以對capl中預定義的類進行實例化,然后調用里面的方法
  • 可以對capl中預定義的類進行實例化,然后調用里面的方法
  • 類名 對象名;然后用這個對象調用函數
  • 對象名.函數名(參數1,參數2,...)

Timer, MsTimer:這兩個類用於定期執行特定的功能,其中,Timer以秒為單位,MsTimer以毫秒為單位

File    這個類用於讀取或寫入文件

TcpSocket  這個類用於實現tcp網絡通信

UdpSocket 這個類用於實現udp網絡通信

TestCheck  這個類是與測試序列或模擬節點並行運行,目的是持續檢查是否遵守指定條件

TestStimulus 這個類可以為信號或環境變量生成特定值模式以刺激設備

DiagRequest  這個類表示診斷請求

DiagRespons 這個類表示診斷響應

Associative fields  關聯字段

CAN  提供對總線指定信息的訪問

Classes of CAN Disturbance Interface    CAN干擾接口的類

Classes of Scope   范圍類

4.數組

和其他編程語言一樣,capl也有數組類型,需要注意的是,字符串是CHAR類型的數組,另外也支持多維數組

例如:

int num1[5] = {1,2,3,4,5};
byte num[3]={0x01,0x02,0x03};
int num3[2][2]={{1,2},{3,4}};
char str=[6]="hello";

對於char類型的數組,數組長度要是字符串字符個數加1,因為默認還有一個換行符,也算一個字符

消息可以使用id或dbmsg來定義並進行初始化

 

message 0x5c0 msg_wakeup = {dlc = 8, byte(0) = 0x11, byte(1) = 0x22, byte(2) = 0x33, byte(3) = 0x44, byte(4) = 0x55, byte(5) = 0x66, byte(6) = 0x77, byte(7) = 0x88};  
message IgnitionOn msg_wakeup = {dlc = 8, byte(0) = 0x11, byte(1) = 0x22, byte(2) = 0x33, byte(3) = 0x44, byte(4) = 0x55, byte(5) = 0x66, byte(6) = 0x77, byte(7) = 0x88};

 

如果是多個消息的集合,可以用message *

message * msgArray[4] = {msgABSdata, motbus::EngineData, msgGearBoxInfo, {dlc = 8}};

數組元素個數可以用elcount()獲取  

除了下標來獲取數組的元素以外,還可以用訪問數據的選擇器來獲取

on key 'a'
{
  byte num1[4] = {0x11, 0x22, 0x33, 0x44};
  write("value1: 0x%2x", num1.byte(0));
  write("value2: 0x%4x", num1.word(2));
  write("value3: 0x%8x", num1.dword(0));
}  

打印結果:

 

 

 可以看出

 

 

byte(i)、word(i)、dword(i)、int(i)、double(i)等傳入的參數i代表的是從第i個byte開始,所以能調用它們的數組也只能是byte數組

 

byte(i)是從第i個byte開始的一個byte值

 

word(i)是從第i個byte開始的一個word值

 

dword(i)是從第i個byte開始的一個dword值

 

byte數組是存入的window電腦,采用的是小端存儲,那么低位下標的值表示低位,高位下標的值表示高位,所以0x33,0x44才會變成4433

對於消息來說,它里面的值也是以byte為單位的,所以也可以用這些選擇器獲取索引值

msg_wakeup.byte(0) = 0x01;
msg_wakeup.word(1) = 0x1234

 swapWord(num1.word(2))   大小端轉

由於網絡傳輸采用的是大端存儲,那么低位下標的值表示高位,高位下標的值表示低位,所以0x33,0x44就會寫成3344  

5.結構體

定義一個結構體

struct Date {
  int type;
  long l;
  cahr name[50];
}; 

注意:中括號得后面需要有分號

定義這個結構體后,還需要聲明這個結構體變量

struct Date data;

然后用這個結構體變量調用里面的元素,比如data.type

你會發現結構體從定義到使用,都和類的實例化比較像

反過來想,其實類的實例化也是聲明變量類型的一種形式

對類的實例化,其實就是聲明這個類的類型的變量

而聲明變量也是類的實例化的表現,比如聲明一個int類型的變量,其實也是對int類實例化一個對象,所以很多時候,可以直接用變量調用某些方法,這些方法其實就是變量類型的類里的方法

結構體的常見用法是可以定義協議頭部里的各種字段,而對結構體里的元素賦值后,需要把報頭以數組的形式發出去,結構體和數組的轉換,在capl中也是提供了方法的

 

 

 計算機系統為了簡化處理器與內存之間的傳輸,以及提升讀取數據的速度,對數據在內存中的存儲的位置進行了限制,要求是某個數k的倍數,這就是所謂的內存對齊

結構體中的元素由於大小不一,就需要設置這個k值

capl中用_align()來設置對齊方式,只允許使用值1、2、4、8,默認是8

_align(2) struct Point2 
{
  byte x;    // offset 0, size 1, (alignment 1)
  qword y;   // alignment 2, offset 2, size 8, padding before: 1
};         // size 10, alignment (of the struct) 2

設置對齊方式,並不意味着結構體的長度/大小發生了變化,可以用__size_of(struct Data)來獲取結構體長度,注意傳入的參數是結構體而非結構體變量

6.枚舉

結構體類型是對不同變量的定義,而枚舉類型是對不同值的定義

怎么說,舉個例子

某校統計學生信息,各班報上來的信息有

名字:xxx
年級:xxx

姓名:xxx
年齡:xxx

稱呼:xxx
歲數:xxx

這樣統計到一起時會顯得雜亂無序

聰明的校長想到了可以用結構體來定義各信息的變量名

struct INFO
{
  char name[10];
  int age;
};  

 

這樣我在統一的時候只需要聲明這個結構體變量,然后調用里面的元素變量即可實現統一

雖然解決了變量的統一,但是對於有些值又可能造成不統一,比如在統計性別時,有的班級用男/女,有的班級用公/母,有的班級用雌/雄,這又要如何統一呢?

就可以用枚舉類型,把值固定

enum GENDER
{
  male = 1,
  female = 0
}; 

用關鍵字enum定義枚舉,枚舉可以賦值,也可以不賦值,如果不賦值,則第一個元素默認0值,后面依次加1  

這里有個注意點,里面的元素用逗號隔開,最后一個元素后面不需要符號

枚舉里的值可以直接使用,無需聲明枚舉變量后調用,這點貌似和C#不同

int i;
i = male; 

7.關聯字段

在capl中叫Associative Fields,我大概的了解了下,和字典類型相似,也是通過鍵值對的方式,快速訪問值

int m[float];
m[3.1] = 2;
m[4.3] = 5;

鍵的數據類型可以是long、int64、float、double、字符換和枚舉,值的數據類型就是簡單的數據類型都可以,包括枚舉和結構體  

關聯字段的大小可以動態增加或減小,你也可以在聲明時指定初始大小

int m[float, 30];  //為30個元素保留的初始空間

當然,它也提供了幾種方法 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

上面的例子,x放在0這個位置的內存上,它只占有一個字節,y如果緊挨着它,放在了1的位置上,就不行了,因為1不是2的倍數,所以它只能放在2的位置上,1的位置就需要空着

設置對齊方式,並不意味着結構體的長度/大小發生了變化,可以用__size_of(struct Data)來獲取結構體長度,注意傳入的參數是結構體而非結構體變量

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM