在之前的導出函數文章中,介紹了如何配置仿真模型并將它導出為函數:使用 Model 模塊。
案例中,我們的模型模擬的是代碼運行一次的行為。也就是說:假設這些代碼要跑在 ECU 里,當模型仿真開始ECU 啟動,這些代碼就運行,當仿真結束ECU 停止。
這是個有意思的過程,不過,要是你想仿真一些更復雜的場景,比如 ECU 多次啟動和關閉的場景呢?
這就是需要用的Initialize Function 和 Terminate Function 模塊。
下面的例子模擬了一輛車在兩種不同情況下多次啟動和關閉的場景:
a.當車在運行時,我們使用計數器累加來跟蹤記錄發動機的在它的整個生命周期里運行的全部時間。
b. 在正常關停的場景下,車鑰匙熄火,我們將累計的時間寫入一個 non-volatile 內存。所以,在下次汽車啟動的時候它還可以被讀出來。
c. 假如電池沒電了汽車也會關停,但是這時候我們就沒有機會把累計時間寫入 non-volatile 內存了。
下面我們來看看如何實現上述邏輯。
使用 Initialize 和 Terminate 事件
首先用一個簡單的計數器例子,用來模擬發動機運行時間計數:
把上圖這種形式的導出函數模型,使用一個Model 模塊引用起來。在 R2016b 里 Model 模塊的參數設置對話框里就會出現兩個新選項:
勾選這兩個選項,Model 模塊就多出兩個輸入端口,可連接 Function-call 信號(見下圖)。
作為第一次簡單嘗試,我們用一個 Stateflow chart 來仿真車鑰匙啟、停時分別啟動和關閉這個計數器 EngineRunTime。
仿真結果如下:
當車鑰匙啟動時,計數器在增長,而當車鑰匙關停時,計數器停止計數。而當車鑰匙再次啟動的時候,計數器重置了。
自定義Initialize 和 Terminate 事件
就像之前所說的,我們并不希望這個計數器在每一次車鑰匙關停的時候都重置,不然就沒法累計發動機的運行時間了。
為了保留這個計數器的值,我們這時候就可以使用 Initialization 和 Terminate 模塊了。
在 Terminate Function 內部,我們使用 State Reader 模塊來獲取當前的計數值,并保存在 Data Store 模塊里。類似的,在 Initialize Function 內部,我們可以讀取這個 Data Store 模塊,并用這個值來初始化計數器。
譯者補充:熟悉 Simulink 代碼生成的朋友都知道,EngineRunTime 模型生成代碼時,會生成 step 函數,以及相應的Initialize 和 terminate 函數。默認情況下 Initialize 函數里進行輸入、輸出以及狀態量的初始化,terminate函數里是空的。R2016b 之后,新增加的這個 Initialize 和 terminate 模塊,可以讓你顯示的定義這兩個函數里的內容。
我們來看結果:
在車鑰匙關閉和重啟后,每一次EngineRunTime 被重新調用運行時,是在持續計數的。
Reset Function
就像之前說的,我們還需要模擬由于電池電壓過低引起的車輛重啟。
這表示,在有些真實場景下,有時候計數器模型結束運行的時候,我們是沒機會往Data Store 里寫數據的。
為了模擬這種場景,我們把原來的Terminate 模塊里面的 Terminate Event Listener 模塊的事件類型從 Terminate 改為 Reset,并設置一個有含義的名字 writeNVmem。
這樣一來,模型里就不再有Terminate Function 模塊了。當仿真觸發 terminate 事件后,就會執行默認的模塊 terminate 函數。
我們重寫 Stateflow 調度器,處理這兩種關停的情況:
注意,在上面這個模型中,我們在 Model 的參數對話框里勾選了 "Show model reset ports",所以就出來了這個額外的 writeNVmem 端口。
仿真結果如下:
可以看到,在因為電池失效而引起的關停時,計數器的值并不會保存給下次重啟的時候用。
代碼生成
現在,仿真結果跟我們想要的一致了,接著我們來生成代碼。
在生成的代碼里,寫入 non-volatile 內存一般都是用戶自定義代碼來實現,或者是 Embedded target 提供的硬件服務。為了模擬這種情況,我們使用 Function call 模塊和 Simulink Function 來實現,以前的帖子有介紹過這兩個模塊的用法。
簡單來說,就是把上面 EngineRunTime 模型里的 Data Store Read/Write 模塊替換為 Function call。
另外,為了能在仿真的時候得到同樣的結果,我們使用 Simulink Function 來完成讀寫 Data Store 這個功能,跟之前在Initialize 和Terminate function 的讀寫功能一樣。
這就是整個模型的結構:
之前的帖子有介紹過,在代碼生成的時候,可以在 EngineRunTime模型里設置配置選項,告訴 Simulink 在鏈接的時候,去哪里找這個 writeEngineRunTimNV 和 readEngineRunTimNV 函數。
我們把這個導出函數模型生成如下代碼:
-
計數器
+關注
關注
32文章
2292瀏覽量
96511 -
函數
+關注
關注
3文章
4384瀏覽量
65080 -
電池
+關注
關注
84文章
11103瀏覽量
135471
發布評論請先 登錄
【案例2.36】芯片啟動異常的故障分析

MDMF304L1DAM-MINAS A6 系列 Block動作應用說明資料 -Modbus啟動- 松下

模擬電路分析技巧
示波器波形分析軟件使用指南
MHMF082L72N-MINAS A6 系列 Block動作應用說明資料 -Modbus啟動- 松下

評論