« PimoroniボードをPicoで動かす | トップページ | Display_Packをpico_arduinoで動かす »

2021年4月22日 (木)

platformioでpicoを動かす

2021/4/24+
arduino-frameworkの対応を追加した、

2021/4/22
初版

Pico Platformio Pico-SDK/Arduino

Pico Platformio Pico-SDK/Arduino

概要

platformioでpicoを動かす
(ホストはubuntu20.04を想定している)
platformioが既にインストールされている前提で説明する。

platformioのインストールについては以下などを参照のこと:
arduinoフレームワーク用platformio.ini集

プロジェクトの作成

プロジェクトのディレクトリを作成して、その中に以下に述べるファイルを作成する:
(このディレクトリ名は任意だが、ここでは、pico_projとする)

# platformioの環境に入っている前提 mkdir pico_proj cd pico_proj # platformio.iniを作成する gedit platformio.ini

platformio.ini

[env:raspberry-pi-pico] platform = https://github.com/Wiz-IO/wizio-pico.git ;platform = wizio-pico board = raspberry-pi-pico framework = baremetal upload_port = /media/USER/RPI-RP2/ ; directory for mass-storage monitor_port = /dev/ttyACM0 ; directory for usb-over-serial monitor_speed = 115200 board_build.bynary_type = copy_to_ram build_flags = -D PICO_STDIO_USB ; enable stdio over USB build_unflags = -D PICO_STDIO_UART ;lib_deps =

・USERは環境依存なので、自分の環境に合わせて変更すること。
・frameworkとしては、baremetal(Pico-SDK)を設定する。

テスト用プログラムを以下のように作成する:
src/main.c

/* * --------------------------------------- * Copyright (c) Sebastian Günther 2021 | * | * devcon@admantium.com | * | * SPDX-License-Identifier: BSD-3-Clause | * --------------------------------------- */ #include <stdio.h> #include <stdbool.h> #include "pico/stdlib.h" int LED_BUILTIN = 25; int LED_GREEN = 15; void setup() { stdio_init_all(); gpio_init(LED_BUILTIN); gpio_set_dir(LED_BUILTIN, GPIO_OUT); gpio_init(LED_GREEN); gpio_set_dir(LED_GREEN, GPIO_OUT); } void blink() { gpio_put(LED_BUILTIN, 1); gpio_put(LED_GREEN, 1); //sleep_ms(750); sleep_ms(200); gpio_put(LED_BUILTIN, 0); gpio_put(LED_GREEN, 0); //sleep_ms(1050); sleep_ms(200); } int main() { setup(); printf("Starting...\n"); while (true) { printf("Hello World\n"); //printf("."); blink(); } return 0; }

・「Raspberry Pico: The Simple Startup with PlatformIO 」にあるサンプルを一部修正したものになる。

ビルド&書き込み

以下の手順でビルトと書き込みができる:

cd pico_proj # ツールなどのインストール(最初の1回のみ) pio run -t clean # ビルドと書き込み # bootselボタンを押しながらホストにUSB接続して # その後、bootselボタンを離すると、書き込み用ストレージが出現する pio run -t upload # この時点で書き込みが完了する

出力例:

<省略> Archiving .pio/build/raspberry-pi-pico/sdk/libSDK.a Indexing .pio/build/raspberry-pi-pico/sdk/libSDK.a Linking .pio/build/raspberry-pi-pico/APPLICATION.elf Building .pio/build/raspberry-pi-pico/APPLICATION.bin Checking size .pio/build/raspberry-pi-pico/APPLICATION.elf DONE Advanced Memory Usage is available via "PlatformIO Home > Project Inspect" RAM: [ ] 2.2% (used 5848 bytes from 262144 bytes) Flash: [ ] 2.0% (used 41728 bytes from 2097152 bytes) Configuring upload protocol... AVAILABLE: cmsis-dap, dap, picoprobe, uf2 CURRENT: upload_protocol = uf2 Uploading... Converting to UF2 Start address: 0x10000000 FamilyID: 0xe48bff56 Output size: 84480 bytes Wrote 84480 bytes to /media/USER/RPI-RP2/APPLICATION.uf2 DONE ========================= [SUCCESS] Took 3.39 seconds =========================

・書き込み終了後、プログラムが起動する。ボード上のLEDが点滅して、
USBシリアルには「Hello World」の文字列が繰り返し出力される。

他のサンプル(morse_blinky)

morse_blinky
src/main.c

