2012-03-21 95 views
18

我正在使用ARM Cortex M3芯片(STM32F2),ST提供了一個「標準外設庫」。它有一些有用的.c和.h文件。它也有.s文件。.s文件在C項目中的作用是什麼?

這些.s文件在C項目上下文中的用途是什麼?我如何得到我的編譯器/鏈接器/?考慮到他們?

回答

27

.s擴展名是GNU和許多其他彙編程序文件工具鏈使用的約定。

最後,我查看了STM32標準外設庫本身不包含彙編文件,但是CMSIS庫包含各種STM32部件的啓動代碼,例如startup_stm32f2xx.s是所有STM32F2xx系列設備的啓動代碼。不同的工具鏈有不同的實現;您需要構建並鏈接與您的特定零件和工具鏈相關的文件。如果您正在使用構建和運行的示例項目,或者爲您創建針對特定部分的項目的IDE,則可能已經完成了這項工作 - 如果您擁有運行它的代碼肯定已經完成。

您如何構建和鏈接代碼將取決於您使用的工具鏈。大多數基於IDE的工具都會自動識別擴展名並調用匯編程序來生成一個像其他任何鏈接一樣鏈接的對象文件。工具鏈版本的確切內容略有不同,但主要是創建C運行時環境(堆棧和堆),初始化處理器,定義初始中斷/異常向量表,初始化靜態數據並跳轉到main()。

的凱爾/ ARM的RealView版本例如文件的核心是這樣的:

; Reset handler 
Reset_Handler PROC 
       EXPORT Reset_Handler    [WEAK] 
     IMPORT SystemInit 
     IMPORT __main 
       LDR  R0, =SystemInit 
       BLX  R0 
       LDR  R0, =__main 
       BX  R0 
       ENDP 

Reset_Handler是地址程序計數器(PC)寄存器將被設置爲一個處理器復位後。

SystemInit是一個外部C代碼函數,它執行大量的初始化 - 這可能需要爲您的硬件定製。 Cortex-M的特殊之處在於,它可以在復位後立即開始運行C代碼,因爲向量表包含復位地址和初始堆棧指針地址,它們在復位時自動加載到SP寄存器。因此,你不需要太多的彙編知識就可以運行。

__main()是編譯器爲您的C代碼提供的入口點。它不是您編寫的main()函數,而是在調用main()函數之前執行標準庫,靜態數據,堆的初始化。

由於GCC版本在Keil/ARM RealView版本中完成了__main()所做的大部分工作,但本質上它執行相同的功能。

請注意,CMSIS SystemInit()在system_stm32f2xx.c中定義,可能需要爲您的電路板進行定製(正確的晶體頻率,PLL設置,外部SRAM配置等)。因爲這是C代碼,而且評論很好,所以你可能會更加適應它。

+0

除了我只注意到你指定的STM32F2xx。答案仍然適用,除了相應的文件名是startup_stm32f2xx.s和system_stm32f2xx.c。我已經修改了答案,使其更加專用於STM32F2。 – Clifford 2012-03-22 15:22:08

+0

Clifford - 在ARM網站的文檔中,它提到startup_xxx.s中的另一個例程__user_initial_stack_heap不應該使用多於88個字節的堆棧。你知道這個限制來自哪裏嗎?見http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0099a/armlib_cihhdahf.htm – NickHalden 2014-10-29 23:11:06

+0

@NickHalden:你認爲也許這應該被視爲一個問題嗎?這個問題已經兩年多了,甚至沒有你的問題。這不是他評論部分的內容 - SO不是論壇。除了;你會以這種方式獲得更多的觀衆。 – Clifford 2014-10-29 23:46:12

7

它們通常包含彙編代碼。彙編器將它們轉換爲對象文件,然後由鏈接器將其與主要內容鏈接起來。但我想它取決於編譯器,工具鏈等。

1

您可能已經爲您的ST套件獲得了基於Keil的開發環境。根據編譯器的版本,項目文件應該有C,C++和彙編代碼的不同部分。在您的IDE中,打開您的項目並查找「項目屬性」或類似的東西。

您可以在彙編代碼中導入和導出符號,以便它和C/C++代碼鏈接。通過Keil,它們都可以很好地集成在一起。

EXPORT指令告訴彙編程序公開指定的符號,以便您的C/C++代碼可以鏈接到它。

IMPORT指令告訴彙編程序指定的符號是在別處定義的,並且會在鏈接時解析。

相關問題