web-dev-qa-db-ja.com

GDB(Gnu Debugger)とOpenOCDをマイクロコントローラーのデバッグに使用する方法-端末から?

ARMマイクロコントローラーをプログラミングする標準的な(低コスト)の方法は、Eclipseに複雑なツールチェーンをプラグインして使用することです。ソフトウェアをビルド(コンパイル-リンク-フラッシュ)し、デバッグセッションを実行すると、舞台裏で何が起こるかを知りたいのですが、このようなより深い理解を得るには、コマンドから手順全体を実行するのが素晴らしいでしょうライン。

注:64ビットWindows 10を使用していますが、ここで説明するほとんどの内容はLinuxシステムにも適用されます。管理者権限ですべてのコマンド端末を開いてください。これにより、多くの問題を回避できます。

1。ソフトウェアの構築

最初の「ミッション」が達成されます。コマンドラインを使用して、ソフトウェアをコンパイルし、バイナリ.binおよび.elfイメージにリンクできるようになりました。成功の鍵は、Eclipseが特定のプロジェクトのメイクファイルをどこに置くかを見つけることでした。それらがどこにあるかがわかったら、コマンドターミナルを開いてGNU makeコマンドを入力するだけです。

enter image description here

そのためにEclipseはもう必要ありません!特に、メイクファイルを読み(理解し)、プロジェクトの進行時にニーズに合わせて調整できる場合。

SW4STM32(System Workbench for STM32)をインストールした後、次のフォルダーにGNUツール(コンパイラー、リンカー、makeユーティリティー、GDBなど)が見つかりました。

C:\Ac6\SystemWorkbench\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.7.0.201602121829\tools\compiler\

次に、ハードドライブに新しいフォルダーを作成し、これらすべてのGNUツールをコピーしました:

C:\Apps\AC6GCC
           |-> arm-none-eabi
           |-> bin
           '-> lib

そして、これらのエントリを「環境パス変数」に追加します。

 - C:\Apps\AC6GCC\bin
 - C:\Apps\AC6GCC\lib\gcc\arm-none-eabi\5.2.1

Huray、すべてのGNUツールをシステムで起動して実行しました!次のbuild.batファイルをmakefileと同じフォルダーに配置しました:

@echo off
echo.
echo."--------------------------------"
echo."-           BUILD              -"
echo."--------------------------------"
echo.

make -j8 -f makefile all

echo.

このbat-fileを実行すると、仕事ができるはずです!すべてうまくいけば、コンパイルの結果として、1つの.binと1つの.elfバイナリファイルが得られます。

2。ファームウェアのフラッシュとデバッグ

次の自然なステップは、ファームウェアをチップにフラッシュし、デバッグセッションを開始することです。 Eclipseでは、「ボタンをクリックする」だけです-少なくともEclipseがマイクロコントローラー用に正しく構成されている場合。しかし、舞台裏で何が起こるのでしょうか? OpenOCDの開発者であるDominic Rathの修士論文(の一部)を読みました。ここで見つけることができます: http://openocd.net/ 。これは私が学んだことです:

  • 「デバッグ」アイコンをクリックすると、EclipseはOpenOCDソフトウェアを起動します。 EclipseはOpenOCDにいくつかの構成ファイルも提供します。これにより、OpenOCDはマイクロコントローラーへの接続方法を認識します。 「接続方法」は簡単なことではありません。 OpenOCDは、JTAGアダプター(STLinkなど)に接続するための適切なUSBドライバーを見つける必要があります。 JTAGアダプターとそのUSBドライバーの両方は、通常、チップメーカー(STMicroelectronicsなど)から提供されます。 Eclipseは、マイクロコントローラーの仕様を記述する構成ファイルをOpenOCDに渡します。 OpenOCDがこれらすべてを認識すると、ターゲットデバイスへの信頼できるJTAG接続を確立できます。

  • OpenOCDは2つのサーバーを起動します。 1つ目は、TCPポート4444上のTelnetサーバーです。OpenOCDCLI(コマンドラインインターフェイス)へのアクセスを提供します。Telnetクライアントは、OpenOCDに接続してコマンドを送信できます。単純な「停止」、「実行」、「ブレークポイントの設定」、...

  • このようなコマンドは、マイクロコントローラーのデバッグには十分かもしれませんが、多くの人々はすでにGnu Debugger(GDB)に精通しています。 OpenOCDがTCPポート3333でGDBサーバーも起動するのはこのためです。GDBクライアントはそのポートに接続して、マイクロコントローラーのデバッグを開始できます!

  • Gnuデバッガーはコマンドラインソフトウェアです。多くの人々は視覚的なインターフェースを好む。それがまさにEclipseのすることです。 Eclipseは、OpenOCDに接続するGDBクライアントを起動しますが、それはすべてユーザーに隠されています。 Eclipseは、バックグラウンドでGDBクライアントと対話するグラフィカルインターフェイスを提供します。

