两万字的CAPL语法基础,一篇文章带你入门
- 🍅 我是螞蟻小兵,專注于車載診斷領域,尤其擅長于對CANoe工具的使用
- 🍅 尋找組織 ,答疑解惑,摸魚聊天,博客源碼,點擊加入👉【相親相愛一家人】
- 🍅 玩轉CANoe,博客目錄大全,點擊跳轉👉
📘前言
-
🍅 本章內容,面向CAPL初學者,超過兩萬字,超全超詳細。
-
🍅 本節內容大量引用,翻譯下面的Vector 官方文檔:capl_programming ,資料我放在下方公眾號網盤了,有需自取!
目錄
- 📘前言
- 📙1 CAPL 簡介
- 📙2 CAPL 語法基礎
- 🍅2.1 CAPL和C語言的主要不同點
- 🍅2.1 CAPL和C語言中等價的函數
- 🍅2.2 注釋
- 🍅2.3 變量的命名規范
- 🍅2.4 區分大小寫
- 🍅2.5 CAPL 關鍵字
- 🍅2.6 CAPL 支持的數據類型
- 🍅2.7 變量聲明
- 🍅2.8 數據類型轉換
- 🍅2.9 常量
- 整形
- 浮點數
- 字符
- 字符串
- 宏定義
- 🍅 2.10 數組
- 🍅 2.11 枚舉類型
- 🍅 2.12 結構體數據類型
- 🍅 2.13 message
- 🍅 2.14 定時器
- 🍅 2.15 運算符
- 2.15.1 算數運算
- 2.15.2 賦值運算符
- 2.15.3 布爾運算符
- 2.15.4 比較運算符
- 2.15.5 位運算符
- 2.15.6 三目運算符
- 2.15.7 其它運算符
- 2.15.8 不支持運算符
- 2.15.9 運算符優先級
- 🍅 2.16 控制語句
- 2.16.1 if 語句
- 2.16.2 if else 語句
- 2.16.3 Switch 語句
- 2.16.4 While 循環語句
- 2.16.5 do...while 循環語句
- 2.16.6 for 循環語句
- 2.16.7 break 語句
- 2.16.8 continue 語句
- 2.16.9 return 語句
- 🍅 2.17 函數
- 🌎總結
📙1 CAPL 簡介
-
CAPL(發音為“kapple”),是 Communication Access Programming Language 的縮寫。CAPL是基于C語言開發的,專門用于CANalyzer和CANoe工具環境,但是CAPL簡化了C語言,移除了復雜的指針概念,和一些不常用的關鍵字等,也融入了一些C++的概念,比如函數重載等。就學習難度而言 CAPL < C< C++。
-
CANalyzer或CANoe工具本身無需CAPL程序,就足以執行簡單的測量和分析。采用CAPL程序,大大擴展了CAN通信的測量和分析。
如果沒有CAPL,該工具無法執行的是涉及計時的分析。CAPL可以使分析更加高效 -
CAPL 腳本是基于事件驅動的,和常規語言不同,CAPL沒有 main()函數,沒有程序入口,任何事件都有可能觸發CAPL腳本的執行,比如,按鍵事件,定時器事件,執行測試等;如果沒有事件發生,那么CAPL程序是“閑置的”。
-
任何語言都需要編譯之后才能運行,我們編寫CAPL 的IDE叫做 CAPL Browser ,是CNAoe 整個開發環境的一部分組件;因為CAPL Browser的整體結構基于事件的概念,并且是專門組織的圍繞不同的事件類,軟件開發過程比傳統的組織要簡單得多C程序。關于CAPL的事件結構更詳細的解讀,參考后面章節博客內容。
📙2 CAPL 語法基礎
🍅2.1 CAPL和C語言的主要不同點
- 下圖可以看出,C語言支持很多概念,CAPL都舍棄掉了,或者只取其一小部分支持,讓CAPL語言更加簡便和易懂
- 比如CAPL是基礎事件驅動的,所以不需要main()函數入口
- 持指針操作,宏定義,頭文件都不在支持
- 下圖有點老,博主基于CANoe 11版本,枚舉和結構體類型都是支持的。
- 在c語言中,使用函數之前,必須要進行聲明,而CAPL是不需要的。
Note:
1,在CAPL中,默認所有的局部變量都是靜態的,在C語言中,需要用關鍵字static 修飾的變量才是靜態的。這一點新手在寫腳本要特別注意 點擊,了解 CAPL腳本中關于 局部變量 容易忽略的一點
2,void 在CAPL中只支持函數返回值類型,表示函數沒有返回值
3,CAPL中使用了一些標準的C函數。這些函數通常是數學函數或字符串函數(例如,abs(),strncpy())已經在CAPL內部預定義了。
4,CAPL沒有完整的ANSI C標準庫,但它有CAPL特有的庫,稱為CAPL dll。dll編程需要有一定的編程經驗
5,字符串數據類型在CAPL中不支持;但是,您可以使用字符數組(例如,char temp[6]= " Hello "😉。
🍅2.1 CAPL和C語言中等價的函數
- 對于C程序員來說,了解一些等價的函數是很有幫助的。下面是一個類似的簡明列表函數,但有關CAPL函數如何使用的更多詳細信息,請參閱CAPL函數參考手冊。
🍅2.2 注釋
- CAPL 的注釋方式和大多數語言都一樣,都是通過 // 或者 /**/ 來實現的,下面四種注釋方法都是合法的。
- CAPL Brower中注釋代碼的默認快捷鍵 選中你要注釋的代碼,先按住組合鍵 Ctrl + K ,然后在按組合鍵Ctrl +C ; 解除注釋是 先按住組合鍵 Ctrl + K ,然后在按組合鍵Ctrl +U ;
🍅2.3 變量的命名規范
-
變量名、函數名和數組名可以由字母和數字和下劃線組成,但是首字母不能是數字
-
下面的命名都是合法的:
sum
number_of_units
J5x7
_sysflag -
下面的命名都是不合法的:
int // because it is a reserved keyword
sum$value // the $ is not a recognized character
3Times // because a variable name cannot begin with a number
number of units // because spaces are not allowed
🍅2.4 區分大小寫
-
在使用CAPL編寫時,一定要記住,對于用戶定義的變量,小寫字母和大寫字母是不同的變量
-
下面三個變量是三個不同的變量
input_1
Input_1
INPUT_1 -
但是CAPL支持的關鍵字是不區分大小寫的,比如 INT a; 和int a;是一樣的。
🍅2.5 CAPL 關鍵字
- 關鍵字不能用來命名變量或函數。CAPL使用C編程中保留的關鍵字語言。但是,CAPL不支持一些常見的C關鍵字。
下面是保留關鍵字的列表,包括CAPL支持的和不支持的關鍵字 - 本圖較老,emum和struct現在是支持的。
🍅2.6 CAPL 支持的數據類型
- 下表列出了支持的部分數據類型,不全,不過足以介紹CAPL支持的基本數據類型,以及所占的字節數,還有是是有符號數等等。message 和timer等是CAPL獨有的數據類型,這里不描述
🍅2.7 變量聲明
- CAPL 變量有局部變量和全局變量,在CAPL 中Variables中定義的是全局變量
- 數據類型float和double都是占8個字節,它們指定符合IEEE的64位浮點數標準,它們彼此兼容。
- 變量的初始化在聲明期間是可選的,定義的時候如果沒有初始化,
整形數據則默認是0;
char 型默認是null ;
message 類型默認的數據段是0;
定時器timer ,不需要初始化 - 下面的變量聲明是合法的
🍅2.8 數據類型轉換
- CAPL支持類型轉換,隱形和顯性都可以
-下面 第一個賦值語句使用隱形轉換,即將1.6和1.7添加到結果3.3,但是sum是整形,所以自動截斷,結果就是3
-下面 第二個賦值語句使用顯性轉換,即1+1 =2 ,最后結果就是2
🍅2.9 常量
- 初始化一個變量意味著給它賦一個初始值或開始值。在CAPL中,這可以在同一行中完成變量聲明。當值在聲明期間賦值時,它們被視為常量
整形
- 整形可以是十進制和十六進制
浮點數
- 浮點數可以是十進制數,或者科學計數法,以下都是合法的
字符
- 字符常量 是用單引號,括起來的一個字符
- CAPL支持使用ASCII字符集。上面的三個字符賦值可以用十六進制分別
字符串
- 字符串常量由一系列由雙引號括起來的一個或多個連續字符組成。
- 字符串存儲在char類型的數據元素數組中。最后一個元素包含空字符\0,即用于指示字符串的結束。
- 要確保字符串數組定義時的大小總是字符串長度 + 1,因為結束符\0也占用一個字符
- 如果已經定義過了一個字符串數組,不可以直接給它賦值的,下面代碼時不允許的
- 可行的一種方法,是通過CAPL自帶的字符串操作函數實現
宏定義
- 在C語言中,下面代碼是合法的,但是在CAPL中是不可以的。
🍅 2.10 數組
-
數組時同一種數據類型的集合,元素必須小于等于指定的大小
-
下面時26個字母,但是我們必須定義27個大小,因為數據類型時char , 結束符\0要占一個字節
char alphabet[27] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
我們通過下表索引可以獲取數組中的數值,比如 alphabet[0] 就是 ‘A’ -
整形或者浮點型數組,大小可以和聲明的元素數量一致,比如
int sample_data[4] = { 100, 300, 500, 600 }; -
如果,定義時,數組沒有完全舒適化,其余的用默認值0填充
int sample_data[10] = { 100, 300, 500, 600 }; -
也可以定義二維數組
int M[4][5] = {
{ 10, 5, -3, 17, 82 },
{ 9, 0, 0, 8, -7 },
{ 32, 20, 1, 0, 14 },
{ 0, 0, 8, 7, 6 }
}; -
要確定數組中元素的數量,可以使用elCount()函數,如下面的例子所示:
nt i, j;
for ( j = 0; j < elCount(array); j++ )
for ( i = 0; i <= elCount(array[j]); i++ )
. . .
🍅 2.11 枚舉類型
- 枚舉類型在CAPL中定義的方式與在C中完全相同
- 定義完成后,可以直接使用enum的成員變量
- 當對枚舉類型初始化變量后,有兩種方法給枚舉變量賦值,如下腳本
- 可以通過 enum.Name() 可以獲取變量當前值對應的元素名字
🍅 2.12 結構體數據類型
- 結構體在CAPL中定義的方式與在C中完全相同
- -定義結構體變量時,完成初始化
- 定義結構體變量時,沒有初始化,后面再賦值
🍅 2.13 message
- message 是CAPL獨有的數據類型,可以用來仿真,改寫,創建報文等,是CANoe 仿真測試的比較核心內容
- message ,有豐富的屬性和相關方法,詳情需要參考help文檔了,不做深入探討
- 一下代碼將向總線上發送一幀ID = 100 的報文
🍅 2.14 定時器
- 由于CAPL被設計為提供事件驅動的環境,計時器提供了一種簡單的觸發周期性的方法事件。CAPL允許設置無限多個用戶定義的計時器。
- CAPL 提供兩種定時器: 毫秒計時器(msTimer) 和 秒計時器(timer),必須再全局變量中定義定時器
-
使用一個定時器分一下三個步驟:
- 聲明一個計時器變量
- 在事件過程(preStart 除外)或用戶定義的函數中預先設置計時器
- 為該計時器定義一個on timer 事件
-
下面代碼,是一個簡單但是完整的毫秒定時器的使用方法,目的是案件‘a’觸發后,開啟定時器,20ms后發送 ID =100的報文
- 周期定時器:下面代碼周期為100ms的發送ID=0x555的報文
- 如果定時器還沒被觸發,你可以通過setTimer() 函數,重置該定時器
- 如果定時器還沒被觸發,你也可以通過cancelTimer() 函數來取消該定時器
🍅 2.15 運算符
- CAPL的運算符大多數和C都一樣,也進行了一些刪減
- CAPL的運算符包括下面幾大類
算數運算
賦值運算
關系運算
布爾運算
位運算
混合運算
2.15.1 算數運算
-
下圖是CAPL支持的算數運算符,包括加減乘除,取模等,完全和C語言一樣
-
下面一些算數運算符的使用
2.15.2 賦值運算符
- 下圖是CAPL支持的賦值運算符,完全和C語言一樣。
- 下面一些賦值運算符的簡單使用
2.15.3 布爾運算符
- 下圖是CAPL支持的布爾運算符,完全和C語言一樣。
- 下面一些布爾運算符的簡單使用
2.15.4 比較運算符
-
下圖是CAPL支持的比較運算符,完全和C語言一樣。
-
下面一些比較運算符的簡單使用
2.15.5 位運算符
- 下圖是CAPL支持的位運算符,完全和C語言一樣。
- 下面一些位運算符的簡單使用
2.15.6 三目運算符
- 下圖是CAPL支持的三目運算符,完全和C語言一樣。
- 返回值:先求表達式 1 的值,如果為真,則執行表達式 2,并返回表達式 2 的結果;如果表達式 1 的值為假,則執行表達式 3,并返回表達式 3 的結果
2.15.7 其它運算符
- 下圖是CAPL支持的運算符,[]可以用來數組索引取值, 點 表示結構體的成員,這在CAPL語言中很常見,不止用于結構體的成員變量,很多Object都有成員
- 比如message數據類型
2.15.8 不支持運算符
- 下圖是CAPL支持的運算符,& 在CAPL中局部支持,可以用來地址傳參,比如 void function(int & dl),可以在函數內部改變傳入的變量
2.15.9 運算符優先級
- 下圖是我在網上找的C語言的運算符優先級,因為CAPL語言基于C,大部分都適用。
- 沒有必要去記哈,貼出來給個參考。如果代碼需要復合運算的時候,都加上括號,既方便閱讀代碼,也不用擔心優先級的問題。
🍅 2.16 控制語句
- CAPL支持的控制語句和C語言中一樣,包括 if else ,do ,while ,for 等
2.16.1 if 語句
if (expression) statement;
- if 括號內的表達式為真,或者非0,則執行if 下面的語句
- 如果沒有花括號,則只執行if下面的第一行語句
- 如果有花括號,執行if下面花括號的所有語句
2.16.2 if else 語句
-
如果下面表達式為真或者非0,則執行語句塊1,否則執行語句塊2
if (expression) statement_1
else statement_2 -
if else 的典型用法
2.16.3 Switch 語句
- 下面是switch 語句的偽代碼表示:
- switch (expression) 中的 expression應該是個 整形變量或者字符變量或者枚舉類型變量
- case value1: 每個case分支中的value應該是個 整形或者字符常量,注意case value后面有個冒號
- default ,當所有分支都不能匹配的時候,會執行default內的代碼
- 當遇到 break 語句時,switch 終止,控制流將跳轉到 switch 語句后的下一行。
- 不是每一個 case 都需要包含 break。如果 case 語句不包含 break,控制流將會 繼續 后續的 case,直到遇到 break 為止。
2.16.4 While 循環語句
- Capl 語言中 while 循環的語法:
- 在這里,statement(s) 可以是一個單獨的語句,也可以是幾個語句組成的代碼塊。
- condition 可以是任意的表達式,當為任意非零值時都為 true。當條件為 true 時執行循環。 當條件為 false 時,退出循環.
2.16.5 do…while 循環語句
- Capl 語言中 do…while 循環的語法:
- 在這里,statement(s) 可以是一個單獨的語句,也可以是幾個語句組成的代碼塊。
- condition 可以是任意的表達式,當為任意非零值時都為 true。當條件為 true 時執行循環。 當條件為 false 時,退出循環.
- 不像 for 和 while 循環,它們是在循環頭部測試循環條件。在 C 語言中,do…while 循環是在循環的尾部檢查它的條件。
- do…while 循環與 while 循環類似,但是 do…while 循環會確保至少執行一次循環。
- 還要注意while 表達式最后是分號結尾的
2.16.6 for 循環語句
- Capl 語言中 for 循環的語法:
-
下面是 for 循環的控制流:
1,init 會首先被執行,且只會執行一次。您也可以不在這里寫任何語句,只要有一個分號出現即可。CAPL語句不允許在這個位置定義新的變量,而C語言是可以的
2,接下來,會判斷 condition。如果為真,則執行循環主體。如果為假,則不執行循環主體,且控制流會跳轉到緊接著 for 循環的下一條語句。切記不要讓condition永遠為真,否則會是個死循環的
3,在執行完 for 循環主體后,控制流會跳回上面的 increment 語句。該語句允許您更新循環控制變量。該語句可以留空,只要在條件后有一個分號出現即可。
4,條件再次被判斷。如果為真,則執行循環,這個過程會不斷重復(循環主體,然后增加步值,再然后重新判斷條件)。在條件變為假時,for 循環終止。 -
下面三個代碼都是可以的
2.16.7 break 語句
-
Capl 語言中 break 語句有以下兩種用法:
當 break 語句出現在一個循環內時,循環會立即終止,且程序流將繼續執行緊接著循環的下一條語句。
它可用于終止 switch 語句中的一個 case。 -
如果您使用的是嵌套循環(即一個循環內嵌套另一個循環),break 語句會停止執行最內層的循環,然后開始執行該塊之后的下一行代碼。
-
下圖是break語句在循環語句中的使用,和退出循環的過程
2.16.8 continue 語句
-
continue 語句有點像 break 語句。但它不是強制終止,continue 會跳過當前循環中的代碼,強迫開始下一次循環。
-
對于 for 循環,continue 語句執行后自增語句仍然會執行。對于 while 和 do…while 循環,continue 語句重新執行條件判斷語句
-
-下圖是continue 語句在循環語句中的使用
2.16.9 return 語句
- CAPL腳本中,不帶參數的return也可以退出循環語句
- 但是更多的使用return,是用來在函數中,返回一個值或者值的表達式
- 注意:CAPL中所有的事件處理都不返回值
🍅 2.17 函數
1, CAPL語言,選用了C語言庫的少部分函數,但是CANoe有它自己的大量的函數庫,這些函數都是專用于CANalyzer或CANoe編程環境中有用的各種專用操作。
2,CAPL的函數大致分為3類:
- 自定義的函數;不用任何聲明,在CAPL文件任意位置都可以
- CAPL內置的函數;不用像C語言那樣的要引用 #include <stdio.h>等等各種庫,已經被內置在CAPL中,隨用隨調
- DLL: 考慮到CAPL內置庫不夠用,CAPL對動態庫有很好的支持
3, 這里CAPL引入了C++的函數重載的思想,我們可以定義相同的函數名,但是要保持參數不同。
on key 'c' {printme(5.7);printme(3, "Feet"); }void printme (double num) { write("Floating point %f", num); } void printme (int num, char units[]) { write("%d %s", num, units); }4 ,CAPL為其內置函數使用一致且易于閱讀的命名約定:
- 所有標準C函數都是小寫的(例如,sin(), cos(), strlen(), strncat())
- 非標準C函數,且只有1個單詞的函數都是用小寫(例如,trigger(), outport(), inport())
- 非標準C函數,但是超過1個單詞的,除第一個單詞,其余的首字母都大寫(例如,swapInt(), timeDiff(), putValueToControl())
5, 雖然函數名是不區分大小的,但是為了保持CAPL統一的編碼規則和可讀性,建議你依據上面的規則
🌎總結
- 🚩要有最樸素的生活,最遙遠的夢想,即使明天天寒地凍,路遙馬亡!
- 🚩如果這篇博客對你有幫助,請 “點贊” “評論”“收藏”一鍵三連 哦!碼字不易,大家的支持就是我堅持下去的動力。
總結
以上是生活随笔為你收集整理的两万字的CAPL语法基础,一篇文章带你入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 河北联通烽火HG680-J机顶盒破解安装
- 下一篇: 一行代码完成模型训练,30倍加速,3毫秒