1. 程式人生 > >使用VisualGDB開發Keil MDK-ARM專案

使用VisualGDB開發Keil MDK-ARM專案

前言

本教程展示瞭如何使用VisualGDB使用Keil MDK-ARM編譯器構建專案,使用VisualGDB智慧感知包括CodeMap,並使用Visual Studio除錯它。

步驟

在開始之前,確保您可以使用uVision IDE構建Keil專案

使用VisualGDB開發Keil MDK-ARM專案

 

開啟Visual Studio,開始建立一個新的嵌入式VisualGDB專案:

使用VisualGDB開發Keil MDK-ARM專案

 

選擇“匯入專案”和“生成Makefile”選項:

使用VisualGDB開發Keil MDK-ARM專案

 

在下一頁選擇ARM工具鏈,然後選擇“手動指定標誌”,現在標誌為空:

使用VisualGDB開發Keil MDK-ARM專案

 

指定包含Keil專案的目錄。如果您沒有太多的檔案,您可以選擇“顯示所有原始檔在一起”,以平展Keil目錄結構:

使用VisualGDB開發Keil MDK-ARM專案

 

選擇一個除錯方法。在本例中,我們將使用STM32F411RE核子板中集成了ST-Link的OpenOCD:

使用VisualGDB開發Keil MDK-ARM專案

 

不要忘記手動選擇裝置型別。當您手動指定標誌時,VisualGDB將無法檢測它。

預設情況下,VisualGDB不會匯入程式集啟動檔案(.s),因此將其複製到新的專案目錄中,並通過上下文選單將其新增到專案中:

使用VisualGDB開發Keil MDK-ARM專案

 

現在我們需要從uVision專案匯入編譯器和連結器標誌。開啟uVision中的目標屬性,複製編譯器控制字串:

使用VisualGDB開發Keil MDK-ARM專案

 

指定的選項需要分為3類:

  • 包括目錄和前處理器巨集。這些選項對於智慧感知很重要。
  • Keil-specific選項。這些選項不相容gcc,並且會產生智慧感知錯誤。
  • “-c”和“-o”等指定檔名的選項。它們是由Makefile自動新增的。

下表對示例uVision專案的選項進行了分類:

使用VisualGDB開發Keil MDK-ARM專案

 

首先,我們將向專案屬性新增與智慧感知相關的選項。在第一頁開啟VisualGDB專案屬性,並指定從uVision標誌中提取的目錄的定義和包含目錄:

使用VisualGDB開發Keil MDK-ARM專案

 

注意,您可以指定與專案目錄相關的路徑(例如,RTE表示RTE)。

轉到Makefile Settings頁面,除去uVision flags中除了-g和-O0之外的所有gc特定的標誌(也禁用二進位制檔案生成):

使用VisualGDB開發Keil MDK-ARM專案

 

稍後我們將指定特定於keil的標誌。如果您在這裡輸入它們,它將會混淆基於clang的智慧感知引擎。

按下OK。VisualGDB將重新檢查標誌並更新智慧感知。開啟原始檔,確保沒有智慧感知錯誤,語法著色工作正常:

使用VisualGDB開發Keil MDK-ARM專案

 

現在,我們將更改Makefile,以使用Keil編譯器而不是GCC,並提供特定於Keil的標誌。開啟mcu.mak檔案:

使用VisualGDB開發Keil MDK-ARM專案

 

mcu.mak檔案指定了編譯器工具(CC, CXX, LD和AR)和智慧感知引擎使用的公共標誌。因為我們不想破壞智慧感知,所以我們將在不同的地方指定它們,而不是修改這個檔案。在此之前,開啟Keil目標選項並注意連結器標誌:

使用VisualGDB開發Keil MDK-ARM專案

 

現在我們將指定特定於keil的標誌。建立一個名為keil的檔案。mak在專案目錄中,放置剩餘的C/ c++標誌和連結器標誌,以及CC、CXX和其他工具的覆蓋:

使用VisualGDB開發Keil MDK-ARM專案

 

以下是keil.mak的樣本內容:

KEIL_ROOT := C:/Keil_v5/ARM/ARMCC

CC := $(KEIL_ROOT)/bin/armcc.exe

CXX := $(CC)

LD := $(KEIL_ROOT)/bin/armlink.exe

AR := $(KEIL_ROOT)/bin/armar.exe

FROMELF := $(KEIL_ROOT)/bin/fromelf.exe

COMMONFLAGS += --cpu Cortex-M4.fp --apcs=interwork

LDFLAGS += --cpu Cortex-M4.fp

--ro-base 0x08000000

--entry 0x08000000

--rw-base 0x20000000

--entry Reset_Handler

--first __Vectors

--strict

--summary_stderr

--info summarysizes

--map

--xref

--callgraph

--symbols

--info sizes

--info totals

--info unused

--info veneers

--list "$(BINARYDIR)/stm32demo.map"

最後,我們需要調整Makefile。首先,指定“ADDITIONAL_MAKE_FILES += keil”。麥鴻崧說:“兩者之間包括以下指示:

include $(CONFIGURATION_FLAGS_FILE)
ADDITIONAL_MAKE_FILES += keil.mak
include $(ADDITIONAL_MAKE_FILES)

然後用“–depend”替換所有“-MD -MF”

