[STM32] 在 Windows 下使用 VSCode 架設 STM32 開發環境

1. 所需安裝的軟體 GNU Arm Embedded Toolchain : 下載壓縮檔,解壓到你想擺放的目錄。例如:c:\stm32\gcc-arm\ GNU MCU Eclipse Windows Build Tools : 這是 make 和相關的軟體,也可以使用 cygwin 或 mingw 內的工具,但我發現這包最簡潔。下載壓縮檔後將其解開,把裡面 bin 目錄下的執行檔複製到你想擺放的目錄。例如:c:\stm32\build tools\ OpenOCD : 這是燒 code 和 debug 的工具。下載壓縮檔,解壓到你想擺放的目錄。例如:c:\stm32\openocd\ VSCode : 這次的主角,編輯器和整合的操作介面。下載安裝程式執行,依指示安裝。安裝過程中有選項可將開啟檔案和開啟目錄加入滑鼠右鍵選單,建議打勾,以後開啟專案比較方便。 ST-Link Utility : STM32 原廠開發版的驅動程式和燒錄工具 STM32CubeMX (非必備): ST 提供的程式碼生成工具,利用它產生 makfile 的專案比較快 2. VSCode 的設定 由於 VSCode 的 Build 和 Debug 設定是存放在專案目錄下 .vscode/ 裡的 tasks.json 和 launch.json ,以下的操作必需是以 Folder 的方式開啟專案目錄才能用。你可以在檔案總管中,在專案的目錄上按右鍵,選"Open with Code"(安裝時必需有打開滑鼠右鍵選單功能)。或是在 VSCode 內用 "Open Folder" 打專案的目錄。 2.1 安裝 Extensions 第一次使用 VSCode 先從左側打開 Extensions 的側欄,安裝下列 Extensions。 C/C++ (Microsoft) Cortex-Debug 打開 settings,設定 cortex-debug 需要的路徑 "cortex-debug.openocdPath": "c:/stm32/openocd/bin/openocd.exe", "cortex-debug.armToolchainPat

[STM32] 2. 建立專案

2.1 建立樣板專案

STmicroelectronics 提供的標準函式庫中,已經有其他編譯器用的樣板專案。我們從裡面去修改成 gcc 用的樣板專案。一開始建立專案的步驟較為繁瑣,所以先建立一個空的專案當作樣板留下來,以後要寫程式就可以直接把樣板複製一份。
  1. 建立一個放置專案的目錄 stm32f466 ,並在裡面再建立子目錄 src 和 inc
  2. 將從 STmicroelectronics 下載的 stm32f4_dsp_stdperiph_lib.zip 解壓縮,放在自己習慣的目錄
  3. 進入 Project\STM32F4xx_StdPeriph_Templates\
  4. 將 main.c, stm32f4xx_it.c, system_stm32f4xx.c 複製到 stm32f466\src\ 下
  5. 將 main.h, stm32f4xx_conf.h, stm32f4xx_it.h 複製到 stm32f466\inc\ 下
  6. 再進入 TrueSTUDIO\STM32F446xx\
  7. 將 STM32F446ZETx_FLASH.ld 複製到 stm32f466\ 下
  8. 回到 stm32f4_dsp_stdperiph_lib 的最上層
  9. 進入 Libraries\CMSIS\Device\ST\STM32F4xx\Include\
  10. 將 stm32f4xx.h, system_stm32f4xx.h 複製到 stm32f466\inc\ 下
  11. 回到上一層,進入 Source\Templates\TrueSTUDIO\
  12. startup_stm32f446xx.s 複製到 stm32f466\src\ 下
  13. 回到 Libraries\CMSIS\ ,進入 Incluse\
  14. 將 core_cm4.h, core_cmFunc.h, core_cmInstr.h, core_cmSimd.h 複製到 stm32f466\inc\ 下
  15. 回到 Libraries\
  16. 將 STM32F4xx_StdPeriph_Driver 整個目錄複製一份到 stm32f466\src\ 下
  17. 根據 mcufreaks 的網頁打造 makefile 或是下載製作好的版本: makefilecommon.mk。放到 stm32f466\ 下
接著就能進入 DOS 的開發環境,打 make 進行編譯。編譯完成的檔案會放在 stm32f446\bin 下。

目前專案中各檔案內容的簡單說明如下
  • core_cm4.h, core_cmFunc.h, core_cmInstr.h, core_cmSimd.h:CORTEX-M4 的標準介面
  • stm32f4xx_conf.h, stm32f4xx.h, system_stm32f4xx.h, system_stm32f4xx.c:STM32F4 週邊硬體的介面以及開機時的 clock 設定
  • startup_stm32f446xx.s:中斷向量表及 reset_handler ( reset 後進入 main() 之前的程式 )
  • stm32f4xx_it.h, stm32f4xx_it.c:中斷服務常式
  • STM32F4xx_StdPeriph_Driver:STM32F4 週邊硬體的標準函式庫
  • STM32F446ZETx_FLASH.ld:STM32F446 的 Linker Script,定義最後程式的記憶體配置。只需確認 FLASH 和 RAM 的大小是否正確,在弄懂 Linker Script 之前,不要去修改它
  • makefile, common.mk:定義編譯專案的流程。當專案增加檔案或是目錄結構變動時,就需要修改 makefile 內容
其中 makefile 是較需要注意的檔案,裡面分別設定了 .h 和 .c 檔的路徑和需要編譯的 .c 檔,如果新增加檔案或是改變目錄結構就需要修改內容。另外 makefile 裡面也有定義了一些常數名稱,-DUSE_STDPERIPH_DRIVER -DSTM32F446xx -D__FPU_PRESENT=1 ,這些都是 STM32F4 標準函式庫會用到的。