これらすべてを説明する図を作成しました。

enter image description here

>> OpenOCDの起動

コマンドラインからOpenOCDを起動できました。その方法を説明します。

  1. まず、STLink-V2 JTAGプログラマーが正しくインストールされていることを確認してください。 STMicroelectronicsの「STLink Utilityツール」を使用してインストールをテストできます。素敵なGUIがあり、接続ボタンをクリックするだけです。 enter image description here
  2. 次に、このWebサイトからOpenOCDソフトウェア実行可能ファイルをダウンロードします: http://gnutoolchains.com/arm-eabi/openocd/ それをインストールし、「C:\ Apps \」などのハードドライブ上のフォルダーに入れます。
  3. コマンドターミナルを開き、OpenOCDを起動します。 OpenOCDにいくつかの構成ファイルを提供する必要があります。これにより、マイクロコントローラーを探す場所を知ることができます。通常、JTAGプログラマーを記述する構成ファイルと、マイクロコントローラーを定義する構成ファイルを提供する必要があります。コマンドラインで-f引数を使用して、これらのファイルをOpenOCDに渡します。また、-s引数を渡してOpenOCDにscriptsフォルダーへのアクセスを許可する必要があります。これは、コマンドラインを使用してコンピューターでOpenOCDを起動する方法です。

    > "C:\Apps\OpenOCD-0.9.0-Win32\bin\openocd" -f "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts\interface\stlink-v2.cfg" -f "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts\target\stm32f7x.cfg" -s "C:\Apps\OpenOCD-0.9.0-Win32\share\openocd\scripts"
    
  4. OpenOCDを(正しい引数で)適切に起動すると、次のメッセージが表示されて起動します。

    Open On-Chip Debugger 0.9.0 (2015-08-15-12:41)
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    adapter speed: 2000 kHz
    adapter_nsrst_delay: 100
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : Unable to match requested speed 2000 kHz, using 1800 kHz
    Info : clock speed 1800 kHz
    Info : STLINK v2 JTAG v24 API v2 SWIM v4 VID 0x0483 PID 0x3748
    Info : using stlink api v2
    Info : Target voltage: 3.231496
    Info : stm32f7x.cpu: hardware has 8 breakpoints, 4 watchpoints
    Info : accepting 'gdb' connection on tcp/3333
    Info : flash size probed value 1024
    
  5. 端末ウィンドウがブロックされていることに注意してください。コマンドを入力できなくなりました。しかし、それは正常です。 OpenOCDはバックグラウンドで実行されており、ターミナルをブロックします。これで、OpenOCDと対話するための2つのオプションがあります。別の端末でTelnetセッションを開始し、TCP port localhost:4444にログオンして、OpenOCDにコマンドを与えることができますまたは、GDBクライアントセッションを開始して、TCP port localhost:3333。]に接続します。

