1 底層驅動的那些事
先說說MBD關于底層驅動的一些基本情況。
我們知道,MBD是通過建立模型來生成代碼,然而并不是所有的代碼都能建立模型,嵌入式系統中的底層驅動(Low Level Drivers,LLD)就屬于這樣的代碼。之所以底層驅動代碼不能建立模型,是因為其具有下面這樣的特征:
- 沒有明顯是數學邏輯,無法使用數學表達式表達;
- 與芯片的外設(Peripherals,例如ADC、PWM等外設)息息相關,不同的芯片可能差別很大;
- 嚴格規范的底層驅動需要滿足一定的要求,例如AUTOSAR;
- 底層驅動往往需要頻繁的調用;
- 配置底層驅動的邏輯關系往往比較復雜。
模型擅長處理的是數學問題,而底層驅動本質上是一種格式化的代碼,是一套與芯片設計、功能配置聯系緊密的流程式操作,所以不適合建模實現。
很多剛入門MBD的讀者可能并不具備嵌入式相關的基礎(學習MBD大多是機械、汽車專業的,很少有電子、自動化和計算機專業的),這里給大家看看實際的嵌入式工程中,底層驅動究竟是什么樣子的。下面這段代碼摘自NXP(恩智浦)電機控制工具包MCSPTE1AK144中的部分代碼:
int main(void)
{
McuClockConfig(); /* 配置時鐘 */
McuCacheConfig(); /* 配置緩存 */
McuPowerConfig(); /* 配置功耗模式 */
McuIntConfig(); /* 配置中斷 */
McuSimConfig(); /* 配置系統集成模塊 */
McuTrigmuxConfig(); /* 配置觸發單元 */
McuPinsConfig(); /* 配置Pin腳 */
McuLpuartConfig(); /* 配置UART(通用異步收發) */
McuAdcConfig(); /* 配置ADC */
McuPdbConfig(); /* 配置延時計時器 */
McuFtmConfig(); /* 配置PWM輸出模塊 */
FMSTR_Init(); /* 配置上位機通信模塊 */
GD3000_Init(); /* 配置預驅芯片 */
MCAT_Init(); /* 配置FOC初始化 */
for(;;){ /* 省略 */ } /* 進入死循環 */
return 0;
}
可以看到,程序在進入死循環之前,全部的工作都在進行底層配置的初始化,以ADC為例,底層配置初始化調用的底層驅動API是這樣的:
void McuAdcConfig (void)
{
/* ADC0 module initialization */
ADC_DRV_ConfigConverter(INST_ADCONV0, &adConv0_ConvConfig0);
/* ADC1 module initialization */
ADC_DRV_ConfigConverter(INST_ADCONV1, &adConv1_ConvConfig0);
/* AD4 input channel is used for PhaseA stator current sensing */
ADC_DRV_ConfigChan(INST_ADCONV0, 0, &adConv0_ChnConfig0);
/* AD7 input channel is used for DC bus voltage sensing */
ADC_DRV_ConfigChan(INST_ADCONV1, 0, &adConv1_ChnConfig0);
/* AD15 input channel is used for PhaseB stator current sensing */
ADC_DRV_ConfigChan(INST_ADCONV1, 1, &adConv1_ChnConfig1);
}
這些API由NXP的S32K1xx SDK3.0.0提供。而實際上,這些API之下還有硬件訪問層(Hardware Access Layer),在這一層完全變成了寄存器位操作,那就更沒辦法搭建模型了。
所以,一款芯片的底層驅動本身就是一套非常復雜的軟件,這樣的底層軟件不需要芯片使用者來開發,通常由芯片制造商提供,開發者直接使用即可。
在MBD中就沒有相應的解決方案了嗎?實際上是有的,這就要提到部分芯片廠商會發布的另一種MBD工具包(也稱為硬件支持包)。還是以NXP為例,NXP會隨著某一款芯片,發布其基于Simulink的 MBDT (Model-Based Design Toolbox)工具包。該工具包作為Simulink的擴展,可以實現大部分底層驅動的配置。例如NXP S32K1xx的MBDT,安裝好后在Simulink的庫中可以看到相應的底層驅動模型:
NXP MBDT底層驅動模型 - Frome NXP MBDT
而使用模型的方式,底層驅動的初始化就變成了這樣,只需要把需要初始化的模塊放置在模型中即可:
NXP MBDT底層驅動初始化 - Frome NXP MBDT
雙擊ADC0_Init模型可以編輯底層驅動的一些配置選項,例如采樣精度等參數:
NXP MBDT底層驅動配置示例 (ADC) - Frome NXP MBDT
除了上面提到的NXP,其他芯片廠商也會提供這種類似的MBD工具包,匯總如下:
最后兩家并不是芯片廠商,Arduino是開源電子原型平臺,樹莓派已經屬于微型電腦了,這說明了MBD的應用領域是可以上升到更加高級的場合,并非限于MCU領域。
當然還有很多其他家的MBD工具包,這里只列舉了部分。以后我會選擇其中的幾個家,詳細講講它們的MBD工具的使用。目前還沒發現有國內芯片廠商有提供MBD開發包的。
(題外話,實際上國內MCU廠商的開發工具鏈都不算完整,集成開發環境IDE大多也依賴第三方Keil、IAR等,編譯器也不是自己的編譯器,能提供的開發工具更少,***任重而道遠)
這些底層驅動模型調用的依然是原本設計好的底層驅動軟件,但是Simulink并不認識這些軟件,所以需要告訴Simulink真正的驅動軟件在哪里。這些底層驅動模型本質上是Simulink的S-函數,S-函數是能生成代碼的。芯片廠商底層驅動的配置通過S-函數的形式在模型中實現,S-函數中包含了用戶的配置信息,以及底層驅動的代碼。
總的來說,關于嵌入式軟件的底層驅動部分,雖然不容易建模實現,但借助芯片廠商的MBD工具包,仍然可以實現建模和自動生成代碼。
2 底層驅動為啥是MBD“禁區”?
故事講到這里,似乎很圓滿,為啥還被稱為“禁區”呢?
我在MATLAB中文論壇的基于模型設計板塊看到幾篇帖子,很有參考意義,有許多大佬在這個帖子上發表了關于底層驅動的一些觀點,比如劉杰博士(《基于模型設計》四部著作的作者)和老胡(MathWorks高級工程師)。
關于大佬們的觀點,我總結了以下幾點:
- 在Simulink中是可以實現底層驅動的,但繁瑣且效率不高;
- MBD應當重點關注上層應用和算法,沒必要做底層驅動;
- MBD的核心是算法驗證,即驗證上層應用和算法。
我們可以發現,大佬們討論的時候,都沒有提到芯片廠商的MBD工具包。但可以猜測,那時的MBD工具包應該非常不完善,達不到應用的要求,所以才會圍繞底層驅動是否值得做展開了激烈的討論。現在和那時相比,MBD工具包發展了很多,它的底層驅動模塊已經可以滿足一些簡單的應用需求,MBD工具包給的例程是可以直接下載到相應的硬件中,包括電機控制這樣的算法可以直接跑起來。
但也僅僅只是滿足一些簡單的應用需求 ,即使是現在,MBD工具包依然存在著很多局限性。
**首先,**MBD工具包的功能沒有底層驅動軟件強大,可以說,芯片廠商提供的底層驅動軟件能發揮芯片的100%功能,但MBD工具包就很難說了,芯片廠商移植了多少,就支持多少。而且芯片廠商也不會把底層驅動軟件的全部功能都移植到MBD工具包中,因為底層驅動軟件是屬于芯片廠商自己的產品,你愿意把自己的產品放在別人家的平臺(例如Simulink)上面嗎?
**其次,**目前大多數芯片廠商的底層驅動軟件已經具備了圖形化的配置界面,例如NXP的Processor Expert(PE),利用該配置工具,已經可以很友好的配置底層軟件,體驗效果并不比在Simulink中差。
**第三,**對于芯片廠商來說,它們的資源肯定是優先投放非底層驅動軟件和圖形化配置界面的開發,一款芯片的MBD工具包肯定會落后與前兩者發布。
**第四,**從我的使用經驗來看,MBD工具包并沒有底層驅動軟件靈活,在熟悉了底層驅動軟件后,遇到問題能很快定位到位置。而如果在MBD工具包的模型中遇到了問題,有時候不查看底層驅動軟件,可能很難找到問題所在,因為MBD工具包底層本身也是調用的底層驅動軟件,中間隔了一層S-函數。
**第五,**對應復雜的項目來說,使用底層驅動模塊可能會大大增加模型的復雜程度,前面提到了,底層驅動模塊是需要頻繁調用的。
**最后,**也是一個很現實的問題,除了上述提到的芯片廠商會提供MBD工具包,如果使用的芯片不提供MBD工具包呢?畢竟現在能提供MBD工具包的是少數。
所以,即使是在2020年,老胡在回復網友時依然不建議自己搭建底層驅動接口。大佬們的觀點到現在依然成立,我們在使用MBD開展項目的時候,可以不考慮底層驅動,也盡量不要涉及底層驅動。因此我把底層驅動稱作MBD的“禁區”。
3 底層驅動與模型集成
我們知道,底層驅動是連接上層算法和硬件的橋梁,如果模型中不做底層驅動,那底層驅動怎么實現呢?
按照上面的結論,我們在搭建模型的時候,并不需要將底層驅動放到模型中(當然建模時要考慮底層驅動帶來的影響,例如的ADC精度),所以生成的代碼就只有算法,我需要做的就是在模型中將這個算法的接口做好。就像下面這樣:
算法模型 - Frome aotuMBD
這樣在測試的時候,也可以直接將該模型作為參考模型進行測試,這樣也將測試和建模的工作分離開了。
算法測試 - Frome aotuMBD
接下來就是將生成的代碼和底層驅動集成在一起,這一步操作需要在IDE中進行。在IDE中我們建立好工程,利用芯片廠商的配置工具將底層配置好,然后將生成的代碼復制到工程中去,將模型生成的頭文件包含到工程當中,在需要用到算法的地方調用生成的函數接口即可。
這里只是很簡要的描述了底層驅動與模型集成的大致過程,后續我會針對不同的芯片更加詳細的展示這個過程,歡迎持續關注。
可以看到,底層驅動與模型集成是需要和代碼打交道的,但這正是目前使用MBD的主流方式。不要覺得MBD就是純粹的無代碼式開發,就目前來說,如果是產品級的設計,我們依然需要在底層驅動部分和代碼接觸,MBD工具包只能實現簡單demo性質的功能。
評論
查看更多