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