>> OpenOCDと対話するためのTelnetセッションの起動

これは、実行中のOpenOCDプログラムと対話するためにTelnetセッションを開始する方法です。

> dism /online /Enable-Feature /FeatureName:TelnetClient

> telnet 127.0.0.1 4444

正常に機能する場合、端末に次のメッセージが表示されます。

Open On-Chip Debugger
> ..

これで、コマンドをOpenOCDに送信する準備が整いました!しかし、ここではGDBセッションに切り替えます。これはOpenOCDと対話するための最も便利な方法だからです。

>> OpenOCDと対話するためのGDBクライアントセッションの起動

さらに別のターミナルウィンドウを開き、次のコマンドを入力します。

> "C:\Apps\AC6GCC\bin\arm-none-eabi-gdb.exe"

このコマンドは、単にarm-none-eabi-gdb.exe GDBクライアントを起動します。すべてうまくいけば、GDBは次のメッセージで起動します。

    GNU gdb (GNU Tools for ARM Embedded Processors) 7.10.1.20151217-cvs
    Copyright (C) 2015 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "--Host=i686-w64-mingw32 --target=arm-none-eabi".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos Word" to search for commands related to "Word".
    (gdb)..

次に、このGDBクライアントをOpenOCD内のGDBサーバーに接続します。

    (gdb) target remote localhost:3333

これでOpenOCDに接続できました!知っておきたいこと:ネイティブOpenOCDコマンドを(Telnetセッションで行うのと同じように)使用する場合は、コマンドの前にキーワードmonitorを付けてください。これにより、OpenOCD内のGDBサーバーはコマンドを自分で処理せず、ネイティブOpenOCDデーモンに渡します。

それで、今度はチップをリセットし、消去して停止します。

    (gdb) monitor reset halt
       target state: halted
       target halted due to debug-request, current mode: Thread
       xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
    (gdb) monitor halt

    (gdb) monitor flash erase_address 0x08000000 0x00100000
       erased address 0x08000000 (length 1048576) in 8.899024s (115.069 KiB/s)
    (gdb) monitor reset halt
       target state: halted
       target halted due to debug-request, current mode: Thread
       xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
    (gdb) monitor halt

これで、チップから指示を受け取る準備ができました。最初に、フラッシュセクション0〜7(1Mbチップのすべてのフラッシュセクション)を保護しないようにチップに指示します。

    (gdb) monitor flash protect 0 0 7 off

    (gdb) monitor flash info 0
       #0 : stm32f7x at 0x08000000, size 0x00100000, buswidth 0, chipwidth 0
            #  0: 0x00000000 (0x8000 32kB) not protected
            #  1: 0x00008000 (0x8000 32kB) not protected
            #  2: 0x00010000 (0x8000 32kB) not protected
            #  3: 0x00018000 (0x8000 32kB) not protected
            #  4: 0x00020000 (0x20000 128kB) not protected
            #  5: 0x00040000 (0x40000 256kB) not protected
            #  6: 0x00080000 (0x40000 256kB) not protected
            #  7: 0x000c0000 (0x40000 256kB) not protected

次に、チップを再び停止します。念のために..

    (gdb) monitor halt

最後に、バイナリ.elfファイルをGDBに渡します。

    (gdb) file C:\\..\\myProgram.elf
       A program is being debugged already.
       Are you sure you want to change the file? (y or n) y
       Reading symbols from C:\..\myProgram.elf ...done.

今こそ真実の瞬間です。このバイナリをチップにロードするようGDBに依頼します。成功を祈っている:

    (gdb) load
       Loading section .isr_vector, size 0x1c8 lma 0x8000000
       Loading section .text, size 0x39e0 lma 0x80001c8
       Loading section .rodata, size 0x34 lma 0x8003ba8
       Loading section .init_array, size 0x4 lma 0x8003bdc
       Loading section .fini_array, size 0x4 lma 0x8003be0
       Loading section .data, size 0x38 lma 0x8003be4
       Error finishing flash operation

