題:
C ++是否適合嵌入式系統?
Toby Jaffey
2010-06-15 20:55:50 UTC
view on stackexchange narkive permalink

這里和其他地方的常見問題。 C ++是否適合嵌入式系統?

微控制器?實時操作系統?烤麵包機?嵌入式PC?

OOP在微控制器上有用嗎?

C ++是否會使程序員離硬件太遠而無法提高效率?

Arduino的C ++是否應該(沒有)?動態內存管理,模板,異常)被視為“真正的C ++”?

(希望,此Wiki將充當包含這場潛在的聖戰的場所)

快速提問:當您說_embedded_時,您的意思是微控制器?微處理器?嵌入式x86 /嵌入式PC?
我無意發動一場聖戰;目的是要了解您的反對意見。
之前已經有幾個問題提出來了,所以我認為一個中心位置會很好。
C ++與嵌入式是一個有爭議的話題。我有很強的見解,但我認為提出問題並在得分上發揮作用是不公平的。我希望社區Wiki能夠使討論更加平衡。
我理解您為什麼這麼做,我的看法是基於使工作能夠快速好地完成的,但是我認識的大多數人都認為這是一個熱門話題,並且容易使他們的面孔變紅。
我同意@Joby,,這是100%清晰的社區Wiki ...
是的,我看錯了東西,以為別人是原始的海報。不好,清除我的評論。
這是一個不好的問題,因為在確定特定語言及其相關行李是否合適時,“嵌入式”是毫無意義的屬性。重點是小型系統與大型系統,小型系統不運行操作系統,內存有限,可能不是von-Neuman,在調用堆棧,數據堆棧上可能有各種硬件限制,您不能只是動態分配Mb甚至kb等。大多數微控制器都是“小型”系統。單板計算機通常是嵌入式的,但通常是“大型”系統。
該問題似乎暗示“ c ++ = OOP”。事實並非如此,C ++是一種多範式語言,它可以執行OOP,嚴格的過程,功能等等!
十六 答案:
Jay Atkinson
2010-06-16 08:10:46 UTC
view on stackexchange narkive permalink

是的,C ++在嵌入式系統中仍然有用。就像其他人所說的那樣,它仍然取決於系統本身,就像8位uC在我的書中可能是不行的,即使那裡有編譯器並且有人這樣做(顫抖)。即使在8位微型環境中,即使將C ++縮小到“ C +”之類,使用C ++仍然有一個優勢。我所說的“ C +”是什麼意思?我的意思是不要使用new / delete,避免異常,避免具有繼承的虛擬類,可能一起避免繼承,對模板要非常小心,使用內聯函數而不是宏以及使用 const 變量

我已經在嵌入式系統中使用C和C ++進行了十多年的工作,而我對C ++的年輕熱情肯定已經消失了由於一些現實世界中的問題而動搖了天真。我已經看到了嵌入式系統中最糟糕的C ++,我將其稱為“ CS程序員在EE世界中瘋狂”。實際上,這就是我正在與我的客戶合作以改善他們擁有的這一代碼庫的東西。

C ++的危險在於,它是一個非常強大的工具,就像一把兩刃劍,如果不正確地接受其語言和通用編程本身的教育和訓練,就會割傷您的胳膊和腿。 C更像是單刃劍,但仍然一樣鋒利。使用C ++,很容易獲得非常高級的抽象並創建混淆的接口,這些接口從長遠來看變得毫無意義,這部分是由於C ++能夠靈活地用多種不同的語言功能(模板,OOP,程序, RTTI,OOP +模板,重載,內聯)。

我完成了由C ++專家Scott Meyers進行的兩個4小時的有關C ++嵌入式軟件的研討會。他指出了有關模板的一些我從未考慮過的事情,以及它們可以幫助創建安全關鍵代碼的更多信息。關鍵是,您不能在必須滿足嚴格的安全關鍵代碼要求的軟件中包含無效代碼。模板可以幫助您完成此任務,因為編譯器僅在實例化模板時創建所需的代碼。但是,必須對它們的使用進行更徹底的教育才能正確地設計此功能,這在C語言中很難完成,因為鏈接器並不總是優化死代碼。他還演示了模板的功能,該模板只能用C ++來完成,如果NASA實施類似的系統來保護計算中的計量單位,那麼火星氣候觀察者將不會崩潰。

斯科特·邁耶斯(Scott Meyers)是關於模板和內聯的明智使用的非常大的支持者,我必須說,我仍然對模板感興趣。我傾向於迴避它們,即使他說只應將它們應用到成為最佳工具的地方。他還指出,C ++為您提供了製作非常好的接口的工具,這些接口易於正確使用,而難以錯誤使用。同樣,這是困難的部分。在您知道如何以最有效的方式應用這些功能成為最佳設計解決方案之前,必須先熟練掌握C ++。

OOP也是如此。在嵌入式世界中,您必須熟悉編譯器將要發布的哪種代碼,才能知道您是否可以處理運行時多態性的運行時成本。您還需要願意進行測量,以證明您的設計將滿足您的最後期限要求。新的InterruptManager類會使我的中斷等待時間過長嗎?還有其他形式的多態可以更好地解決您的問題,例如C可以做到的鏈接時多態,但是C ++可以通過 Pimpl設計模式(不透明指針)來實現。

我要說的就是C ++在嵌入式世界中佔有一席之地。您可以恨自己想要的一切,但它不會消失。可以用非常有效的方式編寫它,但是要比使用C來學習正確的方法要困難得多。在解決問題和表達更好的接口方面,有時它可以比C更好地工作,但是同樣,您必須教育自己,不要害怕學習方法。

這與我從其他嵌入式系統顧問那裡讀到的內容一致。我一直被教導說,使用C,您會不斷地自我削減,但是C ++中的錯誤會越來越少,但是當您搞砸了時,您會迷失方向。感謝您用我沒有的一些專業知識做出清晰的答复。
我被告知,在首先使用C ++之前,您確實需要花費時間並接受適當技術的培訓。
注意到計算機科學專業在EE領域變得瘋狂。在我的工作中,我們遇到的最糟糕的代碼是由CS專業編寫的。我們花了很多時間來教他硬件。他使用UML製作了一個結構化的系統,並使用適當的繼承等在Java中基於它構建了整個系統。它一直有效,直到發生任何更改為止,然後添加功能或進行完整的重新設計是一項糟糕的補丁工作。該代碼幾乎不可用,因為他對繼承的整體混淆不清。
不僅是蟲子會咬你,而且無法維護的代碼也會咬你。當然,當您開始使用這些純淨的C ++功能進行項目開發時,一切都會順利進行,但是如果在開發過程中不花大力氣進行重構,那麼經過2或3年的熵就會啟動。這就是我現在面臨的問題。.隨著時間的流逝,代碼在C ++中的運行速度更快。
UML和狀態機。您確實需要在http://www.state-machine.com上了解Miro Samek的內容。他建立了一個高效的系統,該系統易於重構和更改,但是確實需要花費一些時間。
這就是Java DoxaLogos中殺死我們的原因。對於我們來說,運行時錯誤是一個問題,在我們的大多數維護工作中,我們都有運行時錯誤的機會,因為我們的系統正在超過95%的負載點運行。
@Kortuk-關於“將頭先導入C ++”的另一條評論。我同意,理想情況下,您希望先花時間先學習C ++,然後再進行頭腦風暴,但有時效果並不理想。在我以前的雇主那裡,我們遇到了一種情況,我們因功能而選擇了另一部門用C ++編寫的代碼,但整個樓層都是大多數人熟悉C的EE。我是少數接受過C ++培訓的人之一時間,但不多。您可以想像隨之而來的混亂:-)
@Doxa,是的,我可以。我一直在購買書籍,並嘗試在啟動任何新系統之前給自己盡可能多的培訓。
@Kortuk。我相信您可以,而且很高興您有遠見。這就是為什麼我在大學攻讀EE時就開始在大學自己學習它的原因。我的觀點是,有時效果不佳。由於持續的“上市時間”,所有這些工程師現在都必須在C ++環境中工作,而無需任何培訓。當然,錯誤是在管理方面,而不是他們的錯。
@doxa,是的,在我之前的那個人非常聰明,幹得很好。他的代碼無法使用,原因是部署時間太短,而且功能漫長,他不得不修改內容以保持頭腦清醒。我所能做的就是戰鬥,有時甚至接受後果。
@DoxaLogos-您說避免繼承/虛擬函數是一件好事-您能解釋一下您的意思嗎?這個想法是否排除了將類寫入抽象基類接口的可能性?
這實際上取決於您的系統以及可用的內存量。您是在RAM很少的8位微型計算機上編寫代碼嗎?這樣一來,您最好避免避免在抽象接口上發瘋。如果要編寫帶有內存塊的32位嵌入式系統之類的東西,那就去吧。您真的必須權衡一下。例如,每次在該類上使用“虛擬”世界時,對於您聲明該對象的每個實例,都會獲得一個額外的指針,該指針可能是8位,16位或32位,具體取決於系統。你甚至不會意識到,伙計,
我被那個咬了嗎我可能不應該說迴避,但是更像要確保在設計中確實需要它。與查看直接的C代碼相比,C ++的問題在於它如何“隱藏”它使用的內存量,而且我什至都沒有提到STL庫,後者在使用時會很快佔用RAM。
對不起...請確保您確實需要它,並且可以在您的設計中使用它。
然後我們可以總結一下所有內容並說,在C ++中,過度設計比在C中容易得多嗎?
根據一些Google命中,我決定看看C ++如何在MSP430上工作。“ Hello world”失敗了,這真令人尷尬。iostream庫顯然太單片或其他東西,因此需要128KB的FRAM進行編譯。無論如何,這表明事情一開始就可能崩潰。
C ++具有一些非常好的功能(我會大量使用它-取決於項目),但是必須考慮的一件事是不要“過度”抽象事物所需要的紀律。這可能是維護的主要問題。
“就像一把可以割斷胳膊和腿的兩刃劍”-C也是如此。
Jason S
2010-06-21 00:53:53 UTC
view on stackexchange narkive permalink