$(BINARYDIR)/%.o : %.cpp $(all_make_files) |$(BINARYDIR)
$(CXX) $(CXXFLAGS) -c $< -o [email protected] --depend $(@:.o=.dep)

如果你現在構建你的專案,你將會得到幾個錯誤關於丟失的HAL符號:

使用VisualGDB開發Keil MDK-ARM專案

 

要解決這個問題,首先通過uVision找到HAL資料夾:

使用VisualGDB開發Keil MDK-ARM專案

 

該資料夾中的原始檔實現了各種HAL功能:

使用VisualGDB開發Keil MDK-ARM專案

 

在解決方案資源管理器中右鍵單擊,選擇Add->現有項並向專案新增HAL原始檔。然後構建你的解決方案。雙擊VisualGDB使用Keil編譯器和連結器的構建日誌:

使用VisualGDB開發Keil MDK-ARM專案

 

現在按F5開始除錯程式。一旦你驗證了LED是閃爍的,在你的程式迴圈的某處設定一個斷點,並驗證你可以計算變數:

使用VisualGDB開發Keil MDK-ARM專案

 

右鍵點選main()函式,開啟CodeMap,選擇“show called functions”來驗證Clang智慧感知:

使用VisualGDB開發Keil MDK-ARM專案

 

由Keil連結器生成的ELF檔案有一個基本問題。如果用GDB載入它,全域性變數的值將是-1,而不是正常的初始值:

使用VisualGDB開發Keil MDK-ARM專案

 

這是因為GNU和Keil連結器之間的差異。GNU連結器為資料部分計算兩個不同的地址:載入它的地址(VMA)和儲存其內容的快閃記憶體地址(LMA)。然後,GDB將節內容放在LMA地址,啟動程式碼將其複製到VMA。Keil連結器設定了LMA = VMA,因此GDB沒有將資料部分寫入FLASH中,而是直接將其放入RAM中,在RAM中會被Keil statup程式碼覆蓋,該程式碼希望它在FLASH中。為了解決這個問題,我們首先需要找到節名。arm-eabi-objdump執行。exe -x (objdump工具是GCC工具鏈的一部分):

使用VisualGDB開發Keil MDK-ARM專案

 

我們將通過兩個步驟來解決這個問題:首先,我們將執行名為fromelf的Keil工具。exe將ELF檔案轉換為.bin檔案,以反映Keil工具所期望的FLASH記憶體內容:

使用VisualGDB開發Keil MDK-ARM專案

 

然後,我們將使用objcopy工具編輯.elf檔案,用.bin檔案的內容替換複製到快閃記憶體中的資料。這將確保GDB將初始化資料以Keil期望的方式放入FLASH中:

使用VisualGDB開發Keil MDK-ARM專案

 

經過修改的Makefile片段如下所示(片段名稱和地址取決於裝置,應該從原始elf檔案轉儲中取出):

使用VisualGDB開發Keil MDK-ARM專案

 

下圖解釋了.axf (KEIL ELF)、.bin和最終.elf檔案之間的依賴關係:

使用VisualGDB開發Keil MDK-ARM專案

 

現在構建專案並驗證變數是否正確初始化:

使用VisualGDB開發Keil MDK-ARM專案

 

如果它們仍然被破壞,通過檢查arm-eabi-objdump工具生成的轉儲檔案,再次檢查ROM部分是否被放置在正確的地址,其大小是否與bin檔案的大小匹配:

使用VisualGDB開發Keil MDK-ARM專案

 

因為我們已經手動建立了這個專案,VisualGDB不會顯示裝置的外圍暫存器。要解決這個問題,請為您的裝置建立一個普通的VisualGDB專案,並搜尋。MCUDefinitionFile元素專案目錄中的xml檔案,例如:

使用VisualGDB開發Keil MDK-ARM專案

 

在%LOCALAPPDATA%VisualGDBEmbeddedBSPs中查詢檔案(它將具有.gz副檔名),並將其複製到包含mcu的目錄中。匯入Keil專案的xml檔案。然後修改mcu。xml檔案引用裝置定義檔案:

使用VisualGDB開發Keil MDK-ARM專案

 

重新開始除錯您的專案,並驗證硬體暫存器現在顯示:

使用VisualGDB開發Keil MDK-ARM專案

 

最後,我們將修復Keil錯誤訊息的解析。由於它們使用的語法與GCC不同,VisualGDB預設不會識別它們。您可以通過新增一個簡單的函式來重現這個問題,該函式將產生警告和錯誤,並嘗試構建您的檔案:

使用VisualGDB開發Keil MDK-ARM專案

 

使用VisualGDB開發Keil MDK-ARM專案

 

為了支援“, line ”格式,下載BuildMessageRegexes。xml檔案,將其儲存到您的專案目錄(或附近的任何其他目錄),並在.vgdbsettings檔案中指定它的相對路徑,如下所示:

使用VisualGDB開發Keil MDK-ARM專案

 

如果您現在構建專案,Visual Studio將正確顯示錯誤和警告:

使用VisualGDB開發Keil MDK-ARM專案

 

如果您正在使用VisualGDB和Keil編譯器,請在論壇中告訴我們。一旦我們收集了足夠的反饋,我們將在下一個VisualGDB版本中簡化與Keil工具的整合。