作者:Lucio Di Jasio,Microchip公司 簡(jiǎn)介 Raspberry Pi系列不久前通過(guò)全新的Raspberry Pi Zero W1(2017年2月)擴充了產(chǎn)品線(xiàn),這是一臺支持無(wú)線(xiàn)連接的個(gè)人計算機,售價(jià)僅10美元。對于業(yè)余愛(ài)好者、制造商、工匠和黑客而言,它的意義非同尋常。是的,我們之中很少有人真正嘗試做好我們的工作,即設計真正的(電子)產(chǎn)品!當我最近觀(guān)看Eben Upton的視頻公告時(shí),我忍不住想起早年的經(jīng)歷。那是80年代中期,我買(mǎi)不起BBC電腦,也負擔不起奢侈的Amiga。但我花光所有的錢(qián)購買(mǎi)了Sinclair ZX Spectrum。因此,Eben努力實(shí)現“讓所有人都買(mǎi)得起”的目標確實(shí)讓我產(chǎn)生了共鳴。 一臺功能強大的個(gè)人計算機塞進(jìn)一塊小巧的印刷電路板(PCB)上,確切地說(shuō)是6 x 3 cm的印刷電路板,達到這種小尺寸的新記錄著(zhù)實(shí)讓我驚嘆。經(jīng)過(guò)進(jìn)一步思考,我經(jīng)常想弄清楚是否正是Spectrum的簡(jiǎn)約及其諸多限制促使我深入研究計算機并最終沉醉于這一奇妙領(lǐng)域——軟件和硬件之間的邊界,我們今天稱(chēng)之為嵌入式。 小型片上系統 Raspberry Pi Zero設計基于片上系統(SoC)(BCM2835),其中包括一個(gè)1 GHz ARM內核和一個(gè)圖形處理單元(GPU)、一個(gè)視頻接口、多個(gè)串行接口(USB、UART、SPI和I2C)以及一個(gè)外部存儲器接口,用于管理運行Linux操作系統(OS)所需的大容量RAM(512 MB DDR2)和大容量存儲卡(SD卡)。對于單芯片器件來(lái)說(shuō),這些都是令人印象深刻的功能,特別是與我年輕時(shí)看到的早期個(gè)人計算機相比。我們可能會(huì )爭辯,與目前在各種嵌入式控制應用中常用的最新簡(jiǎn)單型單片機相比,這并非不成比例。雖然時(shí)鐘速度和處理能力都要低得多(從10 MHz到100 MHz不等),但今天所有小型單片機本身都是真正的小型片上系統奇跡。正如您對單片機期望的那樣,所有RAM和閃存都位于芯片上。存在串行接口(USB、UART、SPI和I2C),但也集成了所有電源調節和電壓監控電路。片上通常有五個(gè)或更多不同的(精密)振蕩器,以便獲得更大的靈活性并控制功耗。此外,還有幾個(gè)具有大輸入/輸出多路開(kāi)關(guān)的模擬外設(ADC、DAC、運算放大器和模擬比較器......),取代了Raspberry Pi幻想視頻中的功能,一直以來(lái)反映出偏愛(ài)嵌入式超過(guò)計算的設計選擇中的顯著(zhù)不同。 事實(shí)上,當Raspberry Pi用戶(hù)需要與現實(shí)世界連接時(shí),對于使常用LED閃爍等最平和I/O應用以外的應用而言,由更小的單片機(實(shí)際上通常為8位單片機)通過(guò)“帽子”(小型子板)提供必要的I/O接口和所需電壓轉換并不意外。 我不想在兩個(gè)截然不同的世界之間將這種不公平的對比一直拖下去,但我必須指出,在支持開(kāi)發(fā)人員方面,兩者有一個(gè)共同關(guān)注的問(wèn)題:“控制復雜性”,最終“吸引新用戶(hù)”。毋庸置疑,它們的解決方案類(lèi)似,但終究有所不同。 這兩個(gè)平臺都是由提供免費軟件工具開(kāi)始,包括集成開(kāi)發(fā)環(huán)境(IDE)、編譯器、鏈接器、模擬器、調試器(在專(zhuān)業(yè)版中提供,只需少量費用)、或多或少的開(kāi)放式中間件和(RT-)OS以及一小部分硬件(板)選項。 兩個(gè)陣營(yíng)(嵌入式計算和通用計算)之間的差異比您想象的要小。兩者最終都依賴(lài)于類(lèi)似的(如果不相同)工具鏈,這些工具鏈大部分都基于GNU。在中間件級別,一旦您正確抽取下級(下至金屬)驅動(dòng)程序層,開(kāi)源選項會(huì )再次變得極其相似。操作系統級別的差異最大,因為許多單片機將很愿意運行RTOS,但無(wú)法承受完整Linux內核的負擔。這反映了真正的行業(yè)差異。實(shí)時(shí)是操作系統“工作說(shuō)明”的一部分。 膨脹 查看文檔時(shí)會(huì )發(fā)現,兩者的復雜度在膨脹。我最喜歡的一個(gè)例子是基于流行8位PIC架構的小巧而簡(jiǎn)單的單片機。PIC16F1619經(jīng)常用于控制小家電,為此,它將小容量閃存(16 KB)封裝在20引腳微型封裝中,具有十幾個(gè)數字外設接口和幾乎同樣多的模擬支持模塊。其數據手冊長(cháng)達650頁(yè),之后還增加了特性數據、表和圖2。 此小型SoC上提供的一些外設(例如信號測量定時(shí)器)需要長(cháng)達50頁(yè)的篇幅才能適當記錄。這幾乎是描述實(shí)際PIC內核及其整個(gè)指令集所需頁(yè)數的兩倍。 在Raspberry Pi方面,如果只是按比例放大(10倍),則問(wèn)題類(lèi)似,因為有多個(gè)數據手冊需要考慮,每個(gè)數據手冊只記錄片上系統硬件組件的一部分(SoC外設、GPU和內核),內核單獨占用超過(guò)750頁(yè)的篇幅。 嵌入式軟件架構 很明顯,沒(méi)有人能夠閱讀或跟上如此龐大的信息量。特別是嵌入式開(kāi)發(fā)人員,他們總是承擔著(zhù)極大的壓力,需要在更短的時(shí)間內完成應用,以實(shí)現最快的產(chǎn)品上市速度。常見(jiàn)的解決方案是使用分層架構對應用進(jìn)行分區,并使用標準化外設庫來(lái)抽取硬件詳細信息。這些層可以整齊地形成協(xié)議棧,其中“應用”位于硬件抽象層(HAL)的頂部。實(shí)際上,可以進(jìn)一步細化此圖片來(lái)完全識別HAL,HAL上方的中間件層將負責實(shí)現諸如網(wǎng)絡(luò )、文件系統和圖形UI(如果存在/需要)一類(lèi)的通用服務(wù)/功能。 ![]() 圖1:嵌入式應用的軟件協(xié)議棧 注:通常通過(guò)從HAL分離驅動(dòng)程序層和電路板支持層來(lái)進(jìn)一步細化協(xié)議棧,但是在以下考慮中,我們不需要詳細到這種程度。 此軟件架構直接來(lái)源于“計算”領(lǐng)域,可以很好地對大多數通用案例進(jìn)行建模。遺憾的是,由于它適用于嵌入式應用,因此有兩個(gè)基本缺點(diǎn): • 只要重點(diǎn)放在頂層中間件層提供的標準功能上,分層架構就可以簡(jiǎn)化文檔篇幅過(guò)長(cháng)的問(wèn)題。在應用范圍的底端,當中間件層(如果存在)非常薄時(shí),結果大多比較模糊。開(kāi)發(fā)人員必須依賴(lài)以大型應用編程接口(API)形式存在的HAL文檔,這份材料的篇幅同樣較長(cháng)(可達數千頁(yè)),但始終未真正研究器件的任何細節。出現問(wèn)題時(shí),他/她將身陷窘境或被迫深入研究陌生領(lǐng)域和大量代碼。 • HAL層為支持標準中間件服務(wù)提供了巨大幫助,但由于其性質(zhì)極其嚴格,因此最終會(huì )清除特定器件的任何獨特差異化功能。否則,這些獨特功能可以為特定應用提供技術(shù)優(yōu)勢,并且可能成為選擇特定器件型號的原因。 • 在應用范圍的頂端,中間件層非常厚,例如Raspberry Pi,僅Linux OS內核就添加了數百萬(wàn)行代碼來(lái)應對問(wèn)題3。雖然可以說(shuō)這是開(kāi)源代碼,但對于希望自己永遠不必深入了解到如此程度的普通開(kāi)發(fā)人員而言,它幾乎無(wú)法帶來(lái)安慰。 讓計算機盡其所能! 最終,Raspberry Pi開(kāi)發(fā)人員將能夠依靠“計算”性能帶來(lái)的巨大收益和小電路板提供的大量資源。標準Linux操作系統的便利性遠不止彌補API的復雜性和廣泛性。 我最關(guān)心的是全新小型SoC的開(kāi)發(fā)人員:現代單片機用戶(hù)。對于他們而言,使用標準化HAL的好處減少了,因為性能存在損失,而且堆疊軟件架構使獨特的功能變得單一。 用于快速開(kāi)發(fā)的新一代軟件工具代表了擺脫這一難題的巧妙方式。這是最近出現在嵌入式控制市場(chǎng)中的一種新型代碼生成器或配置器。盡管最初時(shí)持有明顯(但通常合理)的懷疑態(tài)度,但事實(shí)證明,這些工具不僅有效,對于任何嚴格的嵌入式開(kāi)發(fā)人員也必不可少。 我們發(fā)現的顯著(zhù)特征包括: - 完全集成在常見(jiàn)的IDE中,這有助于其了解項目上下文:型號(器件編號)選擇和中間件庫感知。 - 支持獨特和復雜的外設。例如,先前示例中提到的信號測量定時(shí)器(SMT)可以在單個(gè)頁(yè)面/對話(huà)框中直觀(guān)地呈現給用戶(hù),其中僅包含少數滾動(dòng)列表、復選框和一些直觀(guān)選項。有關(guān)來(lái)自Microchip的PIC單片機的旗艦快速開(kāi)發(fā)工具M(jìn)PLAB®代碼配置器(MCC)4的屏幕截圖,請參見(jiàn)圖2。 ![]() 圖2——MPLAB代碼配置器:信號測量定時(shí)器選項 - 利用模板引擎,將配置選項轉換為一小部分完全自定義的函數。這意味著(zhù)只需通過(guò)少量待學(xué)習的函數以及一致且直觀(guān)的命名約定便可生成最小API。函數定制保證大多數硬件抽象是在編譯時(shí)(實(shí)際上在編譯前)靜態(tài)執行的。這有助于減少傳遞到每個(gè)函數所需的參數列表,從而提高性能和代碼密度。有關(guān)MPLAB代碼配置器的典型簡(jiǎn)約用例,請參見(jiàn)列表1。 - 輸出由非常短的(C語(yǔ)言)源文件組成,這些源文件可由用戶(hù)全面檢查(可將其作為一次學(xué)習機會(huì )),但也會(huì )經(jīng)過(guò)專(zhuān)家進(jìn)一步手動(dòng)優(yōu)化,F代化的代碼生成器將其代碼與用戶(hù)代碼靈活地混合,既可保持完整性,也允許充分利用寶貴的高級硬件功能。 void SMT1_Initialize(void) { // CPOL rising edge; EN enabled; SPOL high/rising edge enabled; SMT1PS 1:1 Prescaler; … SMT1CON0 = 0x80; // SMT1MODE Counter; SMT1GO disabled; SMT1REPEAT Single Acquisition mode; SMT1CON1 = 0x08; // SMT1CPRUP SMT1PR1 update complete; SMT1TS not incrementing; RST SMT1TMR1 update complete … SMT1STAT = 0x00; SMT1CLK = 0x00; // SMT1CSEL FOSC; SMT1WIN = 0x00; // SMT1WSEL SMTWINx; SMT1SIG = 0x00; // SMT1SSEL SMTxSIG; SMT1PRU = 0x00; // SMT1PR16 0x0; SMT1PRH = 0x00; // SMT1PR8 0x0; SMT1PRL = 0x00; // SMT1PR0 0x0; } void SMT1_DataAcquisitionEnable(void) { SMT1CON1bits.SMT1GO = 1; // Start the SMT module by writing to SMTxGO bit } void SMT1_SetPeriod(uint32_t periodVal) { // Write to the SMT1 Period registers SMT1PRU = (periodVal >> 16); SMT1PRH = (periodVal >> 8); SMT1PRL = periodVal; } 列表1——由MCC生成、用于配置SMT外設的源文件(smt1.c)部分 從根本上說(shuō),代碼配置器/生成器可將“計算機”執行的操作做到最好。構建HAL是硬件外設配置重復且容易出錯的階段,通常會(huì )導致在數據手冊中花費大量時(shí)間進(jìn)行乏味的搜索,現在,這一階段現已然消失或顯著(zhù)縮短,只留下一些更加趣味橫生、啟發(fā)思維的探索與創(chuàng )造時(shí)間。 事實(shí)上,用戶(hù)可以從同一個(gè)用戶(hù)界面了解特定的硬件外設功能,從根本上消除(或至少極大減少)對數據手冊的需求。 硬件抽象層成為項目的靈活部分,實(shí)際上可以根據需要頻繁、快速地重新生成,從而優(yōu)化應用性能。 十(二進(jìn)制)行代碼 處理完(外設)配置后,可將注意力立即集中到應用上,這是設計中更智能的部分(在應用層上),這一部分位于“主循環(huán)”之內,而不是之前。 最后要說(shuō)的是,憑借代碼生成器,即使在嵌入式領(lǐng)域中,經(jīng)典的“Hello World”示例(總是轉換為使LED閃爍)也會(huì )成為令人耳目一新的兩行代碼練習! LED_Toggle(); __delay_ms(500); 列表2——為創(chuàng )建第一個(gè)嵌入式“Hello World”而需要輸入的短短兩行代碼 您將能夠在我最近出版的書(shū)中找到(20個(gè))更多關(guān)于同樣有效利用快速開(kāi)發(fā)工具的實(shí)例:“In 10 Lines of Code”5。 對抗復雜性 在小型單片機發(fā)展成為小型SoC或者個(gè)人計算機縮小為Raspberry Pi的過(guò)程中,不僅會(huì )浪費時(shí)間和造成認知負擔,還會(huì )在我們操作無(wú)法完全理解/掌握的系統時(shí)引入漏洞。 復雜性不是技術(shù)進(jìn)步的必然結果,F代化的代碼配置器/生成器可以通過(guò)擴展我們的軟件開(kāi)發(fā)流程、實(shí)現自動(dòng)化并最終恢復我們對快速增長(cháng)的可用功能/選項數量的掌握來(lái)幫助我們。 鏈接 1- RaspberryPi ZeroW公告。https://www.raspberrypi.org/blog/raspberry-pi-zero-w-joins-family/ 2- PIC16F1619數據手冊。http://microchip.com/pic16f1619 3- Linux內核中的代碼行。https://arstechnica.com/business/2012/04/linux-kernel-in-2011-15-million-total-lines-of-code-and-microsoft-is-a-top-contributor/ 4- MPLAB代碼配置器。http://microchip.com/mcc 5- In 10 Lines of Code。http://blog.flyingpic24.com/10lines 個(gè)人簡(jiǎn)歷 Lucio Di Jasio是Microchip的EMEA業(yè)務(wù)開(kāi)發(fā)經(jīng)理。過(guò)去18年來(lái),他一直在公司8位、16位和32位部門(mén)擔任各種技術(shù)和營(yíng)銷(xiāo)職位。作為一位固執己見(jiàn)的多產(chǎn)技術(shù)作家,Lucio發(fā)表了大量文章和多部有關(guān)嵌入式控制應用編程的書(shū)籍。憑借對飛行的熱情,他獲得了FAA和EASA私人飛行員執照證書(shū)。您可以在他的博客上閱讀更多關(guān)于Lucio最新書(shū)籍和項目的信息:http://blog.flyingpic24.com |