C ++絕對適用於嵌入式系統。現在,我將是否存在良好的開發工具(或缺乏)作為我是否使用特定微處理器的主要標準。

在嵌入式系統上很好使用的C ++區域具有較低的資源成本:

  • 通過良好使用類/結構帶來的模塊化
  • 模板如果,編譯器在有效地編譯它們方面做得很好。模板是將算法重用引入不同數據類型的好工具。

確定區域:

  • 虛擬函數–我以前反對這樣做,但是資源成本非常小(每個一個vtable,而不是每個對象;每個對像一個指向vtable的指針;每個虛函數調用一個解引用操作),並且它的最大優點是它允許您要擁有一個包含幾種不同類型對象的數組,而不必知道它們是什麼類型。我最近使用了這個對像數組,每個對象代表一個I2C設備,每個對像都有單獨的方法。

不使用的區域,主要是因為運行時開銷在小型計算機上是不可接受的系統:

  • 動態內存分配-其他人已經提到了這一點,但使用動態內存分配的另一個重要原因是它表示時序不確定性;使用嵌入式系統的許多原因都是出於實時應用。
  • RTTI(運行時類型信息)-內存開銷很大
  • 例外-肯定是 否,因為執行速度不佳
感謝您的輸入。有趣,非常類似於我所讀的內容。
實際上,動態內存分配是可以的,有時是不可避免的。問題是動態內存的重新分配(和後續重用)。 RTTI是記憶豬,我同意這一點。但是異常有什麼問題呢?
@WoutervanOoijen:異常的問題是,如果foo在try / catch塊內調用bar,而bar創建一些對象並調用boz,則拋出異常,系統必須以某種方式調用在將控制權返回給foo之前創建的對象bar的析構函數。除非完全禁止例外,否則bar不能知道boz是否會拋出異常,因此必須包括額外的代碼以允許這種可能性。我希望看到帶有“檢查的異常”的C ++變體來解決這個問題;如果例程可以允許異常轉義...
...必須這樣聲明,那麼編譯器只需要在此類例程的調用程序中包括異常處理代碼即可。可以肯定的是,必須添加所有必需的聲明,同時希望避免不必要的聲明,這會有些負擔,但是這將允許在有用的地方使用異常,而無需在沒有使用的地方增加開銷。
@WoutervanOoijen:順便說一句,如果我正在設計用於在ARM上進行此類異常處理的ABI,我將指定調用可能通過異常退出的例程的代碼應使R14指向所需返回地址之前兩個字節的地址(這自然會發生) (如果呼叫者在CALL指令後加上16位字)。然後,被調用的例程將通過“ add r15,r14,#2”而不是“ mov r15,r14”正常退出;通過異常ldrhs r0,[r14] /添加r15,r14,r0退出。正常退出的周期成本為零,並且沒有堆棧幀限制。
因此,有例外的問題是,當前的實施給無例外情況帶來了不可忽視的負擔。這使異常變得不受歡迎,因此實現者感覺沒有必要提高效率:(我從未研究過異常返回的詳細信息,但是從直覺上講,我已經接受了您所描述的內容。
@WoutervanOoijen:知道了。必須有效地全局啟用或禁用異常處理;如果為1%的代碼啟用,則會使所有代碼的空間效率降低,並且通常較慢。至於實現者是否想使其效率更高,則存在兼容性問題。除其他事項外,允許異常通過C或彙編代碼傳遞,要求Throw代碼可以通過要求C或C語言來找到catch。遵循嚴格的堆棧框架協議的彙編代碼,或者使用靜態位置保存必要的信息或指向它的指針。
-1
我認為不是“重寫”,而只是“使用相同的C ++編譯器重新編譯”。
@WoutervanOoijen:我的意思是“重寫”。用C ++編寫的代碼將不是問題。如果在多任務系統上,C ++例程“ foo”調用彙編語言例程“ bar”,則在調用C ++例程“ boz”之前將未知的任意內容放入堆棧中,而“ boz”會引發異常,因此系統必須找到foo的堆棧框架。沒有修改彙編語言例程“ bar”以使其初始堆棧指針值可用於其調用的代碼,或者修改多任務器以保存/恢復靜態異常框架指針,是不可能發生的。
@WoutervanOoijen RTTI的內存成本是多少?
@supercat“ _允許通過C或彙編代碼的異常傳遞_”本質上是不可靠的*,因為該代碼不是為這種情況準備的,並且可能會留下垃圾
RTTI的內存成本是一些有關應用程序中類的閃存信息。IMO這不是一個大成本,但是我發現RTTI(主要是dowcasts)的使用案例無論如何都沒有吸引力,所以為什麼不迴避成本呢。
@curiousguy:您是正確的,如果有任何傳遞代碼需要清除,則它必須知道控件可以通過何種方式對其進行轉義。我的觀點是,即使在非C ++代碼不需要進行任何清理的情況下,無法使用不可展開的堆棧框架也會給無法使用線程靜態存儲的實現帶來問題。
Rocketmagnet
2012-02-21 04:51:04 UTC
view on stackexchange narkive permalink

是的,C ++當然適用於嵌入式系統。首先,讓我們澄清一些關於C和C ++之間區別的誤解:

在嵌入式微型計算機中,如果您擔心時間或空間,則總是需要謹慎使用高級語言。約束。例如,許多MCU不能很好地處理指針,因此在使用堆棧時效率很低。這意味著您在使用數組,指針和遞歸將變量傳遞給函數時必須格外小心。一個簡單的C語言行,例如:

  a [i] = b [j] * c [k];  

可以生成大約4頁的指令取決於這些變量的性質。

每當您使用任何高級語言,並且擔心時間和空間限制時,都需要了解每個的功能該語言的語言翻譯成MCU上的機器指令(至少,您使用的每個功能)。對於C,C ++,Ada,無論如何都是如此。可能所有語言都將包含在小型MCU上無法有效翻譯的功能。始終檢查反彙編清單,以確保編譯器不會生成大量瑣碎的指令。

C是否適合嵌入式MCU?是的,只要您注意生成的代碼即可。
C ++是否適合嵌入式MCU?是的,只要您注意生成的代碼。

這就是為什麼我認為即使在8位MCU上,C ++也比C更好:C ++為以下方面提供了更好的支持:

  • 數據隱藏
  • 更強的鍵入/檢查功能
  • 使用類進行多周界透明化
  • 模板(一如既往,請謹慎使用)
  • 初始化列表
  • const

這些功能都不比C的典型功能重。

當您最多移動16或32位MCU時,在功能更強大的MCU上以相同的方式使用更重的C功能(堆棧,堆,指針,數組,printf等)就變得有意義了。使用C ++的重功能(堆棧,堆,引用,STL,新建/刪除)變得合適了。

因此,無需在PIC16上對C ++的想法感到震驚。如果您正確地了解您的語言和MCU,那麼您將知道如何一起有效地使用它們。

這是對該問題的很好表達和合理的答案。 +1歡呼!
“`[a [i] = b [j] * c [k];`可以生成大約4頁的指令,具體取決於這些變量的性質。”如果您的MCU /編譯器這樣做,是因為您使用的是80年代的車庫業餘CPU。
@Lundin-igh。不,這意味著您使用的是便宜的小MCU,該MCU被設計為盡可能小巧,便宜,並且沒有像堆棧索引這樣的複雜事物。
-1
不需要比16位更快的@Lundin 32位處理器。這很明顯可以追溯到PC世界中從16到32位程序轉換的時代。
@Barleyman除了速度以外,還有其他一些問題使8位和16位錯誤的選擇,最值得注意的是無法方便地處理65kb以上的內存。但是,諸如此類的C語言問題也往往會針對此類小型MCU出現,例如隱式整數提升錯誤。此外,市場上幾乎每一個8位架構都具有一個始於1970年代至80年代的“絕對可怕的核心”。包括:PIC,8051,HC08,AVR。
@Lundin我對MSP430(16位體系結構)有豐富的經驗。我不會將其與8051或類似產品相比,它是完全不同的野獸。還有,為什麼那個µCU只有64kB,您為什麼需要更多的64kB內存?認真地考慮,它有20位尋址,這確實是一個相當普遍的安排。與FLASH相比,FRAM確實很棒。真正的隨機存取非易失性RAM。我的主要抱怨是它不執行DIV,這意味著您必須向後彎腰以避免分裂。無論如何,得克薩斯州擁有出色的支持和文檔,因此比起例如意法半導體。
Mark
2010-06-17 05:21:24 UTC
view on stackexchange narkive permalink

我總是覺得閱讀這些辯論很有趣。關於各種可用語言的利弊的學術討論不是很多,而是因為您通常可以根據某人的工作/經驗/感興趣的領域來確定某人對該主題的立場。就在那兒,帶有“過早的優化”參數,這是CS專業人士和維護程序員在左右引用Knuth以及那些在現實世界中工作的人,他們認為性能非常瘋狂(我是後者的成員)公平地說。)