cat src/main.c // morse_blinky // modified on 2021/2/6 /** * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. * * SPDX-License-Identifier: BSD-3-Clause */ #include <stdio.h> #include "pico/stdlib.h" #include "hardware/gpio.h" char str[100]; const uint LED_PIN = 25; const uint DOT_PERIOD_MS = 100; const char *morse_letters[] = { ".-", // A "-...", // B "-.-.", // C "-..", // D ".", // E "..-.", // F "--.", // G "....", // H "..", // I ".---", // J "-.-", // K ".-..", // L "--", // M "-.", // N "---", // O ".--.", // P "--.-", // Q ".-.", // R "...", // S "-", // T "..-", // U "...-", // V ".--", // W "-..-", // X "-.--", // Y "--.." // Z }; void put_morse_letter(const char *pattern) { for (; *pattern; ++pattern) { gpio_put(LED_PIN, 1); if (*pattern == '.') sleep_ms(DOT_PERIOD_MS); else sleep_ms(DOT_PERIOD_MS * 3); gpio_put(LED_PIN, 0); sleep_ms(DOT_PERIOD_MS * 1); } sleep_ms(DOT_PERIOD_MS * 2); } void put_morse_str(const char *str) { for (; *str; ++str) { if (*str >= 'A' && *str <= 'Z') { put_morse_letter(morse_letters[*str - 'A']); } else if (*str >= 'a' && *str <= 'z') { put_morse_letter(morse_letters[*str - 'a']); } else if (*str == ' ') { sleep_ms(DOT_PERIOD_MS * 4); } } } int main() { stdio_init_all(); gpio_init(LED_PIN); gpio_set_dir(LED_PIN, GPIO_OUT); while (true) { printf("Enter String for Morse\n"); fflush(stdin); scanf("%s",str); //gets(str); // does not work?? printf("morse: %s\n", str); //puts(str); //put_morse_str("Hello world"); put_morse_str(str); //sleep_ms(1000); } }

・USBシリアル経由で文字列を入力すると、それに対応したモールス信号でLEDが点滅する。

Arduino framework 対応(2021/4/24)

arduinoのframeworkとして使用する場合は以下のplatformio.iniを使用する:

platformio.ini

[env:pico] platform = https://github.com/platformio/platform-raspberrypi.git framework = arduino board = pico upload_port = /media/USER/RPI-RP2/ ; directory for mass-storage monitor_port = /dev/ttyACM0 ; directory for usb-over-serial monitor_speed = 115200 ;lib_deps =

・USERは、環境依存なので、自分の環境の合わせること。

(1)プログラム(スケッチ)のファイルタイプは.cppではなく.inoを使用すること。
(2)platformio.ini,src/main.inoを作成した後、
以下を実行してudev-ruleを登録する:(src/main.inoはダミーで良い)

# プロジェクト・ディレクトリの中で以下を実行して関係ツールをダウンロードする pio run -t clean # udev-ruleを登録する cd ~/.platformio/packages/framework-arduino-mbed sudo bash ./post_install.sh

udev-rule登録が完了して、書き込みが正常に動作した場合、
以下のような出力になる:

$ pio run -v -t upload # 詳細情報を出力するために「-v」を付けている <省略> Advanced Memory Usage is available via "PlatformIO Home > Project Inspect" RAM: [== ] 18.7% (used 50500 bytes from 270336 bytes) Flash: [ ] 3.5% (used 73048 bytes from 2097152 bytes) .pio/build/pico/firmware.elf : section size addr .boot2 256 268435456 .text 53048 268435712 .rodata 8620 268488760 .ARM.exidx 8 268497380 .ram_vector_table 192 536870912 .data 11372 536871104 .uninitialized_ram.magic_location 12 536882476 .uninitialized_data 0 536882488 .scratch_x 0 537133056 .scratch_y 0 537137152 .bss 39128 536882488 .heap 210416 536921616 .ARM.attributes 40 0 .comment 132 0 .debug_frame 5144 0 .stab 60 0 .stabstr 118 0 Total 328546 <lambda>(["upload"], [".pio/build/pico/firmware.elf"]) AVAILABLE: cmsis-dap, raspberrypi-swd, stlink BeforeUpload(["upload"], [".pio/build/pico/firmware.elf"]) Use manually specified: /media/USER/RPI-RP2/ Forcing reset using 1200bps open/close on port /media/USER/RPI-RP2/ # バグ?で間違ったシリアルポートが選択されているので、ボートがリセットできない /home/USER/.platformio/packages/tool-rp2040tools/rp2040load -v -D .pio/build/pico/firmware.elf rp2040load 1.0.1 - compiled with go1.15.8 .Loading into Flash: [ ] 0% Loading into Flash: [= ] 5% Loading into Flash: [=== ] 11% Loading into Flash: [==== ] 16% Loading into Flash: [====== ] 22% Loading into Flash: [======== ] 27% Loading into Flash: [========= ] 33% Loading into Flash: [=========== ] 39% Loading into Flash: [============= ] 44% Loading into Flash: [=============== ] 50% Loading into Flash: [================ ] 55% Loading into Flash: [================== ] 61% Loading into Flash: [=================== ] 66% Loading into Flash: [===================== ] 72% Loading into Flash: [======================= ] 78% Loading into Flash: [======================== ] 83% Loading into Flash: [========================== ] 89% Loading into Flash: [============================ ] 94% Loading into Flash: [==============================] 100% ========================= [SUCCESS] Took 2.73 seconds =========================

