我知道在計算機中, main()
函數返回的值被操作系統接收。但是,在 main()
函數中微控制器?
我知道在計算機中, main()
函數返回的值被操作系統接收。但是,在 main()
函數中微控制器?
在微控制器上,實際上並不會期望 main()
退出,並且如果行為未定義,則取決於為微控制器編寫C運行時的人。我看到過這樣的系統:
main()
周圍有一個隱式循環,因此,如果退出,則只需再次調用它即可。 main()
退出,則會執行該循環。 main()
之後。這被稱為“逃入野草”。我從未見過有人真正對 main()
返回的值進行任何操作。如果這是您真正關心的事情,那麼您應該查看並可能修改系統C運行時庫的源代碼。
一個常見的誤解/誤解是 int main
是標準指定的唯一有效形式。那是不對的。
C標準涉及兩種實現:託管和獨立。在這種情況下,“實施”是指編譯器。託管編譯器針對特定的OS進行編譯,而獨立編譯器針對特定的裸機應用進行編譯。嵌入式系統幾乎總是獨立的系統-即使是RTOS。
獨立的實現可以對 main()
使用任何形式,甚至不需要一個名為main的函數。大多數情況下,它們使用 void main(void)
的形式,因為返回任何內容都沒有意義。
在這裡要意識到的重要一點是,始終由編譯器決定 main()
的形式,而不是由程序員決定。
要做從 main()
返回某些內容的獨立實現非常有問題。讓您想知道編寫編譯器的人是否真的閱讀了標準...
詳細信息。
C語言標准允許實現定義的變體 void main(void)
,這是嵌入式系統中的常見形式-只是因為預期它們不會返回。
如果您查看編譯器的設置,通常會有一個自舉代碼段,從復位向量中調用,它會在調用main()之前執行一些基本的初始化操作(包括將初始化值複製到變量中)。 p>如果 main()
返回
它(如其他答案所述)取決於您的工具鏈,但是例如在GCC中, main
被編譯為其他函數,因此其返回值將根據調用約定進行存儲(在ARM上,
我猜這在AVR-GCC上是類似的,因此自定義腳本可以在主返回之後使用該值。
您不能在沒有引導程序的情況下進入C引導程序代碼,理想情況下,該代碼是用asm編寫的(如果在C語言中您遇到了雞和雞蛋的問題),則準備了運行C的環境來設置堆棧,preps .data,preps .bss ,然後調用main。有些人認為主線永遠不會回來,但是裸機的美麗在於一切。您當然可以在單片機中從main返回,例如,當發生致命事件時,或者如果您的設計是100%事件(中斷)驅動的,則設置所有外設和中斷,然後返回並讓自舉旋轉成無限循環,即比一段時間還漂亮(1)繼續;在main()代碼中。
許多人使用罐頭庫和環境來使裸機感覺不像裸機,而對下面發生的事情負責,卻不想看或控制它。再次成為裸機之美的一部分。
當主要收益取決於系統(無論是操作系統還是MCU上的裸機)時會發生什麼。明智的設計應允許main返回引導程序,然後根據該設計選擇要執行的操作,至少要進入無限循環。
main()在大多數情況下只是編譯器的另一個函數名稱,某些工具鏈在看到該函數時會添加一些額外的內容,因此您應在裸機環境中謹慎使用該函數,以避免在這種資源受限的環境中產生過多的負擔。使用名稱main()以外的C入口點來避免該問題不是不明智的做法,但是自然地,這通常涉及對整個事物進行控制,而不是僅向其他人的沙箱添加幾行(編寫您自己的引導程序和可能的鏈接器)腳本,因此也可能是庫(這不是一個壞主意)。
一旦接管您,您肯定可以從main那裡得到返回值,在中斷驅動設計的情況下,main()可以簡單地啟動運動,然後返回無限或等待中斷循環。引導程序,但您可以選擇讓返回值導致採取行動(如果不為零),然後進行時鐘門控或將所有外設置於復位狀態以實現低功耗啟動失敗。
簡短的回答:返回值進入以太坊,因為通常您直接進入無限循環,或者在引導程序假設發生了某些不良情況並關閉或取消完成您在應用程序部分中配置的任何內容後,就進入無限循環。任何不允許main()返回的沙箱都是避免使用的沙箱,它至少應具有最小的支持(無限循環)。
更短的答案:誰收到返回值?您應對此應用負責,因此需要執行引導程序。