最終,您可以在這裡用C或C ++或插入語言開發出色的軟件。這取決於開發人員的能力,而不是語言。通常,只有當您選擇了錯誤的語言並且現在需要將其轉換為解決問題的方式時,才需要成為語言專家,在大多數情況下,這是唯一需要深入了解晦澀功能或編譯器的情況

我經常聽到人們以“我是X語言專家,等等”的理由開始爭論,因為我認為他們已經從錯誤的角度解決了問題,此後的一切都因他們渴望使用工具來解決問題並顯示問題的“酷”程度而受到困擾。

我經常看到開發人員首先選擇工具集並嘗試將其屈服於他們的問題,這是完全錯誤的,並導致了解決方案。

正如我在對另一個答案的評論中提到的那樣,這些語言之爭常常演變成爭論:語言X允許程序員做更多愚蠢的事情。在娛樂閱讀的同時,所有這些陳述實際上意味著您在僱用優秀的開發人員時遇到了問題,需要直接解決該問題,而不是通過繼續僱用不良的開發人員並選擇能夠使他們做得很少的工具來試圖解決問題。盡可能的損壞。

在我看來,好的開發人員,無論是軟件開發還是硬件開發,都要研究問題,設計解決方案並找到使他們能夠以“最佳方式”表達解決方案的工具。在使用3-4種語言/開發工具進行項目選擇新工具之後,是否需要使用的工具是您從未使用過的工具都沒關係,

>

當然,“最佳方法”是一個主觀術語,還需要在研究階段進行定義。一個人需要根據眼前的問題考慮許多問題:性能,表達的難易程度,代碼密度等。我之所以沒有將可維護性列入該列表是有原因的,我不在乎您選擇哪種語言,如果您選擇了合適的工具並花時間來理解應該免費的問題。難以維護代碼通常是由於選擇了錯誤的工具或較差的系統結構而導致的,這導致醜陋的雜亂無章,使其無法正常工作。沒有定義一個特定的感興趣的問題。面向對象的方法並不總是比功能方法更好。有一些問題非常適合面向對象的設計範例。有很多沒有。關於人們似乎喜歡使用的許多語言功能,可以做出相同的陳述。

如果您花費超過20%的時間在實際鍵入代碼的問題上,則可能是系統性能很差,或者開發人員性能很差(或者您還在學習)。您應該將大部分時間花在解決問題並確定應用程序各部分之間的交互方式上。將一群才華橫溢的開發人員放在一個帶有標記板和問題的房間中,並告訴他們在他們對整個系統感到滿意之前,他們不能編寫任何代碼或選擇任何工具,這將大大提高他們的質量。輸出和加快開發速度,而不是選擇任何熱門的新工具都可以保證縮短開發時間。 (將Scrum開發視為與我的論點相反的參考)

通常不幸的現實是,許多企業只能通過所寫的行數或通過查看“有形的輸出”。他們將在帶有標記板的房間中呆了3週視為生產力的損失。開發人員經常被迫加速開發的“思考”階段,或者被迫使用公司內部某個政治問題所設定的工具,“我老闆的兄弟為IBM工作,所以我們只能使用他們的工具”,這種垃圾。或更糟糕的是,您會從公司那裡收到一組不斷變化的需求,因為他們沒有能力進行適當的市場研究或不了解更改對開發週期的影響。對於這個話題,我對此話題有很強烈的看法。