重要:
・現状、バグ?で、USBシリアル経由のボード・リセットができない。
そのため、書き込み前に、ボードのbootselボタンを押しながらホストのUSBに接続して、
その後、bootselボタンを離して、書き込みストレージを出現させる必要がある。
・または、以下のようにplatformio.iniを一部修正すると ボード・リセットが正常に動き、書き込みが成功するようだ。
(もしかして、これが仕様なのかも知れない)

upload_port = /dev/ttyACM0 ;upload_port = /media/USER/RPI-RP2/ ; directory for mass-storage


Arduino用デモ・スケッチ

ASCIITablePico:
src/main.ino

/* ASCII table Prints out byte values in all possible formats: - as raw binary values - as ASCII-encoded decimal, hex, octal, and binary values For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII The circuit: No external hardware needed. created 2006 by Nicholas Zambetti <http://www.zambetti.com> modified 9 Apr 2012 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/ASCIITable */ void setup() { //Initialize serial and wait for port to open: //Serial.begin(9600); Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } // prints title with ending line break Serial.println("ASCII Table ~ Character Map"); } // first visible ASCIIcharacter '!' is number 33: int thisByte = 33; // you can also write ASCII characters in single quotes. // for example, '!' is the same as 33, so you could also use this: // int thisByte = '!'; void loop() { // prints value unaltered, i.e. the raw binary version of the byte. // The Serial Monitor interprets all bytes as ASCII, so 33, the first number, // will show up as '!' Serial.write(thisByte); Serial.print(", dec: "); // prints value as string as an ASCII-encoded decimal (base 10). // Decimal is the default format for Serial.print() and Serial.println(), // so no modifier is needed: Serial.print(thisByte); // But you can declare the modifier for decimal if you want to. // this also works if you uncomment it: // Serial.print(thisByte, DEC); Serial.print(", hex: "); // prints value as string in hexadecimal (base 16): Serial.print(thisByte, HEX); Serial.print(", oct: "); // prints value as string in octal (base 8); Serial.print(thisByte, OCT); Serial.print(", bin: "); // prints value as string in binary (base 2) also prints ending line break: Serial.println(thisByte, BIN); // if printed last visible character '~' or 126, stop: if (thisByte == 126) { // you could also use if (thisByte == '~') { thisByte = 33-1; Serial.println("----------------------------------------------"); Serial.println(""); delay(500); /* // This loop loops forever and does nothing while (true) { continue; } */ } // go on to the next character thisByte++; }

・標準のスケッチをベースにPicoボードにリセットがないので繰り返し実行するように変更したもの

Blink:
src/main.ino

/* Blink Turns an LED on for one second, then off for one second, repeatedly. Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to the correct LED pin independent of which board is used. If you want to know what pin the on-board LED is connected to on your Arduino model, check the Technical Specs of your board at: https://www.arduino.cc/en/Main/Products modified 8 May 2014 by Scott Fitzgerald modified 2 Sep 2016 by Arturo Guadalupi modified 8 Sep 2016 by Colby Newman This example code is in the public domain. http://www.arduino.cc/en/Tutorial/Blink */ // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(LED_BUILTIN, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second }

・標準のスケッチ(変更なし)

参考情報

Pico-Platformio(Pico-SDK)関連:
Raspberry Pico: The Simple Startup with PlatformIO
BAREMETAL(pico-sdk)
Examples
Raspberry Pi Pico RP2040 - PlatformIO (Pico-SDK & Arduino)

Pico-Platformio(Arduino)関連:
Official PlatformIO + Arduino IDE support for the Raspberry Pi Pico is now available!

platformio関連:
PlatformIO Core (CLI)
Arduino-IDEとPlatformioのコンパイラーの挙動の違いについて
arduinoフレームワーク用platformio.ini集
ubuntu20.04をインストールする

以上

|

« PimoroniボードをPicoで動かす | トップページ | Display_Packをpico_arduinoで動かす »

PlatformIO」カテゴリの記事

Pico」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




« PimoroniボードをPicoで動かす | トップページ | Display_Packをpico_arduinoで動かす »