2.2 燒錄程式

2.2.1 使用 ST-LINK_CLI

ST-LINK_CLI.exe -c SWD -p "bin/STM32F446.hex" -Rst -Run

2.2.2 使用 OpenOCD

  1. 打開 dos 工作環境,進入專案目錄。輸入 openocd -f board/st_nucleo_f4.cfg ,成功後保留視窗不要關閉
  2. 打開 putty ,使用 telnet 連線 localhost , port: 4444 ,即可連上 Open On-Chip Debugger
  3. 輸入 reset halt ,將 mcu 重新啟動後停止
  4. 輸入 load_image bin/STM32F446.elf 0 ,將 STM32F446.elf 檔載入 flash address 0x00000000 的位址
  5. 輸入 reset run ,將 mcu 重新啟動後,繼續執行
  6. 如果沒有要繼續使用 Open On-Chip Debugger 可輸入 shutdown 關閉 putty 和 openocd
除了燒錄程式碼外,Open On-Chip Debugger 的環境內還可以執行其他 debug 的命令,如讀寫記憶體等。詳細操作可參考 openocd 目錄下的 OpenOCD User’s Guide.pdf。若只是要單純燒錄程式碼,上述動作可結合成下面一行 dos 命令

  • openocd -f board/st_nucleo_f4.cfg -c "init" -c "reset halt" -c "load_image bin/STM32F446.elf 0" -c "reset run" -c "shutdown"

2.3 建立 eclipse 專案

2.3.1 設定 Workspace

進入 eclipse 時要要求選擇一個 Workspace 的目錄,這是 eclipse 存放工作環境設定的目錄,以後新建專案會放在這個目錄下。依個人習慣選擇一個放專案的目錄即可。如果不想每個打開 eclipse 都問一次,記得把 "Use this as the default and do not ask again" 打勾。
將 make 需要用到的程式路徑加入環境設定中。從上方的 Menu bar 點選 Window 再選 Preferences 打開設定視窗。選到 C/C++ -> Build -> Environment 分頁,點選 Add 加入一個新的環境變數。欄位 Name 填寫 PATH ,欄位 Value 填寫 d:\ARM-SDK\cygwin\;d:\ARM-SDK\gcc-arm\bin\;d:\ARM-SDK\gcc-arm\arm-none-eabi\bin\

修改將 eclipse 自動搜尋 Include Paths 。選到 C/C++ -> Build -> Setting。選到 Discovery 分頁,點 CDT Cross GCC Built-in Compiler Settings [Shared]。將下方 Command to get compiler specs: 中的 ${COMMAND} 改成 arm-none-eabi-gcc.exe

2.3.2 建立 Project

  1. 開啟 New 的視窗
  2. 選擇 C/C++ 裡的 Makefile Project with Existing Code
  3. 填寫 Project Name ,選擇 Existing Code Location
  4. Languages 要勾 C ,C++ 可勾可不勾
  5. Toolchain for Indexer Setting 選 Cross GCC
  6. 最後點選 Finish 按鈕,Project 就建好了

2.3.3 設定 Project Properties

eclipse 無法自動找到 makefile 中的 define ,因此需要手動加入。
  1. 打開 Project 選單,選擇 Properties 打開設定視窗
  2. 左邊選擇 C/C++ General 下的 Paths and Symbols
  3. 右邊選擇 Symbols 分頁,Langiages 選擇 GNU C
  4. 新增 USE_STDPERIPH_DRIVER 和 STM32F446xx
  5. 新增 __FPU_PRESENT ,值記得設定為 1
  6. 左邊選擇 Preprocessor Include Paths, Macros etc.
  7. 選擇 Providers 分頁,選擇 CDT Cross GCC Built-in Setting Entries [Shared]
  8. 將下方 Use global provider shared between projects 打勾
設定完成後,eclipse 的 indexer 就能正確解析程式碼內容了。若覺得每次設定 Symbols 很麻煩,可以利 Symbols 頁面的下方 Export Setting 按鈕將設定存成檔案,以後新的專案再利用 Import Settings 載入即可。

2.4 參考資料:

留言

  1. 您好,我目前也在使用STM32F446,之前都是使用 Keil MDK 做開發,日前發現 Keil 可以支援 GCC 編譯器,這幾天嘗試改成 GCC 來編譯,但對 __libc_init_array 的問題一直無法解決,因本身沒有碰過這種底層與 GNU 的相關經驗,想請教您是否在使用 GCC 編譯過程中也有遇到相同問題?


    在 Keil 中使用 GCC 編譯的方法大致與以下教學相同 http://eeontheway.com/1170.html
    xxx.ld 與 xxx.s 都是從 STM32F4_StdPeriph_Lib_V1.7.1/.../TrueSTUDIO 拉進來的


    以下是完整的錯誤訊息:

    linking...
    c:/program files (x86)/gnu tools arm embedded/5.4 2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/lib/armv7e-m\libc.a(lib_a-init.o): In function `__libc_init_array':
    init.c:(.text.__libc_init_array+0x22): undefined reference to `_init'
    collect2.exe: error: ld returned 1 exit status


    希望可以給予解決方向或方法,非常謝謝:)

    回覆刪除
    回覆
    1. 幫你 google 了一下。根據下面這篇,應該是 Keil 使用的 link 參數 -nostartfiles 的關係,而一般是使用 --gc-sections。
      http://stackoverflow.com/questions/13734745/why-do-i-have-an-undefined-reference-to-init-in-libc-init-array

      刪除

張貼留言

這個網誌中的熱門文章

[STM32] 3. USART 的發送與接收

[STM32] 在 Windows 下使用 VSCode 架設 STM32 開發環境

[STM32] 4. 移植 FreeRTOS