+1,雖然很長,但我很喜歡。我只在工作中使用C,但是我真的想轉向C ++,因為有很多好處。我有偏見,主要是因為出了什麼問題,或者我有一個老闆在告訴我們需要什麼的兩天內更改了規格。我仍在學習,並且預計還會有4-5年的時間。在那之後,我仍然會學習,但是我的公司沒有遵循的樣式指南或檢查過程,因此我試圖兩者兼而有之。
我認為您對解決該問題時彎曲工具的評論打在了頭上。它使我想起了這樣一句俗語:“當你只有錘子時,一切看起來都像釘子!”這是一個雙關語嗎?在世界上,如何在不浪費大量時間在模擬件上的情況下,對硬件進行模擬以對設備驅動程序進行單元測試?
現在,我不會敲打某些嵌入式系統上應用程序級別(在驅動程序之上)的單元測試。在開發階段早期進行單元測試和消除錯誤的即時反饋具有一定的價值,但是在整個TDD範式中誕生設計的整個方法在我看來有點不明智。在開始編寫代碼之前,我寧願花些時間“思考”問題並在腦海中,在紙上或在白板上畫出問題。我還認為TDD鼓勵市場不要對需求進行前期研究,因為它應該有助於不斷地改變需求。
最後要對我的超長評論做最後的說明。我們需要可以使用該語言的專家設計師。
抱歉,這是冗長的演講,當我看到一個問題被激烈辯論時,我往往會變得非常瘋狂,因為我認為這是一個更深層次問題的簡單結果,我認為這應該是討論的真正主題。
@doxalogos TDD點很好。我在強迫這些問題的公司中所經歷的一個有限的經驗是,它們需要TDD,但不願產生牢固的PRD。
@doxalogos錯誤,對不起,我走了,將TDD與TRD混淆了,太多的TLA(三個字母的縮寫)
@mark,可以定義PRD和TRD。
PRD =產品需求文件,MRD =市場需求文件,TRD =技術需求文件。 TDD =測試驅動開發。
-1
-1
@Mark-我同意您的前期設計觀點,但只限於一點。我認為,如果a)您的要求相當穩定/已知,並且b)進行設計的開發人員是_experienced_,那麼繁重的前端設計工作將獲得回報。在上一個這項工作使我承擔了進行設計的任務,而團隊負責人花了很多時間來思考這個問題,我想:“要做的事真愚蠢!預先設計可以省錢(請參閱代碼完整書)?”但是在編碼中,我發現了很多我不知道要尋找的東西。如果我做了很多設計並減少了代碼時間,那將是浪費。 JME。
@sheepsimulator我顯然同意第二點,我假設主導系統架構師是有經驗的開發人員。關於第一點,我實際上不同意。我認為,您對需求的更改越期望,則在設計階段應該花費的時間就越多,因為您需要進行良好的,易於更改的設計。我知道有些哲學提出快速發展。在某些情況下,這很適合工作人員中許多糟糕的或缺乏經驗的程序員。所有這些設計哲​​學都歸納為“我不願設計一個靈活的系統,所以不要浪費時間去嘗試”。
在這裡,我們的需求一直在變化,但是我們花費最多時間設計的系統具有最快的編碼和維護時間。我們在一個子系統上花費了大量時間,因為我們知道它在未來將變得多麼重要以及需要​​進行更改。它是唯一更改少於一天的工作,並且已經完成許多工作的子系統。
Toby Jaffey
2010-06-15 21:12:12 UTC
view on stackexchange narkive permalink

以我的經驗,C ++通常不適用於小型嵌入式系統。我的意思是微控制器和無操作系統設備。

許多C ++ OOP技術都依賴於動態內存分配。在小型系統中經常會缺少這種功能。

STL和Boost確實展示了C ++的強大功能,兩者的佔用空間都很大。

C ++鼓勵程序員將計算機抽像出來,

去年,我將商業遠程桌面產品移植到了手機上。它是用C ++編寫的,並且可以在Windows,Linux和OSX上運行。但是,它嚴重依賴STL,動態內存和C ++異常。要使其在WinCE,Symbian和無操作系統環境中運行,最明智的選擇是C重寫。

我同意使用小型系統,但是我認為我們對小型系統有不同的定義。當您有1kB的ROM且編寫良好的C代碼佔用了除1字節以外的所有ROM時,這是一個很小的系統。
我並不是在說C不能擁有更小的佔用空間,但是您可以仍然使用C ++並為剛剛討論的內容獲得非常相似的結果。我認為問題在於大多數OOP程序員習慣於具有動態內存並且使用效率非常低下的結構的系統,從而導致低功耗系統的代碼完全無用。
我主要在C ++中完成了較大的x86 SBC開發,因此我發現在資源較少的平台上使用C ++的經驗(正面或負面)很有用。
我已經在使用C ++的計算機上進行了大量開發,而在嵌入式平台上卻幾乎未進行任何開發。我在嵌入式平台上做了非常大量的開發,我的意思是在MSP430和PIC系列產品中。這一切都在C中完成。沒有庫或任何東西。我想在嵌入式系統項目上使用C ++,這有很多充分的理由,到目前為止,我還沒有聽到不能通過對可以使用的C ++構造使用嚴格的規則來解決的原因。
所以你的意思是你不想使用C ++,而是想在C和C ++之間使用某種東西(讓我們稱之為C +?)。在那種情況下,我同意,C ++人們使用很多廢話只是因為它可用,而不是因為它是最優的。幾乎任何一種語言都能夠生成良好,快速的代碼,這取決於其使用方式。關於語言的大多數聖戰不是語言能力的結果,而是關於白痴做愚蠢事情有多容易的爭論,這實際上是一個愚蠢的論點:p
“大多數針對語言的聖戰不是語言能力的結果,而是關於白痴做白痴事情有多容易的爭論,這實際上是一種白痴爭論。”這是一個非常愉快的句子。我需要你的姓氏,所以我可以引用它。
我試圖爭論一門語言對完成工作有多強大。我認為C ++為完成任務提供了巨大的飛躍。通過適當的設計和實現,我看到了我們開發系統的巨大進步,這正是我想要的,並且如果它可以幫助其他人,但是只需要更多的培訓,那麼我就很感興趣。
我確實也沒有在C中使用動態內存。我沒有地方必須擁有它。從長遠來看,我讀到它會變得非常細分,並開始引起問題。我需要設計非常清楚的案例來解決內存不足的問題,並且需要能夠準確監視剩餘的內存量。
Wouter van Ooijen
2011-07-04 11:32:47 UTC
view on stackexchange narkive permalink

任何語言都適用於嵌入式系統。嵌入式只是意味著:與免費使用的計算機相反,它是大型設備的一部分。

當要求進行(硬)實時 em 時,該問題具有更大的相關性。 >或有限資源系統。

對於實時系統,C ++是在對嚴格的時間限制進行編程時仍然適用的最高語言之一。除了堆使用(自由運算符)外,它沒有不確定的執行時間的構造,因此您可以測試程序是否滿足其計時要求,並且有更多的經驗甚至可以預測它。當然,應該避免使用堆,儘管新的運算符仍然可以用於一次性分配。 C ++通過C提供的結構可以在嵌入式系統中很好地使用:OO,異常,模板。

對於資源非常有限的系統(8位芯片,RAM不到幾Kb) ,沒有必需的堆棧)完整的C ++可能不適合,儘管它仍可以用作“更好的C”。

我認為很不幸,Ada似乎僅在某些壁ni中使用。從很多方面來說,它都是Pascal ++,但是沒有與一開始就已經很混亂的語言向上兼容的負擔。 (編輯:嚴重的混亂當然是C。Pascal是一門美麗但有些不切實際的語言。)

======================= ========================================

編輯:我正在鍵入一個新問題的答案(“在什麼情況下,當我們對微控制器進行編程時,C ++是必需的嗎?”),因此我將添加我寫的內容:

