{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# VScode(PlatformIO)+OpenOCDでjlink-OBを使い尽くす\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## jlink-OBとは\n", "jlink-OBは、JTAGデバッガーの一つで、ARMのCortex系のデバッグ方式SWDに対応しています。\n", "そのため、RaspberryPi-Pico, XIAO, LPC11U35, LPC812, LPC810, LPC1114FN28等をデバッグ\n", "できます。\n", "\n", "\n", "\n", "\n", "jlink-OBは求めやすい価格でAmazonやAliExpressから購入することができます。\n", "\n", "## VScode(PlatformIO)の魅力\n", "VScodeはとても軽く、複数の言語に対して一貫した環境を提供してくれるすばらしいエディタです。\n", "このエディタで使える拡張機能のPlatformIOは、ボードのコンパイラー、アップローダー、デバッガーの開発環境を\n", "platform.iniファイルに記述するだけで整えてくれる優れものです。\n", "\n", "## PlatformIOのインストール\n", "VScodeのCode>Prefrences>Extensionsとメニューを選択すると、EXTENSIONSの一覧リストが画面左に表示されます(画面左のExtensionsアイコンでも可)。\n", "ここで、「platformio」と入力すると、先頭にPlatformIO IDEが表示されますの「install」ボタンを押下するだけ、自動的にインストールされます(途中VScodeの再起動を要求されます)。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Raspberry Pi PicoのBlinkサンプルを動かす\n", "Rasberry Pi PicoのArduino環境が提供され、同時にPlatformIOでも利用できるようになりました。\n", "\n", "ここでは、以下の手順でBlink(Lチカ)を動かしてみます。\n", "+ Arduinoの基本サンプルBlinkのビルド\n", "+ BlinkのバイナリのRasberry Pi Picoへのアップロード\n", "+ デバッグ環境の構築\n", "\n", "### 新規プロジェクトの作成\n", "PlatformIOの新規プロジェクトの作成は、PlatformIO拡張機能を選択してGUIでもできますが、\n", "VScodeのターミナルからコマンドラインで行った方が手短にできます。\n", "\n", "VSCodeでプロジェクトを作成したフォルダーを開きます(File>Open Folder...を選択)。\n", "\n", "次にターミナルウィンドウを開き、Raspberry Pi Picoのボードを検索します。\n", "Raspberry Pi PicoのID(pico)をメモします。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio boards \"Raspberry Pi Pico\"\n", "\n", "Platform: raspberrypi\n", "====================================================================\n", "ID MCU Frequency Flash RAM Name\n", "---- ------ ----------- ------- ----- -----------------\n", "pico RP2040 133MHz 2MB 264KB Raspberry Pi Pico\n", "pico RP2040 133MHz 2MB 264KB Raspberry Pi Pico\n", "\n", "Platform: wizio-pico\n", "====================================================================\n", "ID MCU Frequency Flash RAM Name\n", "----------------- ------ ----------- ------- ----- ---------------------------------------\n", "pico-dap RP2040 125MHz 2MB 256KB WizIO - Raspberry Pi Pico ( CMSIS-DAP )\n", "raspberry-pi-pico RP2040 125MHz 2MB 256KB WizIO - Raspberry Pi Pico ( PICOPROBE )\n", "```\n", "\n", "ボードのID(pico)を使って、pio init --board picoを実行してプロジェクトを作成します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio init --board pico\n", "\n", "The current working directory /Users/take/Documents/PlatformIO/Projects/Test will be used for the project.\n", "\n", "The next files/directories have been created in /Users/take/Documents/PlatformIO/Projects/Test\n", "include - Put project header files here\n", "lib - Put here project specific (private) libraries\n", "src - Put project source files here\n", "platformio.ini - Project Configuration File\n", "\n", "Project has been successfully updated! Useful commands:\n", "`pio run` - process/build project from the current directory\n", "`pio run --target upload` or `pio run -t upload` - upload firmware to a target\n", "`pio run --target clean` - clean project (remove compiled files)\n", "`pio run --help` - additional information\n", "```\n", "\n", "platformio.iniをみると、以下の設定となっています。\n", "\n", "```\n", "[env:pico]\n", "platform = raspberrypi\n", "board = pico\n", "framework = arduino\n", "```\n", "\n", "### ソースファイルの作成\n", "srcフォルダーの下にmain.cppを作成し、以下の以下のプログラム(ArduinoのBlinkサンプルから引用)をペーストします。\n", "\n", "``` C++\n", "#include \n", "\n", "#define LED_PIN LED_BUILTIN\n", "// the setup function runs once when you press reset or power the board\n", "void setup() {\n", " // initialize digital pin LED_BUILTIN as an output.\n", " pinMode(LED_BUILTIN, OUTPUT);\n", "}\n", "\n", "// the loop function runs over and over again forever\n", "void loop() {\n", " digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)\n", " delay(1000); // wait for a second\n", " digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW\n", " delay(1000); // wait for a second\n", "}\n", "```\n", "\n", "### Blinkのビルド\n", "PlatformIOのアイコンをクリックし、PROJECT TASKSからGeneral>Buildを選択するとビルドを実行しますが、\n", "ここでは、コマンドラインからpio runを実行します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio run \n", "Processing pico (platform: raspberrypi; board: pico; framework: arduino)\n", "--------------------------------------------------------------------\n", "Verbose mode can be enabled via `-v, --verbose` option\n", "CONFIGURATION: https://docs.platformio.org/page/boards/raspberrypi/pico.html\n", "PLATFORM: Raspberry Pi RP2040 (1.4.0) > Raspberry Pi Pico\n", "HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash\n", "DEBUG: Current (cmsis-dap) External (cmsis-dap, jlink, raspberrypi-swd)\n", "PACKAGES: \n", " - framework-arduino-mbed 2.5.2 \n", " - tool-rp2040tools 1.0.2 \n", " - toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)\n", "LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf\n", "LDF Modes: Finder ~ chain, Compatibility ~ soft\n", "Found 30 compatible libraries\n", "Scanning dependencies...\n", "No dependencies\n", "Building in release mode\n", "Compiling .pio/build/pico/src/main.cpp.o\n", "Generating LD script .pio/build/pico/cpp.linker_script.ld\n", "Compiling .pio/build/pico/FrameworkArduinoVariant/double_tap_usb_boot.cpp.o\n", "途中省略\n", "Archiving .pio/build/pico/libFrameworkArduino.a\n", "Indexing .pio/build/pico/libFrameworkArduino.a\n", "Linking .pio/build/pico/firmware.elf\n", "Generating UF2 image\n", "elf2uf2 \".pio/build/pico/firmware.elf\" \".pio/build/pico/firmware.uf2\"\n", "Checking size .pio/build/pico/firmware.elf\n", "Advanced Memory Usage is available via \"PlatformIO Home > Project Inspect\"\n", "RAM: [== ] 15.1% (used 40688 bytes from 270336 bytes)\n", "Flash: [ ] 0.2% (used 4034 bytes from 2097152 bytes)\n", "Building .pio/build/pico/firmware.bin\n", "=================== [SUCCESS] Took 26.56 seconds ===================\n", "```\n", "\n", "### バイナリのアップロード\n", "ビルドで作成されたバイナリファイルをRaspberry Pi Picoにアップロードします。\n", "最初にRaspberry Pi Picoの「BOOTSEL」とかかれた白いボタンを押しながら、USBケーブルをPCに接続します。\n", "RPI-RP2というボリュームがマウントされます。Macの場合/Volumes/RPI-RP2にマウントされます。\n", "\n", "そこで、platformio.iniに以下の行を追加します。\n", "\n", "```\n", "upload_port = /Volumes/RPI-RP2\n", "```\n", "\n", "PROJECT TASKSからGeneral>Uploadを選択するとバイナリのアップロードを実行しますが、\n", "ここでは、コマンドラインからpio run -t uploadを実行します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio run -t upload \n", "Processing pico (platform: raspberrypi; board: pico; framework: arduino)\n", "--------------------------------------------------------------------\n", "Verbose mode can be enabled via `-v, --verbose` option\n", "CONFIGURATION: https://docs.platformio.org/page/boards/raspberrypi/pico.html\n", "PLATFORM: Raspberry Pi RP2040 (1.4.0) > Raspberry Pi Pico\n", "HARDWARE: RP2040 133MHz, 264KB RAM, 2MB Flash\n", "DEBUG: Current (cmsis-dap) External (cmsis-dap, jlink, raspberrypi-swd)\n", "PACKAGES: \n", " - framework-arduino-mbed 2.5.2 \n", " - tool-openocd-raspberrypi 2.1100.0 (11.0) \n", " - tool-rp2040tools 1.0.2 \n", " - toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)\n", "LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf\n", "LDF Modes: Finder ~ chain, Compatibility ~ soft\n", "Found 30 compatible libraries\n", "Scanning dependencies...\n", "No dependencies\n", "Building in release mode\n", "Checking size .pio/build/pico/firmware.elf\n", "Advanced Memory Usage is available via \"PlatformIO Home > Project Inspect\"\n", "RAM: [== ] 15.1% (used 40688 bytes from 270336 bytes)\n", "Flash: [ ] 0.2% (used 4034 bytes from 2097152 bytes)\n", "Configuring upload protocol...\n", "AVAILABLE: cmsis-dap, jlink, picotool, raspberrypi-swd\n", "CURRENT: upload_protocol = picotool\n", "Looking for upload port...\n", "Use manually specified: /Volumes/RPI-RP2\n", "Forcing reset using 1200bps open/close on port /Volumes/RPI-RP2\n", "Uploading .pio/build/pico/firmware.elf\n", "rp2040load 1.0.1 - compiled with go1.15.8\n", ".Loading into Flash: [ ] 0%\n", "Loading into Flash: [= ] 5%\n", "Loading into Flash: [=== ] 11%\n", "Loading into Flash: [==== ] 16%\n", "Loading into Flash: [====== ] 22%\n", "Loading into Flash: [======== ] 28%\n", "Loading into Flash: [========= ] 33%\n", "Loading into Flash: [=========== ] 39%\n", "Loading into Flash: [============= ] 45%\n", "Loading into Flash: [=============== ] 50%\n", "Loading into Flash: [================ ] 56%\n", "Loading into Flash: [================== ] 61%\n", "Loading into Flash: [==================== ] 67%\n", "Loading into Flash: [===================== ] 73%\n", "Loading into Flash: [======================= ] 78%\n", "Loading into Flash: [========================= ] 84%\n", "Loading into Flash: [=========================== ] 90%\n", "Loading into Flash: [============================ ] 95%\n", "Loading into Flash: [==============================] 100%\n", "\n", "=================== [SUCCESS] Took 4.51 seconds ===================\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## OpenOCDを使ったデバッグ\n", "OpenOCDは、様々なJTAGデバッガーとGDBを使ってデバッグできるようにしたツールです。\n", "オープンソースで公開されているため、多くの場面で使われています。\n", "\n", "PlatformIOもデバッグにOpenOCDを使用していますが、その設定がユーザからは見えません。\n", "そのため、PlatformIOの環境でサポートされていないJTAGデバッガーを使えないと思っていました。\n", "しかし、カスタム設定を使ってOpenOCDの起動方法を指定することができることが分かりました。\n", "\n", "## Jlink-OBを使う\n", "Raspberry Pi Pico用のopenocdは、特別なopenocdを使いますが、PlatformIOがtool-openocd-raspberrypiにインストールしています。\n", "\n", "本題のjlink-OBを使ってデバッグできるようにplatformio.iniに以下の行を追加します。\n", "\n", "```\n", "debug_tool = custom\n", "debug_server =\n", " $PLATFORMIO_CORE_DIR/packages/tool-openocd-raspberrypi/bin/openocd\n", " -f openocd.cfg\n", "```\n", "\n", "次にopenocd.cfgファイルを作成し、以下の内容とします。\n", "\n", "```\n", "# インタフェース設定\n", "source [find interface/jlink.cfg]\n", "adapter driver jlink\n", "transport select swd\n", "\n", "# CPUの設定\n", "source [find target/rp2040.cfg]\n", "\n", "# デバッガの初期化\n", "adapter speed 1000\n", "gdb_target_description enable\n", "init\n", "reset init\n", "```\n", "\n", "使用するインタフェース(JTAG)は、jlink-obなので、インタフェース設定は他のCPUを使う場合も変わりません。\n", "\n", "使用するCPUに合わせて「ターゲットCPUの設定」をします。findコマンドでtarget/rp2040.cfgの場所を探し、そのファイルをsourceコマンドで読み込みます。\n", "\n", "```\n", "source [find target/rp2040.cfg]\n", "```\n", "\n", "デバッガの初期化もほとんど変わりません。\n", "\n", "### jlink-obとRaspberry Pi Picoとの結線\n", "SWD方式のjlink-obが使う信号は、GND, SWDIO, SWCLKの3線です。jlink-obはこれに加えて3.3Vも供給しているので、\n", "jlink-obのUSBケーブル1本でデバッグすることができます。\n", "\n", " jlink-obとRaspberry Pi Picoとの結線は、以下の通りです。\n", "\n", "| jlink-ob | Raspberry Pi Pico |\n", "| --- | --- |\n", "| GND | GND |\n", "| SWDIO | SWDIO |\n", "| SWCLK | SWCLK |\n", "| 3.3V | VSYS |\n", "\n", "\n", "\n", "\n", "\n", "### デバッグの実行\n", "VScodeのメニューからRun>Start Debuggingを選択すると、デバッグ用のバイナリファイルを\n", "作成し、デバッガを起動します。\n", "\n", "後は、デバッガー用アイコンとソースファイルのブレークポイントを使ってデバッグを進めます。\n", "\n", "\n", "\n", "\n", "デバッガーを使った開発のもう一つの利点は、BOOTSELボタンを押しながらUSBプラグを抜き差ししなくて済むことです。\n", "ただし、バイナリがデバッグ情報を含むため、サイズが大きくなる点に注意が必要です。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## XIAOを試してみる\n", "PlatformIOでのプロジェクトの作り方が分かったところで、SeeedのXIAOボードにBlinkを書き込んでみましょう。\n", "\n", "最初にボードのIDを調べます。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio boards XIAO\n", "\n", "Platform: atmelsam\n", "======================================================================\n", "ID MCU Frequency Flash RAM Name\n", "---------- ---------- ----------- ------- ----- --------------\n", "seeed_xiao SAMD21G18A 48MHz 256KB 32KB Seeeduino XIAO\n", "```\n", "\n", "Raspberry Pi Picoと以下のコマンドを実行して、プロジェクトを作成します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio init --board seeed_xiao\n", "```\n", "\n", "デバッグ用にplatformio.iniに以下を追加します。今回はデフォルトのtool-openocdを使用しています。\n", "\n", "```\n", "debug_tool = custom\n", "debug_server =\n", " $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd\n", " -f openocd.cfg\n", "```\n", "\n", "src/main.cppもRaspberry Pi Picoのプロジェクトからコピーします。\n", "\n", "OpenOCDの設定ファイルopenocd.cfgは、以下のようになります。\n", "\n", "```\n", "# インタフェース設定\n", "source [find interface/jlink.cfg]\n", "adapter driver jlink\n", "transport select swd\n", "\n", "# CPU設定\n", "source [find target/at91samdXX.cfg]\n", "\n", "# デバッガの初期化\n", "adapter speed 1000\n", "gdb_target_description enable\n", "init\n", "reset init\n", "```\n", "\n", "CPUの設定ファイルを見つける方法は簡単です。\n", "Googleでplatformio XIAOで検索して、PlatfformIOのページにアクセスします。\n", "\n", "Hardwareの項目のMicorcontrollerからCPUがATMEL SAMDシリーズのSAMD21G18Aであることが分かりました。\n", "つぎにsamdをキーワードに以下のコマンドで*.cfgファイルを検索します。\n", "\n", "``` bash\n", "$ ls ~/.platformio/packages/tool-openocd/scripts/target/*samd*\n", "/Users/take/.platformio/packages/tool-openocd/scripts/target/at91samdXX.cfg\n", "```\n", "これからtarget/at91samdXX.cfgだと分かります。\n", "\n", "### XIAOとjlink-obとの結線\n", " jlink-obとRaspberry Pi Picoとの結線は、以下の通りです。8ピンソケットの上段を使います。\n", "XIAOのデバッグ用ピンは、基板の裏側にパットとして付いているので、デバッグをする場合には、\n", "XIAO拡張ボードを使用すると便利です。\n", "\n", "| jlink-ob | XIAO拡張ボード |\n", "| --- | --- |\n", "| GND | GND |\n", "| SWDIO | SWDIO |\n", "| SWCLK | SWCLK |\n", "| 3.3V | 3V3 |\n", "\n", "### デバッグの実行\n", "Raspberry Pi Pico同様、VScodeのメニューからRun>Start Debuggingを選択するとプログラムが\n", "XIAOに書き込まれ、デバッガーが起動します。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 懐かしのLPC1114FN28で試してみる\n", "少し古くてCPU単体では入手できないLPC1114FN28は、クリスタル不要でIO数も多く、\n", "デバッグもできるとても便利なCPUでした。\n", "\n", "ブレッドボードにそのまま挿して使うことがきるボード(mbed LPC1114FN28)が\n", "スイッチサイエンスから販売されています(2021/12/26時点、在庫あり)。\n", "このボードはLPC1114FN28を挿すだけで、mbedのように動く魔法のボードで、mbedの\n", "ブラウザー・コンパイラーでコンパイルし、ダウンロードしてコピーするだけで\n", "プログラムが動く仕組みは画期的でした。しかもmbedのコンパイラーは高性能で、\n", "生成されたバイナリがとてもコンパクトになるのも特徴でした。\n", "\n", "### 古いmbed環境の構築\n", "最初にLPC1114FN28のIDを調べます。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio boards LPC1114FN28\n", "\n", "Platform: nxplpc\n", "================================================================================\n", "ID MCU Frequency Flash RAM Name\n", "----------- ----------- ----------- ------- ----- -------------------------------\n", "lpc1114fn28 LPC1114FN28 48MHz 32KB 4KB Switch Science mbed LPC1114FN28\n", "```\n", "\n", "次にIDを元にプロジェクトを作成します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio init --board lpc1114fn28\n", "```\n", "\n", "生成されたplatformio.iniは、以下のようになります。\n", "\n", "```\n", "[env:lpc1114fn28]\n", "platform = nxplpc\n", "board = lpc1114fn28\n", "framework = mbed\n", "```\n", "\n", "frameworkにはmbedを使用しているので、mbed版Lチカをmain.cppにコピーします。\n", "\n", "``` C++\n", "#include \"mbed.h\"\n", "\n", "DigitalOut myled(LED2);\n", "\n", "int main() {\n", " while(1) {\n", " myled = 1;\n", " wait(0.2);\n", " myled = 0;\n", " wait(0.2);\n", " }\n", "}\n", "```\n", "\n", "mbedのページを参考にLED2使ってブレッドボードに回路を組み立てます。\n", "\n", "https://os.mbed.com/platforms/LPC1114FN28/\n", "\n", "\n", "\n", "\n", "### いざコンパイル\n", "準備ができたので、コンパイルするとエラーがでて失敗します。\n", "\n", "```\n", "Processing lpc1114fn28 (platform: nxplpc; board: lpc1114fn28; framework: mbed)\n", "-----------------------------------------------------------------------------------------------\n", "Verbose mode can be enabled via `-v, --verbose` option\n", "CONFIGURATION: https://docs.platformio.org/page/boards/nxplpc/lpc1114fn28.html\n", "PLATFORM: NXP LPC (9.0.0) > Switch Science mbed LPC1114FN28\n", "HARDWARE: LPC1114FN28 48MHz, 4KB RAM, 32KB Flash\n", "DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (blackmagic, jlink)\n", "PACKAGES: \n", " - framework-mbed 6.60900.210318 (6.9.0) \n", " - toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)\n", "Collecting mbed sources...\n", "Failed to extract configuration for LPC1114FN28.\n", "It might not be supported in the this Mbed release.\n", "================================= [FAILED] Took 2.21 seconds =================================\n", "```\n", "\n", "調べてみるとLPC1115FN28で使用できるmbedのバージョンは古いバージョンのため、\n", "最新のmbed OS(6.9)ではサポートされていないことが分かりました。\n", "\n", "そこで、古いmbed(5.5)を使用するために、platformio.iniを以下のように修正します。\n", "\n", "```\n", "[env:lpc1114fn28]\n", "platform = nxplpc@3.5.0\n", "board = lpc1114fn28\n", "framework = mbed\n", "```\n", "\n", "今度は、うまくコンパイルできました。\n", "\n", "``` bash\n", "Processing lpc1114fn28 (platform: nxplpc@3.5.0; board: lpc1114fn28; framework: mbed)\n", "---------------------------------------------------------------------------------\n", "Verbose mode can be enabled via `-v, --verbose` option\n", "CONFIGURATION: https://docs.platformio.org/page/boards/nxplpc/lpc1114fn28.html\n", "PLATFORM: NXP LPC (3.5.0) > Switch Science mbed LPC1114FN28\n", "HARDWARE: LPC1114FN28 48MHz, 4KB RAM, 32KB Flash\n", "DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (blackmagic, jlink)\n", "PACKAGES: \n", " - framework-mbed 5.51001.181029 (5.10.1) \n", " - toolchain-gccarmnoneeabi 1.90301.200702 (9.3.1)\n", "LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf\n", "LDF Modes: Finder ~ chain, Compatibility ~ soft\n", "Found 39 compatible libraries\n", "Scanning dependencies...\n", "No dependencies\n", "Building in release mode\n", "Compiling .pio/build/lpc1114fn28/FrameworkMbedCore/cmsis/TARGET_CORTEX_M/mbed_tz_context.o\n", "途中省略\n", "Linking .pio/build/lpc1114fn28/firmware.elf\n", "Checking size .pio/build/lpc1114fn28/firmware.elf\n", "Building .pio/build/lpc1114fn28/firmware.bin\n", "Advanced Memory Usage is available via \"PlatformIO Home > Project Inspect\"\n", "RAM: [== ] 16.3% (used 669 bytes from 4096 bytes)\n", "Flash: [=== ] 26.5% (used 8696 bytes from 32768 bytes)\n", "========================= [SUCCESS] Took 16.07 seconds =========================\n", "```\n", "\n", "mbed LPC1114FN28は、cmsis-dapのJTAGデバッガを内臓しているため、そのままデバッグできます(少し処理速度は遅い)。\n", "\n", "### jlink_obで素のLPC1114FN28を動かす\n", "LPC1114FN28をそのままブレッドボードに挿して、jlink_obでデバッグしてみましょう。\n", "\n", "openocd.cfgは、CPU設定は、lpc11xx.cfgを使用するようにします。\n", "\n", "```\n", "# インタフェース設定\n", "source [find interface/jlink.cfg]\n", "adapter driver jlink\n", "transport select swd\n", "\n", "# CPU設定\n", "source [find target/lpc11xx.cfg]\n", "\n", "# デバッガの初期化\n", "adapter speed 1000\n", "gdb_target_description enable\n", "init\n", "reset init\n", "```\n", "\n", "platformio.iniには、XIAO同様デバッグカスタム設定を追加します。\n", "\n", "```\n", "[env:lpc1114fn28]\n", "platform = nxplpc@3.5.0\n", "board = lpc1114fn28\n", "framework = mbed\n", "\n", "debug_tool = custom\n", "debug_server =\n", " $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd\n", " -f openocd.cfg\n", "```\n", "\n", "LPC1114FN28とjlink_obの結線は、以下の通りです。\n", "\n", "| LPC1114FN28 | jlink_ob |\n", "| --- | --- |\n", "| VIN(dp20の位置) | 3.3V |\n", "| SWDIO(dp12の位置) | SWDIO |\n", "| SWCLK(dp3の位置) | SWCLK |\n", "| GND(dp21の位置) | GND |\n", "\n", "たったこれだけで、素のLPC1114FN28が動きます。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 今入手できるLPC812を試してみる\n", "CPU不足の今でも、秋月から入手可能(2021/12/28現在、130円)なLPC812を使ってみましょう。\n", "\n", "LPC812を使ったmbed製品には、LPC812 MAXがあります。\n", "このボードには、トラ技ARMライタで使われているLPC11U35が載っており、そのままmbedのバイナリ\n", "を書き込んだり、デバッグができるようになっています。\n", "手元に素のLPC812がないので、LPC812 MAXを使ってjlink_obが動作するか試しみます。\n", "\n", "pio boardsコマンドでLPC812-MAXのIDを調べると、lpc812であることが分かりました。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio boards LPC812\n", "\n", "Platform: nxplpc\n", "================================================================================\n", "ID MCU Frequency Flash RAM Name\n", "---------------- ------ ----------- ------- ----- --------------\n", "elektor_cocorico LPC812 30MHz 16KB 4KB CoCo-ri-Co!\n", "lpc812 LPC812 30MHz 16KB 4KB NXP LPC800-MAX\n", "```\n", "\n", "プロジェクトを作成します。\n", "\n", "``` bash\n", "$ ~/.platformio/penv/bin/pio init --board lpc812\n", "```\n", "\n", "LチカのLEDは、LED1を使用するので、main.cppは以下のようになります。\n", "\n", "``` C++\n", "#include \"mbed.h\"\n", "\n", "DigitalOut myled(LED1);\n", "\n", "int main() {\n", " while(1) {\n", " myled = 1;\n", " wait(0.2);\n", " myled = 0;\n", " wait(0.2);\n", " }\n", "}\n", "```\n", "\n", "LPC812もそのままではコンパイルでエラーになりました。\n", "\n", "``` bash\n", "Processing lpc812 (platform: nxplpc; board: lpc812; framework: mbed)\n", "--------------------------------------------------------------------------------\n", "Tool Manager: Installing platformio/framework-mbed @ ~6.51506.0\n", "Unpacking [####################################] 100% \n", "Tool Manager: framework-mbed @ 6.51506.201227 has been installed!\n", "Verbose mode can be enabled via `-v, --verbose` option\n", "CONFIGURATION: https://docs.platformio.org/page/boards/nxplpc/lpc812.html\n", "PLATFORM: NXP LPC (9.0.0) > NXP LPC800-MAX\n", "HARDWARE: LPC812 30MHz, 4KB RAM, 16KB Flash\n", "DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (blackmagic, jlink)\n", "PACKAGES: \n", " - framework-mbed 6.51506.201227 (5.15.6) \n", " - toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)\n", "途中省略\n", "Linking .pio/build/lpc812/firmware.elf\n", "/Users/take/.platformio/packages/toolchain-gccarmnoneeabi@1.90201.191206/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld:/Users/take/Documents/PlatformIO/Projects/TestLPC812/.pio/build/lpc812/LPC812.ld.link_script.ld:76 cannot move location counter backwards (from 0000000010000448 to 0000000010000000)\n", "collect2: error: ld returned 1 exit status\n", "*** [.pio/build/lpc812/firmware.elf] Error 1\n", "========================= [FAILED] Took 240.11 seconds =========================\n", "```\n", "\n", "そこで、LPC1114FN28同様の古いmbedを使用するようにplatformio.iniを修正し、ビルドできるようになりました。\n", "\n", "```\n", "[env:lpc812]\n", "platform = nxplpc@3.5.0\n", "board = lpc812\n", "framework = mbed\n", "```\n", "\n", "### LPC812 MAXをjlink-obでデバッグ\n", "LPC812 MAXを外部のJTAGデバッガーでデバッグする場合、P3のピッチの狭いソケットを\n", "使用します。また、LPC812 MAX内のLPC11U35が動かないようにするために、\n", "P1のジャンパーを接続します。\n", "\n", "ピン変換には、以下のような変換コネクターを使用します。\n", "\n", "\n", "\n", "\n", "変換コネクターとjlink-OBの結線は、以下の通りです。\n", "\n", "| 変換コネクター | Jlink-OB |\n", "| --- | --- |\n", "| 1 VTref | VCC |\n", "| 7 SWDIO | SWDIO |\n", "| 9 SWCLK | SWCLK |\n", "| 4 GND | GND |\n", "\n", "LPC812用のopenocd.cfgは、以下のようになります。\n", "\n", "```\n", "# インタフェース設定\n", "source [find interface/jlink.cfg]\n", "transport select swd\n", "\n", "# CPU設定\n", "source [find target/lpc8xx.cfg]\n", "\n", "# デバッガの初期化\n", "adapter speed 1000\n", "gdb_target_description enable\n", "init\n", "reset init\n", "```\n", "\n", "最後にplatformio.iniのdebug_tool, debug_server項目を追加します。\n", "\n", "```\n", "[env:lpc812]\n", "platform = nxplpc@3.5.0\n", "board = lpc812\n", "framework = mbed\n", "debug_tool = custom\n", "debug_server =\n", " $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd\n", " -f openocd.cfg\n", "```\n", "\n", "無事、デバッガーで動きました。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## LPC810でjlink-OBを試す\n", "こちらも入手できなくなったLPC810で試してみます。\n", "(現在ではLPC812の変換基板も販売されているので、こちらを使う場合は、LPC812 MAX と同じ設定が使えます。)\n", "\n", "プロジェクトは、LPC812 MAXを修正することで使えるようになります。\n", "\n", "- board_build.mcuにlpc810をセット\n", "- debug_build_flagsでサイズのオプティマイズとリンカスクリプトを指定\n", "\n", "残念ながら、mbedの高品質のコンパイラーに比べ、GCCの生成するバイナリは大きく、サイズオプティマイズをしないとうまくフラッシュに収まりません。\n", "\n", "platformio.ini\n", "\n", "```\n", "[env:lpc810]\n", "platform = nxplpc@3.5.0\n", "board = lpc812\n", "framework = mbed\n", "\n", "board_build.mcu = lpc810\n", "debug_build_flags = -Os -g -Wl,-T$PROJECT_DIR/LPC810.ld\n", "debug_tool = custom\n", "debug_server =\n", " $PLATFORMIO_CORE_DIR/packages/tool-openocd/bin/openocd\n", " -f openocd.cfg\n", "```\n", "\n", "LPC812と810のメモリマップの違いは、フラッシュが16KBから4KB、RAMが4KBから1KBと小さくなった箇所です。\n", "リンカースクリプトの変更は、MEMOERYセクションのみとなります。\n", "\n", "```\n", "{\n", " FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x1000\n", " RAM (rwx) : ORIGIN = 0x10000000+0xC0, LENGTH = 0x0400-0xC0\n", "}\n", "```\n", "\n", "LPC810.ldスクリプトは、mbedのパッケージに含まれているので、それをコピーします。\n", "\n", "``` bash\n", "$ cp ~/.platformio/packages/framework-mbed@5.51001.181029/targets/TARGET_NXP/TARGET_LPC81X/TARGET_LPC810/device/TOOLCHAIN_GCC_ARM/LPC810.ld .\n", "```\n", "\n", "ピン配置がLPC812と異なるため、\n", "https://os.mbed.com/users/va009039/code/lpc810_helloworld/\n", "のmain.cppを使わせていただきました。\n", "\n", "ここに引用させていただきます。\n", "\n", "```\n", "#include \"mbed.h\"\n", "// LPC810 pinout\n", "#define dp1 P0_5 // nRESET\n", "#define dp2 P0_4 // WAKEUP\n", "#define dp3 // SWCLK\n", "#define dp4 // SWDIO\n", "#define dp5 P0_1 // nISP\n", "#define dp6 // VIN\n", "#define dp7 // GND\n", "#define dp8 P0_0\n", "\n", "DigitalOut myled(dp8);\n", "\n", "int main() {\n", " while(1) {\n", " myled = 1;\n", " wait_ms(200);\n", " myled = 0;\n", " wait_ms(200);\n", " }\n", "}\n", "```\n", "\n", "LPC810とjlink-OBの結線は、以下の通りです。\n", "\n", "| LPC810 | Jlink-OB |\n", "| --- | --- |\n", "| 6 VIN | VCC |\n", "| 4 SWDIO | SWDIO |\n", "| 3 SWCLK | SWCLK |\n", "| 5 GND | GND |\n", "\n", "最後に、デバッグしているLPC810の写真をお見せます。\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "language_info": { "name": "python" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }