{
"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": []
}
]
}