使用任何編程語言從來沒有一個完全否定的理由,但是在特定情況下某些參數可能具有或多或少的重要性。關於此問題的討論可以在很多地方找到,其職位範圍從“從不使用C ++用作微控制器”到“始終使用C ++”。我更喜歡最後一個職位。我可以提供一些論據,但是您必須自己決定它們在特定情況下(以及在哪個方向)所承擔的重量。

  • C ++編譯器比C編譯器稀有。對於某些目標(例如12位和14位核心PIC),根本沒有C ++編譯器。
  • (好的)C ++程序員比(好的)C程序員稀少,尤其是在那些(
  • C ++比C具有更多的構造,不適用於小型系統(例如,異常,RTTI,頻繁使用堆)。
  • C ++具有比C更豐富的(標準)庫集,但是先前觀點的結果是C ++庫經常使用不適用於小型系統的功能,因此在小型系統上不可行。 / li>
  • C ++具有比C更多的結構,可讓您用腳射擊。
  • C ++具有比C更多的結構,可讓您防止射擊
  • C ++具有一組更豐富的抽像機制,因此它提供了更好的編程方式,尤其是對於庫而言。
  • C ++語言功能(例如,構造函數/析構函數,轉換函數)使查看代碼以查看生成的機器變得更加困難,從而增加了語言構造的時空成本。
  • C ++語言構造使您不必了解將代碼準確地轉換為機器代碼的方式,因為它們在“摘要”中做了“正確的事情”採取行動。
  • C ++語言標準發展迅速,並且被大型編譯器(gcc,clang,microsoft)迅速採用。 C的發展相當緩慢,對某些較新功能(可變數組)的採用感到恐懼,甚至在以後的標準中也有所恢復。特別是這一點很有趣,因為不同的人使用它來支持相反的立場。
  • C ++無疑是比C更為敏銳的工具。您是否相信您的程序員(或您自己)使用這種工具來實現這一目標一個美麗的雕塑,還是您擔心它們會傷害自己,您是否寧願選擇一款不太美觀但風險較低的產品呢? (我記得我的雕塑老師曾經告訴我,鈍器在某些情況下比銳利的工具更危險。)

我的博客有關在小型系統(=微控制器)上使用C ++的一些著作。

odinthenerd
2017-01-17 23:04:23 UTC
view on stackexchange narkive permalink

我希望在有關裸機和資源受限系統上的C ++的討論中增加更多的熱量。

C ++中的問題:

  • 異常尤其是一個RAM問題,因為所需的“緊急緩衝區”(例如,內存不足異常就在其中)可能大於可用的RAM,並且肯定對微控制器造成浪費。有關更多信息,請參見 n4049 n4234。它們應該被關閉(這是當前未指定的行為,因此請確保不要拋出)。 SG14目前正在研究更好的方法。

  • RTTI可能永遠都不值得開銷,應該將其關閉

  • 大型調試版本,儘管在經典台式機開發中這不是問題,但如果調試不適合芯片,則可能是一個問題。問題來自於為清晰起見而添加的模板代碼或額外的函數調用。優化器將再次刪除這些多餘的函數調用,並且增加的清晰度或靈活性可能是一個很大的優勢,但是在調試版本中,這可能是個問題。

  • 堆分配。儘管STL允許使用自定義分配器,但對於大多數程序員而言,這可能很複雜。堆分配是不確定的(即不是實時的),儘管進行了測試,但碎片會導致意外的內存不足情況發生。為了跟踪自由空間和變化的大小,堆所需的簿記可能是小對象的問題。通常最好使用池分配(在C和C ++中都是這樣),但這對於習慣只使用堆的C ++程序員來說可能是異常的。

  • 運行時多態性和其他間接調用通常會嚴重影響性能,問題通常出在更多地方,因為優化器無法看到它們,而不是實際獲取和跳轉到地址。因此,在C和C ++中應避免進行間接調用,因為在C和C ++中,它們在文化中更加根深蒂固(並且在其他領域中非常有用)。

  • 與clib的隱式接口可能會出現問題。 clib問題在C ++類別中可能是違反直覺的,但問題是由並發環境中的資源隱式共享引起的(在C中共享更明確)。通用newLib實現的使用通常會導致很多膨脹,這在uC中通常是不需要的,另一方面,newLibNanno不是可重入的,因此必須序列化對其進行訪問(在此過度簡化)。對於C來說也是一個問題,但是訪問更為明確。根據經驗,除非您確定它不會以某種方式訪問clib中的狀態(例如,errorno或堆),否則基本上不應在ISR上下文中使用命名空間std中的任何內容。如果您正在使用線程(我更喜歡RTC)來覆蓋new和delete以同步對malloc和free的訪問,這也很重要。

總而言之,C ++存在一些問題,但它們基本上都是可修復的或可避免的。

現在對於C,這裡的問題是高階。我沒有C語言的語法能力來抽象事物,而我無法在編譯時執行優化或檢查不變式。因此,我無法以某種方式正確地封裝事物,即用戶不需要知道它們的工作方式就可以使用它們,而我的大部分錯誤檢測都是在運行時完成的(這不僅為時已晚,而且會增加成本)。 本質上,在C語言中通用的唯一方法是通過數據,我將格式字符串傳遞給printf或scanf,例如在運行時對其進行評估。然後,對於編譯器來說,很難證明我沒有使用某些選項,這些選項在傳遞正確的數據時理論上是可行的,這意味著潛在的死代碼生成和優化潛力的損失。

我知道我可能會在這裡引發一場風暴,但是我在32位微控制器上的經驗是,在專家之間編寫的C和C ++的比較中,C ++是效率更高的語言。只要一切都需要完全通用(就像在任何庫中一樣),並且在非通用情況下它們基本上是等效的。對於新手來說,利用C ++中的專家庫實現者的專業知識也更加容易。

同時,實際上實際上只有很少的函數不能傳遞不正確的數據,只要輸入不是int而是 something ,而我恰巧使用了int作為一種表示方法,則可能會出錯(​​傳遞無效值或“ otherThing”而不是“ something”)。在C語言中,檢查用戶是否輸入錯誤的唯一方法是在運行時。在C ++中,我可以執行一些檢查,而不是全部檢查,但可以在編譯時執行一些免費的檢查。

在一天結束時,C團隊通常與其最弱的程序員一樣強大,並且所得到的代碼收益是多人遊戲1或性能損失。我的意思是,在一個獨特的設計決策獨特的環境中,它要么是一項工作的高性能,要么是一項獨特的工作,或者它足以在多種環境中使用(其他微控制器,其他內存管理策略,其他延遲vs.)。吞吐量的取捨等),但具有固有的性能成本。

在C ++中,事情可以由專家進行封裝,並在許多環境中使用,在這些環境中,編譯時代碼生成可適應特定任務,而靜態檢查可防止用戶以零成本進行愚蠢的工作。在這裡,我們在通用和快速之間的權衡要少得多,因此最終從成本與收益的角度來看,是一種性能更高,更安全和更俱生產力的語言。

一個很好的批評是,仍然缺少用於嵌入式的良好C ++庫,這可能導致務實的決定,即在C ++編譯器上主要使用C。在項目中僅使用C的決定本質上是出於意識形態的驅動,出於對遺留支持的需求,或者承認團隊的紀律性不足以避免選擇C ++而不是C可以完成的一系列愚蠢的選擇。同時要有足夠的紀律性,以至於不能做任何愚蠢的事情,而這在C語言中是無法防範的,而在C ++中是可以避免的。

我的回答還不錯:)這個神秘的C ++愛好者會是誰?他的個人資料指出:“顯然,這些用戶更喜歡保持神秘感。”(英語不好,BTW)但是AHA的位置是“德國波鴻” ...在會議上見!
是的,更新了我的個人資料;)很高興知道您來emBO ++會很不錯
J. Polfer
2010-06-16 19:43:40 UTC
view on stackexchange narkive permalink

我的背景:剛從貝爾實驗室老程序員的學校接受培訓;已經工作了3年,其中2個是本科生研究項目; VB.NET中的數據採集/過程控制。用了1.5年的時間在VB6中的企業數據庫應用程序上工作。目前正在為具有2GB存儲,512MB RAM,500MHz x86 CPU的嵌入式 PC的項目工作;使用C ++同時運行的幾個應用程序,中間之間具有IPC機制。是的,我還年輕。

我的觀點:我認為,鑑於我上面編寫的環境,C ++可以有效地工作。誠然,硬實時性能不是我正在使用的應用程序的要求,在某些嵌入式應用程序中,這可能是個問題。但是,這是我學到的東西:

  • C ++與C 根本不同(即,沒有C / C ++)。雖然所有有效的C語言都是有效的C ++語言,但C ++語言卻是一種截然不同的語言,需要學習如何使用C ++語言(而不是C語言)進行編程,以便在 any 情況下有效地使用它。在C ++中,您需要面向對象的程序,而不是程序性的程序,而不是兩者的混合(大型類具有很多功能)。通常,您應該集中精力製作具有很少功能的小型類,並將所有小型類組合成一個更大的解決方案。我的一位同事向我解釋說,我以前是在對像上進行過程編程的,這很麻煩,而且很難維護。當我開始應用更多的面向對象技術時,我發現代碼的可維護性/可讀性得到了提高。

  • C ++以面向對象的開發形式提供了其他功能,這些功能可以提供簡化代碼以使其更易於閱讀/維護的方法。老實說,我認為在進行OOP時不會在性能/空間效率方面有所改進。但是我認為OOP是一種可以幫助將一個複雜的問題分解為許多小片段的技術。這對處理代碼的人員很有幫助,這個過程中不可忽略的元素。

  • 許多反對C ++的參數主要與動態內存分配有關。 C也有同樣的問題。您可以編寫面向對象的應用程序而無需使用動態內存,儘管使用對象的好處之一是可以輕鬆地動態分配這些內容。就像在C語言中一樣,您必須注意如何管理數據以減少內存洩漏,但是 RAII技術在C ++中使這一過程變得更加簡單(通過將動態數據存儲器封裝在對像中來自動破壞它)。在某些應用程序中,每個內存位置都很重要,這可能太笨拙了,&難以管理。