残念ながら成功しませんでした。 OpenOCDで次のメッセージが表示されます。

    Error: error waiting for target flash write algorithm
    Error: error writing to flash at address 0x08000000 at offset 0x00000000

EDIT:ハードウェアの問題が修正されました。

どうやらそれはハードウェアの問題でした。 STLink Utilityツールを使用してバイナリをチップにロードすると問題なく機能したため、チップに欠陥があるとは思っていませんでした。 OpenOCDのみが文句を言い、エラーを出していました。当然、私はOpenOCDを非難しました-チップ自体ではありません。詳細については、以下の回答を参照してください。


編集:チップをフラッシュする代替のエレガントな方法-メイクファイルを使用して!

問題が修正されたので、フラッシュを実行してチップをデバッグする別の方法に焦点を当てます。これはコミュニティにとって本当に面白いと思います!

Windowsのcmdコマンドを使用して、必要なすべてのステップを実行したことに気づいたかもしれません。これはバッチファイルで自動化できます。しかし、もっとエレガントな方法があります。メイクファイルのすべてを自動化することです! Mr./Mss。 Othaneは彼/彼女のCortex-M用に次のメイクファイルを提案しましたか?チップ。 Cortex-M7チップの手順は非常に似ていると思います。

            #################################################
            #        MAKEFILE FOR BUILDING THE BINARY       #
            #        AND EVEN FLASHING THE CHIP!            #
            # Author: Othane                                #
            #################################################

    # setup compiler and flags for stm32f373 build 
    SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 


    CROSS_COMPILE ?= arm-none-eabi- 
    export CC = $(CROSS_COMPILE)gcc 
    export AS = $(CROSS_COMPILE)gcc -x assembler-with-cpp 
    export AR = $(CROSS_COMPILE)ar 
    export LD = $(CROSS_COMPILE)ld 
    export OD   = $(CROSS_COMPILE)objdump 
    export BIN  = $(CROSS_COMPILE)objcopy -O ihex 
    export SIZE = $(CROSS_COMPILE)size 
    export GDB = $(CROSS_COMPILE)gdb 


    MCU = cortex-m4 
    FPU = -mfloat-abi=hard -mfpu=fpv4-sp-d16 -D__FPU_USED=1 -D__FPU_PRESENT=1 -DARM_MATH_CM4 
    DEFS = -DUSE_STDPERIPH_DRIVER -DSTM32F37X -DRUN_FROM_FLASH=1 -DHSE_VALUE=8000000 
    OPT ?= -O0  
    MCFLAGS = -mthumb -mcpu=$(MCU) $(FPU) 


    export ASFLAGS  = $(MCFLAGS) $(OPT) -g -gdwarf-2 $(ADEFS) 
    CPFLAGS += $(MCFLAGS) $(OPT) -gdwarf-2 -Wall -Wno-attributes -fverbose-asm  
    CPFLAGS += -ffunction-sections -fdata-sections $(DEFS) 
    export CPFLAGS 
    export CFLAGS += $(CPFLAGS) 


    export LDFLAGS  = $(MCFLAGS) -nostartfiles -Wl,--cref,--gc-sections,--no-warn-mismatch $(LIBDIR) 


    HINCDIR += ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/CMSIS/Include/ \ 
        ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/CMSIS/Device/ST/STM32F37x/Include/ \ 
        ./STM32F37x_DSP_StdPeriph_Lib_V1.0.0/Libraries/STM32F37x_StdPeriph_Driver/inc/ \ 
        ./ 
    export INCDIR = $(patsubst %,$(SELF_DIR)%,$(HINCDIR)) 




    # openocd variables and targets 
    OPENOCD_PATH ?= /usr/local/share/openocd/ 
    export OPENOCD_BIN = openocd 
    export OPENOCD_INTERFACE = $(OPENOCD_PATH)/scripts/interface/stlink-v2.cfg 
    export OPENOCD_TARGET = $(OPENOCD_PATH)/scripts/target/stm32f3x_stlink.cfg 


    OPENOCD_FLASH_CMDS = '' 
    OPENOCD_FLASH_CMDS += -c 'reset halt' 
    OPENOCD_FLASH_CMDS += -c 'sleep 10'  
    OPENOCD_FLASH_CMDS += -c 'stm32f1x unlock 0' 
    OPENOCD_FLASH_CMDS += -c 'flash write_image erase $(PRJ_FULL) 0 ihex' 
    OPENOCD_FLASH_CMDS += -c shutdown 
    export OPENOCD_FLASH_CMDS 


    OPENOCD_ERASE_CMDS = '' 
    OPENOCD_ERASE_CMDS += -c 'reset halt' 
    OPENOCD_ERASE_CMDS += -c 'sleep 10'  
    OPENOCD_ERASE_CMDS += -c 'sleep 10'  
    OPENOCD_ERASE_CMDS += -c 'stm32f1x mass_erase 0' 
    OPENOCD_ERASE_CMDS += -c shutdown 
    export OPENOCD_ERASE_CMDS 


    OPENOCD_RUN_CMDS = '' 
    OPENOCD_RUN_CMDS += -c 'reset halt' 
    OPENOCD_RUN_CMDS += -c 'sleep 10' 
    OPENOCD_RUN_CMDS += -c 'reset run' 
    OPENOCD_RUN_CMDS += -c 'sleep 10'  
    OPENOCD_RUN_CMDS += -c shutdown 
    export OPENOCD_RUN_CMDS 


    OPENOCD_DEBUG_CMDS = '' 
    OPENOCD_DEBUG_CMDS += -c 'halt' 
    OPENOCD_DEBUG_CMDS += -c 'sleep 10' 


    .flash: 
        $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_FLASH_CMDS) 


    .erase: 
        $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_ERASE_CMDS) 


    .run: 
        $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_RUN_CMDS) 


    .debug: 
        $(OPENOCD_BIN) -f $(OPENOCD_INTERFACE) -f $(OPENOCD_TARGET) -c init $(OPENOCD_DEBUG_CMDS) 

