{ "metadata": { "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.8" }, "orig_nbformat": 2, "kernelspec": { "name": "python388jvsc74a57bd076f9b3eb98fee63ee766a339af29bcb269f70e31ae50c94992d90bfff92a1151", "display_name": "Python 3.8.8 64-bit ('toragi_env': conda)" } }, "nbformat": 4, "nbformat_minor": 2, "cells": [ { "source": [ "## RaspberryPi Picoをはじめよう\n", "Raspberry財団から販売されたRaspberry Pi Pico(以下Picoと省略)が正式にArduino IDEをサポートしました。\n", "それと同時にPlatformIOもPicoをサポートしました。\n", "\n", "ここでは、VScodeにPicoの開発環境を構築し、Arduinoフレームワークを使ったアプリの作成とJTAG書き込みツール(jlink-OB)を使ったデバック方法を紹介します。\n", "\n", "" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "## PlatformIOのインストール\n", "VScodeをまだ使用していない場合は、以下のサイトからダウンロードしてください。\n", "- https://code.visualstudio.com/download\n", "\n", "\n", "VScodeを起動すると、画面の左側にさまざまなアイコンが並んでいます。PlatformIOは、VScodeのプラグインとして提供されています。プラグインをインストールするには、Extentionsボタンをクリックしてください。\n", "\n", "\n", "\n", "Extenstionの画面では、検索フィールドが表示されるので、「platformio」と入力してください。リストから「PlatformIO IDE」を選択すると、PlatformIO IDEの説明画面が表示されるので、「Install」ボタンをクリックするとインストールが実行されます。\n", "\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "## 新規プロジェクトの作成\n", "PlatformIOがインストールされると左のアイコンリストにアリさん?のようなPlatformIOアイコンが追加されます。\n", "\n", "新規のプロジェクトを作成するには、このアイコンをクリックし、「PIO HOME」リストから「Open」を選択すると、以下の画面が表示されます。ここで、「New Project」ボタンをクリックしてください。\n", "\n", "\n", "\n", "Project Wizard画面に切り替わりますので、プロジェクトの名前をName:フィールドに「L-Chika」と入力し、Boardフィールドには「pico」と入力すると候補が表示されますので「Rasperry Pi Pico」を選択します。Frameworkフィールドには「Arduino」が表示されます。入力が完了したら「Finish」ボタンをクリックしてください。プロジェクトの作成には時間がかかりますので、お茶でも飲みながら待ってください。\n", "\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "### 設定の変更\n", "プロジェクトが作られると以下のようなplatformio.iniファイルが表示されるます。\n", "このファイルでプロジェクトの設定を行います。\n", "\n", "今回は以下の行を追加してください。\n", "\n", "```\n", "upload_port = /Volumes/RPI-RP2/\n", "\n", "monitor_speed = 115200\n", "build_flags = -g\n", "```\n", "\n", "各設定の意味は以下の通りです。\n", "- upload_port: スケッチをアップロードする場所を指定します。MacOSの場合は「/Volumes/RPI-RP2/」とし、Windowsの場合には「COMn」とシリアルポート番号を指定します。\n", "- monitor_speed: Picoとシリアルモニターで通信するときの通信速度を指定します。\n", "- build_flags: C++のビルドコマンドへのオプションを指定します。後でOpenOCDを使ったデバッグを使用するので、「-g」を指定します。\n", "\n", "\n", "\n", "### Lチカスケッチの作成\n", "続いてLチカのスケッチを描きましょう。EXPLORERリストの「src」の中の「main.cpp」をクリックするとArduinoのデフォルトスケッチが表示されますので、以下のLチカスケッチをコピー&ペーストしてください。\n", "\n", "```C++\n", "#include \n", "\n", "// 起動時に最初に1回だけ実行される関数です\n", "void setup() {\n", " // ArduinoのデフォルトのLEDピンをデジタル出力に設定します\n", " pinMode(LED_BUILTIN, OUTPUT);\n", "}\n", "\n", "// setup後繰り返し実行されます\n", "void loop() {\n", " digitalWrite(LED_BUILTIN, HIGH); // LEDをオン(HIGHは、電圧レベルを指定)\n", " delay(1000); // 1秒待ちます\n", " digitalWrite(LED_BUILTIN, LOW); // LEDをオフ\n", " delay(1000); // 1秒待ちます\n", "}\n", "```\n", "\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "### スケッチのPicoへのアップロード\n", "MacOSの場合、スケッチをアップロードするにはPicoのBOOTSELボタンを押しながらUSBのケーブルを挿入します。USBメモリを差した時と同様にPicoのドライブが現れます。\n", "\n", "\n", "\n", "PlatformIOでスケッチをアップロードするには、PlatformIOアイコンをクリックし、QUICK ACCESS>PIO HOMEの中のOpenを選択し、PROJECT TASK>pico>Generalの中のUploadを選択してください。\n", "(以前はすぐにUploadの選択だけでよかったのですが、現在のバージョンではPIO Homeがアクティブの状態でないとUploadが実行されません)\n", "\n", "スケッチをコンパイルした後、自動的にアップロードを実行します。\n", "\n", "\n", "\n", "スケッチのアップロードが完了するとPicoのドライブがアンマウントされるので、「ディスクの不正な取り出し」ワーニングがでますが問題ありません。\n", "\n", "\n", "\n", "これでPicoへのLチカスケッチがアップロードが完了し、LEDが1秒間隔で点滅します。" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "## JTAG書き込みツールを使ったスケッチのデバッグ\n", "Picoにスケッチを書き込むには、JTAG-SWDに対応したJTAG書き込みツールが必要です。\n", "\n", "私は自称デバッガーマニア(トランジスタ技術 2012/02 Mac/Linuxでも使える! 簡易デバッガの製作)なので、自作したものを含めいろんなJJTAG書き込みツールを使ってきました。\n", "\n", "ここでは、安価なJLink-OBを使います。\n", "aliexpressでは\n", "1000円以下\n", "Amazonでも、1990円\n", "で入手できます。\n", "\n", "\n", "\n", "RaspberryPI Pico用のopenocdは以下のJTAG書き込みツールに対応していますが、実際に動作が報告されているものを使うのがよいでしょう。ST-Link V2では、Picoのrp2040.cfgのjwj_newdapでエラーになりました。\n", "\n", "```\n", "The following debug adapters are available:\n", "1: ftdi\n", "2: usb_blaster\n", "3: jtag_vpi\n", "4: ft232r\n", "5: presto\n", "6: usbprog\n", "7: openjtag\n", "8: jlink\n", "9: vsllink\n", "10: rlink\n", "11: ulink\n", "12: arm-jtag-ew\n", "13: remote_bitbang\n", "14: hla\n", "15: osbdm\n", "16: opendous\n", "17: aice\n", "18: cmsis-dap\n", "19: kitprog\n", "20: xds110\n", "21: st-link\n", "```\n", "\n", "### J-Link OBとの結線\n", "PicoとJ-Link OBとの以下のように接続します。\n", "\n", "| pico | J-Link OB |\n", "| :-- | :-: |\n", "| 1 ▼ |  SWCLK |\n", "| 2 | GND |\n", "| 3 | SWDIO |\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "### OpenOCDコンフィグファイル\n", "Pico用のOpenOCDコンフィグファイル(openocd.cfg)をplatformio.iniと同じディレクトリに作成します。\n", "\n", "RP2040の設定については、OpneOCDの大御所ねむいさんの記事を参考にさせていただきました。\n", "\n", "openocd.cfgの内容\n", "```\n", "# インタフェース設定\n", "source [find interface/jlink.cfg]\n", "adapter driver jlink\n", "transport select swd\n", "\n", "# RP2040 CPU設定\n", "source [find target/rp2040.cfg]\n", "$_TARGETNAME_0 configure -work-area-phys $_WORKBASE -work-area-size $_WORKSIZE -rtos auto\n", "\n", "# デバッガの初期化\n", "adapter speed 1000\n", "gdb_target_description enable\n", "init\n", "reset init\n", "```\n", "\n", "### launch設定の変更\n", "PlatformIOのデフォルトデバッガーはPIO debugとなっており、.vscodde配下のlaunch.jsonをOpneOCD用に変更してもVScodeを起動し直すと元に戻ってしまいます。\n", "\n", "そこで、左下のギアのアイコン(Manage)>Settingsを選択し、「Search settings」フィールドに「launch」と入力するとUserタブにLaunchが表示されるので、「Edit in setting.json」をクリックしてください。\n", "\n", "「configurations」の[]の中をコピー&ペーストしてください。以下の設定は、Windows10とMacOSXで動作を確認しています。\n", "\n", "```\n", "{\n", " \"git.ignoreMissingGitWarning\": true,\n", " \"launch\": {\n", " \n", " \"configurations\": [\n", " {\n", " \"name\": \"Pico debug\",\n", " \"type\": \"cppdbg\",\n", " \"request\": \"launch\",\n", " \"program\": \"${workspaceRoot}/.pio/build/pico/firmware.elf\",\n", " \"args\": [],\n", " \"stopAtEntry\": false,\n", " \"cwd\": \"${workspaceRoot}\",\n", " \"environment\": [],\n", " \"externalConsole\": false, \n", " \"debugServerArgs\": \"-f ${workspaceRoot}/openocd.cfg\",\n", " \"serverLaunchTimeout\": 20000,\n", " \"filterStderr\": true,\n", " \"filterStdout\": true,\n", " // \"serverStarted\"には、ターゲットの起動が完了した時の出力キーワードを指定する\n", " \"serverStarted\": \"target halted due to debug-request, current mode: Thread\",\n", " \"MIMode\": \"gdb\", \n", " \"setupCommands\": [\n", " { \"text\": \"-target-select remote localhost:3333\", \"description\": \"connect to target\", \"ignoreFailures\": true },\n", " { \"text\": \"-target-download ${workspaceRoot}/.pio/build/pico/firmware.elf\", \"description\": \"load image\", \"ignoreFailures\": true },\n", " ],\n", " \"logging\": {\n", " \"moduleLoad\": true,\n", " \"trace\": true,\n", " \"engineLogging\": true,\n", " \"programOutput\": true,\n", " \"exceptions\": true\n", " },\n", " \"osx\": {\n", " \"MIMode\": \"gdb\",\n", " \"MIDebuggerPath\": \"${env:HOME}/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-gdb\",\n", " \"debugServerPath\": \"${env:HOME}/.platformio/packages/tool-openocd-raspberrypi/bin/openocd\",\n", " },\n", " \"windows\": {\n", " \"MIMode\": \"gdb\",\n", " \"miDebuggerPath\": \"\\\\Users\\\\${env:USERNAME}\\\\.platformio\\\\packages\\\\toolchain-gccarmnoneeabi\\\\bin\\\\arm-none-eabi-gdb.exe\",\n", " \"debugServerPath\": \"\\\\Users\\\\${env:USERNAME}\\\\.platformio\\\\packages\\\\tool-openocd-raspberrypi\\\\bin\\\\openocd.exe\",\n", " }\n", "\n", " }\n", " ],\n", " \"compounds\": []\n", " }\n", "}\n", "```" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "### デバッグの開始\n", "準備が整ったで、Lチカ・スケッチをデバッガーで動かしてみましょう。\n", "(MacOSXの人は、これで毎回BOOTSELボタンを押してスケッチを書き込むなくてもよくなります。)\n", "\n", "最初にSetup関数の行番号の左をクリックすると赤丸が付きます。これでsetup関数にブレークポイントがセットされます。\n", "\n", "左のアイコンリストから「虫と▷」のアイコンを選択し、デバッグプルダウンから「Pico debug」を選択し、「▷」をクリックします。デバッガーが裏でしばらく動いてsetup関数の最初のステップで停止します。\n", "\n", "\n", "\n", "ここで、デバッガーのコマンドパネルで「Continue」や「Step Over」を実行すると、「Exception has occurred」のエラーがでることがあります。\n", "\n", "\n", "\n", "この例外は、ブレークポイントでPicoの2つのCPUのスレッドが両方停止状態になっていないために、発生しているものと思われます。これからの脱出方法として、「Terminal」メニューで「New Terminal」を選択し、ターミナルウィンドウを開き、telnetコマンドを起動し、OpenOCDに接続します。\n", "\n", "最初のOpenOCDコマンドhaltは、現在動作しているターゲット(Pico)を停止し、次の「resume」で制御をデバッガに戻しています。\n", "\n", "```bash\n", "$ telnet localhost 4444\n", "Trying 127.0.0.1...\n", "Connected to localhost.\n", "Escape character is '^]'.\n", "Open On-Chip Debugger\n", "> halt\n", "> resume\n", ">\n", "```\n", "\n", "画面上は何も変わりませんが、これで「Continue」や「Step Over」正常に使えるようになります。" ], "cell_type": "markdown", "metadata": {} }, { "source": [ "## Windows10固有の設定\n", "\n", "### libusbのドライバーの設定\n", "OpenOCDとuploadに使われているコマンドは、libusbのライブラリを使用することを前提に作られているので、Windows10で使用するにはドライバーをセットする必要があります。\n", "\n", "通常は、ドライバーのインストーラーが用意されていますが、libusbの場合にはZadigというツールを使用します。\n", "\n", "Zadig 2.5は、以下のサイトからダウンロードします。\n", "- https://zadig.akeo.ie/\n", "\n", "BOOTSELボタンを押したままPicoにUSBコネクターを差します。\n", "Zadigを起動し、「Options」メニューから「List All Devices」を選択します。\n", "\n", "\n", "\n", "デバイスプルダウンから「RP2 Boot(Interface 1)」を選択し、「libusb-win32(v1.2.6.0)」を選択し、「Install Driver」をクリックします。\n", "インストールはしばらく時間がかかります。\n", "\n", "この設定をしておけば、platform.iniでupload_portの指定は不要になります。\n", ";でコメントアウトしてください。\n", "\n", "platform.ini\n", "```\n", "; upload_port = COM7\n", "```\n", "\n", "\n", "同様にJ-LinkをUSBに差してドライバーを「libusb-win32(v1.2.6.0)」に入れ替えます。\n", "\n", "### telnetの有効化\n", "Windows10は、そのままではtelnetコマンドが使えません。Windowsの機能画面を開き、「Windowsの機能の有効化または無効化」を選択し、「Telnetクライアント」にチェックを付け、「OK」ボタンをクリックしてください。\n", "\n", "\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ] }