編輯:

  • WRT的“ Arduino C ++”問題:我認為沒有動態內存管理的C ++仍然有用。您可以將代碼組織到對像中,然後將這些對象放置在應用程序內的各個位置,設置回調接口等。既然我已經在C ++中進行開發,我可以看到在應用程序上分配了所有數據的多種方式。堆棧對於對象仍然有用。我會承認-我從未真正為Arduino編寫過這樣的嵌入式應用程序,因此我沒有任何依據。我有一些機會在即將到來的項目中進行一些Arduino開發-希望我可以在那裡測試我的主張。
我想談談您的第二點,您說這有助於將一個複雜的問題分解為許多小片段,並且應該忽略該功能。這就是我如此親C ++的確切原因。大量的編程研究表明,程序大小的線性增長使開發時間呈指數增長。這是相反的方法,如果您可以適當地拆分程序,則可以使開發時間呈指數衰減。這是迄今為止最重要的事情。
在第二點上:僅使用OOP設計方法不會產生更多的分區代碼。擁有良好的基礎設計,開發人員如何表達設計。 OOP並未定義您是否正確分離了代碼,它提供了另一個選擇,並且提供了這樣做的外觀,但是,它肯定不能實施良好的設計,這取決於開發人員。
總是如此。我從來沒有聽說過可以實現良好設計的語言。我認為我們主要暗示這是開發人員的工作,而C ++使其易於以有組織的方式使用和實現。
@Mark-我同意。對我來說,這是一個學習過程。
“在C ++中,您需要面向對象而非程序地進行編程,”-為什麼?您可以執行類似C的過程C ++,只需從所需的C ++功能中進行選擇即可。例如,const,引用,枚舉,命名空間等。。。您會錯過C ++的* full *好處,但是與純C相比,您仍然會更好。
Kortuk
2010-06-15 21:18:25 UTC
view on stackexchange narkive permalink

是的,C ++的問題是代碼的佔用空間增加。

在某些系統中,您正在計算字節數,在這種情況下,您將不得不承受接近

但是,即使在C語言中,對於設計良好的系統,您也需要將所有內容封裝在一起。精心設計的系統很難,而C ++為程序員提供了一種結構化和受控的開發方法的場所。學習OOP是有成本的,如果您要切換到OOP,則您會接受它,並且在許多情況下,管理層寧願繼續使用C而不支付費用,因為很難衡量要轉換的結果。提高生產力。您可以在此處查看嵌入式系統專家Jack Ganssle的文章

動態內存管理是魔鬼。並非如此,魔鬼是自動路由,動態內存管理在PC上運行良好,但是您可以期望至少每隔幾週重新啟動PC。 您會發現,隨著嵌入式系統持續運行5年,動態內存管理確實會搞砸,甚至開始出現故障。 Ganssle在他的文章中討論了堆棧和堆之類的問題。

C ++中的某些事情更容易引起問題並佔用大量資源,刪除動態內存管理和模板是使C ++的足跡更接近C足蹟的重要步驟。這仍然是C ++,您可以不需要動態內存管理或模板來編寫良好的C ++。我沒有意識到它們刪除了異常,我認為異常是我在發行版中刪除的代碼的重要組成部分,但直到那時才使用。在現場測試中,我可以讓異常生成消息來通知我異常被捕獲。

我曾經同意代碼佔用量是一個問題,但是最近似乎閃存大小對微控制器的價格影響很小,遠小於RAM大小或IO引腳數。
關於動態內存的爭論更為重要。我已經看到工業系統可以連續運行數週,但是診斷層(用C ++編寫)會將重啟時間限制為大約12個小時。
pingswept
2010-06-15 21:52:13 UTC
view on stackexchange narkive permalink

我認為萊納斯·托瓦爾茲(Linus Torvalds)的這種抗C ++特長很有趣。

C ++絕對最糟糕的功能之一是它如何使很多事情變得如此。上下文相關的-這僅意味著當您查看代碼時,本地視圖很少提供足夠的上下文來了解正在發生的情況。

他並不是在談論嵌入式系統世界,但是Linux內核開發。對我而言,相關性來自於此:C ++需要理解更大的上下文,並且我可以學習使用一組對像模板,我不相信自己會在幾個月後必須更新代碼時記住它們。 / p>

(另一方面,我目前正在使用Python(不是C ++,但使用相同的OOP範式)在嵌入式設備上工作,而這個問題確實存在。在我的辯護中,它是功能強大的嵌入式系統足以在10年前被稱為PC。)

我們可能有所不同,但是我發現打開任何一個項目我都無法立即知道發生了什麼,但是如果我知道它在做什麼,並且我用C編寫了很好的代碼,而用C ++編寫了很好的代碼,那麼C ++似乎總是更多明確。您仍然需要實現封裝才能用C進行良好的開發,而C ++則很容易做到。正確使用類可以使您清楚地知道接口的位置,並且可以通過對象完全處理它們。
完全同意封裝和類。運算符的重載和繼承沒有那麼多。
哈哈,是的,可以使用運算符重載來混淆代碼的功能。如果有人在操作員超負荷工作,則出於明確的原因或根本沒有做過。繼承僅在實際情況下才使用,在某些情況下,您實際上正在做一些與父級類似的操作。我想我不會在OOP中使用每個函數。我都使用了這兩種方法,但是在嵌入式系統中,我想不到的是。正如我認為對變量名稱限制為80個字符的編譯器應立即取消。
我只是想起用Python編寫MCU的想法...
您不是唯一的人,但是如果它運行良好且高效,我可以原諒。
python-on-a-chip http://code.google.com/p/python-on-a-chip/
我有一個一般規則,如果它可以更好,更快地完成任務,那麼我會使用它。在某些情況下,一個比另一個更重要。
我的主張是程序員的時間通常比硬件要貴。想像一下,嘗試使用C與Python進行網絡編程,以節省50美元的硬件成本。對於嵌入式應用而言,嵌入式硬件的強大功能已成為當今小型應用的首選。
我同意,我在一家希望銷售數百萬個設備的公司工作,因此每單位的非經常性支出相當低,但是硬件很重要。在一個小項目中,這很有意義。我的意思是,更好,更快是很重要的。您只需要更快。
@pingswept我同意,程序員的時間很昂貴。正如Linus所指出的,對於開源志願者來說,它是無價的。但是,從商業上看,開發與製造的成本確實會產生很大的影響。我目前的職責是將嵌入式linux + python + zigbee系統移植到arm-cortex-m3,以節省成本。
聽起來像一個很棒的項目Joby。
@Kortuk“運算符重載可用於混淆代碼的功能”。我不知道為什麼每個人都以此為反對運算符重載的參數。我可以說“函數名稱可用於混淆代碼的功能”。我可以使用一個名為OpenFile()的函數來實際刪除文件。
@Rocketmagnet,同意,重要的部分是設計代碼以遵循簡潔的方法,並且僅在有意義的情況下才重載運算符,例如允許重載+在矩陣類上進行矩陣加法。
Python是一種漂亮的語言,但更適合於OS。但是,如果有人擁有正確的平台,我就可以在MCU上試用它了……從我所見的情況來看,Python經常使用C庫進行擴展。我用Python編寫樹莓派是不是一個“嵌入式”系統?
fceconel
2011-01-12 20:31:45 UTC
view on stackexchange narkive permalink

我認為其他答案對於正反兩方面以及決策因素都非常有利,因此,我只想總結一下並添加一些評論。

對於小型微控制器(8位),沒有辦法。您只是要傷害自己,就沒有收穫,並且會浪費太多資源。

對於高端微控制器(例如,用於RAM和存儲的32位,10s或100s MB)

所以,問題是:邊界在哪裡?

我不確定,但是一旦我開發了一個帶有1 MB RAM的16位uC系統,&用C ++存儲了1 MB,後來就後悔了。是的,它行得通,但是我所付出的額外工作不值得。我必須使它適應,確保諸如異常之類的東西不會產生洩漏(OS + RTL支持非常錯誤且不可靠)。此外,OO應用程序通常會做很多小的分配,而這些應用程序的堆開銷又是另一個噩夢。

基於這種經驗,我假設在以後的項目中,我只會在至少16位且RAM &存儲至少16 MB的系統中選擇C ++。這是一個任意限制,並且可能會因應用程序類型,編碼樣式和習慣用法等因素而有所不同。但是,請注意,我建議採用類似的方法。

在這裡我不得不不同意,由於系統資源的原因,C ++可以被接受並不是突然的事情,良好的設計實踐可以使C ++的足跡保持在C的足蹟之下。這導致帶有OOP設計的代碼佔用相同的空間。編寫不佳的C可能同樣糟糕。
好吧,這取決於應用程序的大小以及您使用多少需要更多空間的某些功能(例如模板和異常)。但是個人而言,我寧願使用C而不是將自己局限於受限的C ++。但是即使那樣,您仍然會承擔更大的RTL,虛擬方法重擊,構造函數/析構函數鏈調用的開銷……通過仔細的編碼可以減輕這些影響,但是卻失去了使用C ++,抽象和高層次的觀點。
“但是即使那樣,您仍然會有更大的RTL的開銷” –廢話,當我使用C ++時,我會得到與C相同的RTL:本質上為0。
“虛擬方法重擊”-不知道它們是什麼,但是除非您使用虛擬函數*,否則您肯定不會得到它們,在這種情況下,等效的C程序將具有函數指針。
“我寧願使用C而不是將自己限制為受約束的C ++”-我不能代表您,但是當在小型微控制器上使用C時,我使用了經過重新訓練的C,例如:沒有堆,沒有浮點數,沒有setjmp / jongjmp。同樣,我使用了受約束的C ++。
supercat
2011-05-13 20:46:15 UTC
view on stackexchange narkive permalink

C ++的某些功能在嵌入式系統中很有用。還有其他一些例外情況,例如例外情況,可能會很昂貴,而且其代價可能並不總是很明顯。

如果我有德魯特人,那將會是一種流行的語言,它融合了兩全其美,兩種語言都缺少的一些功能;一些供應商提供了一些這樣的功能,但是沒有標準。我想看幾件事:

  1. 類似於Java的異常處理,在異常處理中必須聲明可能引發或洩漏異常的函數。儘管從編程的角度來看,對此類聲明的要求可能會有些煩人,但如果函數可以成功返回任意整數,但也可能失敗,則可以提高代碼的清晰度。許多平台可以通過例如
  2. 僅靜態和內聯函數的重載;在寄存器中具有返回值,在進位標誌中具有成功/失敗指示。我的理解是C的標準機構避免了函數重載,從而避免了名稱修飾。僅允許靜態和內聯函數的重載可以避免該問題,並且可以提供重載外部函數的99.9%的好處(因為.h文件可以根據名稱不同的外部函數來定義內聯重載)。特定的編譯時可解析常量參數值。當使用任何常量值傳遞時,某些函數可能非常高效地內聯,但是如果傳遞變量,則內聯性很差。其他時候,如果值恆定則可能是優化的代碼,如果不是則可能是悲觀的。例如:
     inline void copy_uint32s(uint32_t * dest,const uint32_t * src,__is_const int n){if(n < = 0)return;否則,如果(n == 1){dest [0] = src [0];},否則,如果(n == 2){dest [0] = src [0]; dest [1] = src [1];}
    否則,如果(n == 3){dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2];}否則,如果(n == 4){dest [0] = src [0]; dest [1] = src [1]; dest [2] = src [2]; dest [3] = src [3];}否則memcpy((void *)dest,(const void *)src,n * sizeof(* src));} 
    如果'n'可以在編譯時求值這段時間,上面的代碼比調用memcpy更有效,但是如果在編譯時無法評估'n',則生成的代碼將比簡單地稱為memcpy的代碼更大,更慢。 ol>

    我知道C ++之父不太喜歡C ++的嵌入式版本,但是我認為它可以比僅使用C語言提供一些可觀的改進。

    任何人都知道是否有類似上面的內容正在考慮採用任何類型的標準嗎?

HTTP://恩.Wikipedia.org/wiki/embedded_C%2B%2B
@Joby Taffey:我想我已經編輯了我的文章,以免提及C ++的創建者並不熱衷於嵌入式子集。我知道有人在努力,但據我了解,他們還沒有真正走到盡頭。我確實認為肯定會使用適用於8位處理器的標準化語言,並且如上所述的功能在任何平台上似乎都很有用。您是否聽說過提供上述#3之類的語言?這似乎很有用,但是我從未見過任何語言能夠提供它。
“ C ++之父”對嵌入式系統編程經驗為零,那麼為什麼有人會關心他的意見呢?
@Lundin:一些有影響力的人的確似乎在乎他在各種問題上的觀點,這一事實似乎本身就是其他人這樣做的原因。我在想,自從我在上面撰寫上述內容以來,模板的功能不斷增強,可能會增加一些新的可能性,使其可以基於在編譯時可以解析的常量來進行重載,儘管與支持將此類東西作為編譯對象相比,這種方法要乾淨得多,時間功能(據我了解,人們會指定一個模板,該模板應按順序嘗試各種事情,並採用不會失敗的第一個模板...
...但是這將要求編譯器花費大量的精力來編譯潛在的替換,然後最終將其丟棄。能夠更清楚地說“如果這是一個常數,請執行此操作;否則請執行此操作”而沒有任何“錯誤的開始”,這似乎是一種更乾淨的方法。
是的,EC ++受到好評的主要原因似乎是因為這個模糊的“父親在雲端”,他可能從未見過微控制器。10年前,我在EC ++中做了一個微控制器項目,那時對我來說很有意義。但這也是我最後一次在嵌入式系統上使用C ++,所以我有點過時了。
@Lundin:我對MISRA C ++不熟悉。我確實認為MISRA C可能應該與“其他” C分出來,並指定例如給定``uint16_t x;''語句`x =(uint16_t)(x * x);'的MISRA C編譯器必須產生mod-65536結果,而不管x的值或int的大小如何。儘管當int的大小為17至32位並且x的大小為46341或更高時,該標準從未提出任何要求,但是在這種情況下,32位編譯器的行為與16位編譯器相同,但如今可能以怪異和怪異的方式。
@Lundin:雖然我認為有人可能會爭辯說將代碼編寫為`x = {uint16_t)(1u * x * x);`會更好,因為即使是超現代的編譯器也無法將其弄亂,我在給定後一種措辭的情況下,認為僅要求編譯器保持一致行為的語言規範應被認為比“前一種措辭必須在`int”為17至32位時產生相同結果的情況下被認為“更好”。適用於更大或更小的“ int”尺寸。
fjrg76
2014-06-27 22:31:03 UTC
view on stackexchange narkive permalink

C ++不僅僅是一種編程語言:

a)是一種“更好的” Cb)是一種面向對象的語言c)這是一種允許我們編寫通用程序的語言

儘管所有這些功能都可以單獨使用,但是同時使用其中三個功能時,可以達到最佳效果。儘管如此,如果只選擇其中之一,嵌入式軟件的質量將會提高。

a)它是一種“更好的” C

C ++是一種強類型語言;比C語言更強大。您的程序將受益於此功能。

某些人擔心指針。 C ++包含了引用。重載的函數。

並且應該說:這些功能都不會出現在較大或較慢的程序中。

b)這是一種面向對象的語言