親愛なるMr./Mss。 Othane、次の手順でこのmakefileを使用する方法を説明できますか?

  • ソースコードからバイナリをビルドします
  • チップをフラッシュ

メイクファイルに関するいくつかの基本を知っていますが、メイクファイルはかなり深くなっています。 GNU makeユーティリティ。

------------------------------

36
K.Mulier

私はそれを覚えているように、私はストレートロードコマンドでもいくつかの問題を抱えていたので、「flash write_image erase my_project.hex 0 ihex」に切り替えました..明らかにhexファイルを使用していましたが、elfファイルが動作するはずです、参照してください- http://openocd.org/doc/html/Flash-Commands.html ...このコマンドの良いところは、書き込み中のフラッシュセクションのみを消去することです。消去する必要はありません

上記のコマンドを実行する前に、「stm32f1x unlock 0」を実行して、チップのロックが解除され、フラッシュへの配線が許可されていることを確認する必要があります。

また、コマンド「stm32f1x mass_erase 0」を使用すると、チップが完全かつ迅速に消去されるため、既知の状態で起動することをお勧めします

これらのコマンドのいくつかは、f1向けであると言っていますが、f4シリーズでは

ところで、このファイルにはf4をフラッシュするために使用するコマンドの大部分が含まれているため、参考になります https://github.com/othane/mos/blob/master/hal/stm32f373/stm32f373.mk =

私はあなたが動けなくなることを願っています

7
othane

これは少し簡潔で、優れたstackoverflowスタイルではありませんが、STM32F4およびSTM32F1の「mos」ライブラリにこれを設定したコードを示します( https://github.com/othane/ mos )...これは答えるべき大きなトピックなので、例の方が良いかもしれませんが

要するに、私のプロジェクトはMakefileのツリーです。なぜなら、あなたが興味のある主なものをコンパイルしているコードがあるからです https://github.com/othane/mos/blob/master/hal/stm32f373 /stm32f373.mk ...基本的にopenocdが必要です。その後、make .eraseまたはmake .flashまたはmake .debugと入力するだけで、チップを消去したり、新しいコードをフラッシュしたりデバッグしたりできる一連のコマンドがあります。

最後に、ユニットテスト(これらは基本的にサンプルプログラムです)を見ると、ビルドするMakefile +このようなgdbinitファイルがあります https://github.com/othane/mos/blob/master/ utest/gpio/debug_gpio_utest.gdbinit ... 1つのターミナルで「make && make .flash && make .debug」を実行し、クロスコンパイラをこの「arm-none-eabi-gdb -x」のように呼び出します./debug_gpio_utest.gdbinit "別の...これは、コードをフラッシュした後にgdbを起動し、gdbなどからの通常のbreakおよびlistコマンドを使用してコードと対話できます(.gdbinitファイルでリセットコマンドを定義した方法に注意してください) 、monコマンドのヘルプをチェックアウトします。基本的には、gdbを介してコマンドを直接openocdに送信でき、非常に便利です)

申し訳ありませんが、答えは非常に簡潔で、多くのリンクがありますが、それがあなたの役に立つことを願っています。

2
othane

一見すると、gnutoolchains.comでの配布は十分なはずです。独自のバージョンを作成するためのビルドスクリプトがいくつかあります。 ARM7TDMIを含めるものがあります。 LinuxとFreeBSDでは問題なく動作しますが、前回試したときにMinGWが失敗しました:-(

OpenOCDについては、GDBインスタンスと同じディレクトリで起動することをお勧めします。これにより、GDB内からバイナリをダウンロードしたときに透過的に見えるようになります(最も簡単な方法)。 OpenOCDを起動してコードをロードするスクリプトを作成するオプションもありますが、コンパイルのたびに再起動する必要があります。

2
O. Gautherot

ここで、「gdb」を呼び出して「リモートサーバー」(サーバーとgdbが同じマシンで実行されている場合はlocalhost)に接続します。ソースコードの場所とELFファイルの場所を認識するようにGDBを構成します。 GDBの基本的な使用方法を説明するWebサイトがたくさんあります。

GDB for Windowsがあるようです( http://www.equation.com/servlet/equation.cmd?fa=gdb

GDBの次のコマンドで開始できます。

ターゲットリモートlocalhost:3333

ディレクトリ/ path/to/project

シンボルファイル/path/to/project.elf

1
user6520991

どうやらそれはハードウェアの問題でした。 STLink Utilityツールを使用してバイナリをチップにロードすると問題なく機能したため、チップに欠陥があるとは思っていませんでした。 OpenOCDのみが不平を言ってエラーを出していました。当然、私はOpenOCDを非難しました-チップ自体ではありません。

今日、ボード上の新しいチップで同じ手順を試してみましたが、今ではうまくいきます!

loadコマンドを発行すると、GDBに次の出力が表示されます。

    (gdb) load
       Loading section .isr_vector, size 0x1c8 lma 0x8000000
       Loading section .text, size 0x39e0 lma 0x80001c8
       Loading section .rodata, size 0x34 lma 0x8003ba8
       Loading section .init_array, size 0x4 lma 0x8003bdc
       Loading section .fini_array, size 0x4 lma 0x8003be0
       Loading section .data, size 0x38 lma 0x8003be4
       Start address 0x8003450, load size 15388
       Transfer rate: 21 KB/sec, 2564 bytes/write.
    (gdb)

私を助けるために最善を尽くしたすべての人に感謝します:-)

0
K.Mulier