每當您準備使用微控制器的外設時,很可能外圍設備已經以設備驅動程序的形式為我們(從您自己或第三方)中提取。如我之前所說,該驅動程序使用C語法,如以下示例所示(直接取自NXP LPC1114示例):

/ *定時器設置為TICKRATE_HZ進行匹配和中斷* /

Chip_TIMER_Reset(LPC_TIMER32_0);

Chip_TIMER_MatchEnableInt(LPC_TIMER32_0,1);

Chip_TIMER_SetMatch(LPC_TIMER32_0,1,(timerFreq / TICKRATE_Hatch_Patch_HZ2Enable]

Chip_TIMER_Enable(LPC_TIMER32_0);

您看到抽象了嗎?因此,當出於相同目的使用C ++時,通過C ++的抽象和封裝機制將抽象提升到一個新的水平,

c)這是一種使我們能夠編寫通用程序的語言

通用程序是通過模板實現的,而且模闆對我們的程序也沒有任何成本。

靜態多態性

虛擬方法,RTTI和異常。

使用虛擬方法時存在一個折衷:更好的軟件而不是性能上的損失。但是,請記住,動態綁定可能使用虛擬表(函數指針數組)來實現。我已經在C中做了很多次(甚至是定期進行),所以我看不到使用虛擬方法的弊端。而且,C ++中的虛擬方法更加優雅。

最後,關於RTTI和異常的建議:不要在嵌入式系統中使用它們。不惜一切代價避免它們!!

Tim Williscroft
2010-11-03 09:48:37 UTC
view on stackexchange narkive permalink

我的背景是實時的(嵌入式(MCU,PC,UNIX,其他))。安全至上。我向STL介紹了一位前任雇主。我不再這樣做了。

某些火焰含量

C ++是否適合嵌入式系統?

嗯C ++是編寫的痛苦,也是維護的痛苦。 C +可以嗎(不要使用某些功能)

C ++在單片機中?實時操作系統?烤麵包機?還是嵌入式PC?

我還是說Meh。 C +並不太糟糕,但是ADA卻不那麼痛苦(這確實是在說些什麼)。如果像我這樣幸運的話,您可以使用嵌入式Java。經過檢查的數組訪問和無指針算法使得代碼非常可靠。嵌入式Java中的垃圾收集器並不是最高優先級,並且內存和對象的使用範圍很廣,因此設計良好的代碼可以在沒有GC的情況下永久運行。

OOP在微控制器上有用嗎?

可以。 UART是一個對象..... DMAC是一個對象...

對象狀態機非常簡單。

C ++是否會使程序員離硬件太遠而無法

除非它是PDP-11,否則不是CPU。 C ++最初是C語言的預處理器,因此Bjarne Stroustrup不會因為在AT&T.C ++上具有緩慢的Simula仿真而被嘲笑。C++不是您的CPU。

獲取運行Java字節碼的MCU。 Java程序。

應該將Arduino的C ++(沒有動態內存管理,模板,異常)視為“真正的C ++”嗎?

不。就像所有針對MCU的混蛋C編譯器一樣。

第四,嵌入式Java或嵌入式ADA已標準化。其他所有的都是悲傷。

找到支持Java的微控制器容易嗎?我認為這會大大限制選擇。您對性能下降有何經驗(由於在uC中您通常不會擁有JIT)? GC不可預測性對實時系統的影響如何?
哪些MCU支持嵌入式Java?
對於初學者,請訪問www.ajile.com。
+1為Ada。在包括Arduinos在內的嵌入式方面有很多事情要做。
用c編寫的用於micros的可移植Java VM是開源的。 http://dmitry.co/index.php?p=./04.Thoughts/11.%20uJ%20-%20a%20micro%20JVM
IMRAN AHMAD AWAN
2012-06-29 15:42:57 UTC
view on stackexchange narkive permalink

嵌入式系統旨在執行某些特定任務,而不是用作執行多個任務的通用計算機。嵌入式系統是計算機硬件和軟件的組合。 C是所有現代語言的母親。雖然級別較低,但語言功能強大,並且可以處理各種硬件。因此,C / C ++是開發嵌入式系統軟件的最佳選擇,對於每個嵌入式系統來說,C / C ++都非常有用。眾所周知,C是一種開發語言。操作系統UNIX是用C編寫的。由於成功的軟件開發經常是為給定項目選擇最佳語言,因此令人驚訝的是發現C / C ++語言已證明自己適用於8位和64位處理器;在具有字節,千字節和兆字節內存的系統中。 C具有處理器獨立性的好處,它使程序員可以專注於算法和應用程序,而不是特定處理器體系結構的細節。但是,這些優點中的許多優點同樣適用於其他高級語言。但是C / C ++成功了,而其他許多語言卻大都失敗了?

我真的不確定這會增加討論的內容。
vicatcu
2010-06-16 01:21:57 UTC
view on stackexchange narkive permalink

<rant>

我首先認為C ++是一種糟糕的語言。如果要使用OOP,請編寫Java程序。 C ++不會執行OOP範例,因為直接內存訪問完全可以(濫用)能力來實現。

如果您有MCU,那麼您談論的是閃存容量可能不足100kB。您想用一種語言來編程,該語言的內存抽象為:當我聲明一個變量或數組時,它獲取內存,句點;應該或多或少禁止在嵌入式軟件中使用malloc(C ++中的“ new”關鍵字),除非在少數情況下在程序啟動過程中一次調用。在C語言還不夠底層的情況下進行編程,您需要執行一些操作,例如將變量分配給寄存器,並編寫內聯彙編以加強中斷服務例程(ISR)。諸如“ volatile”之類的關鍵字變得非常重要,需要理解。您花費大量時間在 bit 級別而不是 object 級別上操縱內存。

為什麼要自欺欺人地認為事情比實際上更簡單嗎?

< / rant>

我的問題很簡單,如果我已經完全開發了用於處理接口的驅動程序,那麼為什麼我想知道為控制USART1而編寫的驅動程序的複雜性。
我沒有否決您的意見,但我想指出,C ++不需要強制執行OOP,只需提供執行此操作的工具即可。實施好的編碼標準是開發人員的工作。如果該語言使它變得更簡單,則可以提供幫助,但是該語言永遠不會自己做到。 C在某些情況下可能不可讀。
所有語言對某些事物都有好處。 C ++速度很快。如果做得好,OOP將使多個開發人員可以更輕鬆地並行工作並為未知的人編寫代碼。我認為這就是為什麼它在遊戲開發中具有如此大的吸引力。
是的我同意。我之所以在嵌入式世界中看到它,是因為大量的特性和功能被添加到了許多已經存在的不同系統中,並且正在開發新的系統。項目越來越大。我們要么花費更長的時間來開發它們,要么開始應用並扭曲CS世界已經在PC上完成的工作。
我同意vicatsu。他為什麼被否決?我是具有20多年經驗(非嵌入式)的軟件專業人員。我對C ++的看法是,它是最昂貴的語言,不幸的是,由於純C的早期流行,它很受歡迎。純C的流行僅出於一個原因:有一本關於該語言的非常不錯的書,寫得很好(可用性與C和C ++語言完全相反)
另一個不正確理解C ++的人。它總是讓我感到驚訝。
@Rocketmagnet這個問題正在乞求像我的回答:-p。這只是一種意見,我可以同意不同意。哎呀,我做了很多Arduino編程,而這些都是基於C ++的。這並不意味著我必須喜歡它。
我什至更進一步。如果您的“嵌入式系統”是8位的,非常受內存/資源的限制,沒有操作系統,那麼任何超越舊C語言的東西都會增加開銷。另一方面,例如,如果它是具有Linux的BeagleBoard,足夠的資源且沒有近RT要求,則使用Mono和C#。生產率和可維護性將提高幾個數量級。 C ++只是給您帶來C的所有麻煩,而沒有簡單性和低開銷。


該問答將自動從英語翻譯而來。原始內容可在stackexchange上找到,我們感謝它分發的cc by-sa 2.0許可。
Loading...