chakokuのブログ(rev4)

テック・コミック・DTM・・・ごくまれにチャリ

TinyGoでGDBを起動できない原因を探る

課題:tinygo gdbgdbを起動できない(Cygwin環境下)
目標:tinygo gdbgdbを起動できるようにする
取り組み:tinygoのgdb起動コードを探して、なぜエラーと判断されるのかを特定して、回避手段を検討する
結論: PATH変数に、arm-none-eabi-gdbの実行形式が置かれているフォルダ名を追加することで解消
残る課題:新しいエラーに遭遇、いろんな問題を考えCygwin環境からUbuntu環境に切り替える

詳細:
tinygoのソース一式はGitHubで公開されている。それを一旦落として、grepでエラーコードを検索する。結果、以下のコードでエラー判断されているようであった。
file: compileopts/target.go

// LookupGDB looks up a gdb executable.
func (spec *TargetSpec) LookupGDB() (string, error) {
        if len(spec.GDB) == 0 {
                return "", errors.New("gdb not configured in the target specification")
        }
        for _, d := range spec.GDB {
                _, err := exec.LookPath(d)
                if err == nil {
                        return d, nil
                }
        }
        return "", errors.New("no gdb found configured in the target specification (" + strings.Join(spec.GDB, ", ") + ")")
}

自分の知識では、引数見つけられないのだが、、メッセージから判断すると、spec.GDBには、[gdb-multiarch, arm-none-eabi-gdb]の2要素が入っていて、順番にexec.LookPath(d)で探しているのだろう。exec.LookPath(d)で該当のパスを見つけられず、エラーになっていると判断

Spiegel氏の記事によると、exec.LookPath関数は、os/exec標準パッケージらしい。だったら、この部分だけ切り出してgoで実行すれば、何がおかしいのか分かるはず。

LookPathを使ったサンプルを掲載してくれている人*1がいて、このコードを参考にgdbを探すコードを書いてみる。先人に倣って書くと以下のような感じか。変数binaryにはパスとコマンドが入っているはずなのに、argsで再度コマンドを指定するのが正しいのか、ちょっと理解できず。。

package main
import (
    "os"
    "os/exec"
    "syscall"
)

func main() {

    binary, lookErr := exec.LookPath("arm-none-eabi-gdb")
    if lookErr != nil {
        panic(lookErr)
    }
    args := []string{"arm-none-eabi-gdb", "-v"}
    env := os.Environ()
    execErr := syscall.Exec(binary, args, env)
    if execErr != nil {
        panic(execErr)
    }
}

実行してみる。確かに、PATHを通していないので怒られる

$ go run gdb.go
panic: exec: "arm-none-eabi-gdb": executable file not found in %PATH%

goroutine 1 [running]:
main.main()
        C:/cygwin64/home/<user_id>/lang/go/gdb_test/gdb.go:12 +0x3b
exit status 2

/usr/local/binにarm-none-eabi-gdbを置いていてPATHが通っているので、コマンド名だけで起動できる状態

$ arm-none-eabi-gdb
GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20131129-cvs
Copyright (C) 2013 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=i586-mingw32 --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) quit

なのに、LookPathだと見つけられない。LookPathの検索ディレクトリは環境変数($PATH)なのか、それとも、どこかで指定されているのか。。

$ go run gdb.go
panic: exec: "arm-none-eabi-gdb": executable file not found in %PATH%

goroutine 1 [running]:
main.main()
        C:/cygwin64/home/<user_id>/lang/go/gdb_test/gdb.go:12 +0x3b
exit status 2

os/execの仕様書によると、環境変数からPATHを取得しているらしい。cygwin環境でgoを走らせた場合の環境変数とは何を見ているのか。
試しに、/usr/binにtouchでarm-none-eabi-gdbを置くと再度エラーとなり、/usr/bin/にarm-none-eabi-gdb.exeを置くとファイルを見つけるのには成功した。だから、、LookPathで検索するディレクトリには/usr/local/binが含まれていなさそうである。

/usr/bin $ touch arm-none-eabi-gdb
/usr/bin $ touch arm-none-eabi-gdb.exe

多分検索PATHを環境変数から取っているので、以下のコードでGoが見ているPATHを確認できると思われる(LookPathのソースコードまでは裏取っていない)

    fmt.Printf(os.Getenv("PATH"))

実行結果は以下の通りで、cygwinの/usr/local/binがWindows環境のPATHとして見ている。だからPATH変数は実行時の環境を取ってきている。

C:\cygwin64\usr\local\tinygo0.26.0.windows-amd64\tinygo\bin;
C:\cygwin64\usr\local\bin;

根本原因は分からないが、、cygwinでsymblic linkで配置していたが、この場合、ファイルとしてみなされないのが原因のようであった。実体をコピーするとOK

$ pwd
/usr/local/bin
$ ls -la
total 1106
drwxr-xr-x 1 sumi Unknown+Group      0 Dec 10 19:30 .
drwxr-xr-x 1 sumi Unknown+Group      0 Dec 11 08:51 ..
drwxr-xr-x 1 sumi なし               0 Oct 13 22:30 __pycache__
-rwxr-xr-x 1 sumi なし             205 Mar  5  2022 ampy
lrwxrwxrwx 1 sumi なし              67 Dec 10 19:30 arm-none-eabi-gdb.exe -> /usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin/arm-none-eabi-gdb.exe

Symbolic linkせずに実体を/usr/local/binに置く。

$ ls -la
total 5342
drwxr-xr-x 1 sumi Unknown+Group       0 Dec 11 10:51 .
drwxr-xr-x 1 sumi Unknown+Group       0 Dec 11 08:51 ..
drwxr-xr-x 1 sumi なし                0 Oct 13 22:30 __pycache__
-rwxr-xr-x 1 sumi なし              205 Mar  5  2022 ampy
-rw-r--r-- 1 sumi なし          4334592 Dec 11 10:54 arm-none-eabi-gdb.exe

実行時点でpanicになったが、gdbを見つけることはできた

$ go run gdb.go
panic: not supported by windows

goroutine 1 [running]:
main.main()
        C:/cygwin64/home/sumi/lang/go/gdb_test/gdb.go:21 +0x58
exit status 2

まとめ
(1) cygwinのSymbolic linkは lookPathではファイルとみなされない
(2)回避策として、/usr/local/bin/に gdbの実体を置くか、$PATHにgdbが置かれているパスを追加する

/usr/local/binにgdbの実体を置くのは避けたいので、以下のように$PATHにgdbの実体が置かれているPATHを追加する

export PATH=/usr/local/GNUToolsARMEmbedded/4.8_2013q4/bin:$PATH

GDBを見つけられない問題は解消したと判断して、tinygo gdbを実行する。以下の通り、gdbが無いとは怒れなくなった。が、次のエラーにでくわした。go.modが無いと。。

$ tinygo gdb --target pico
go: go.mod file not found in current directory or any parent directory; see 'go
help modules'

go mod initを実行するらしい。実行してみる

$ go mod init blinky
go: creating new go.mod: module blinky
go: to add module requirements and sums:
        go mod tidy

go.modが無いと怒られる件は解消した。次はopenocdが無いと怒られる。PATH通してないのでこれはその通りなのだが。。openocdはWindows上ではなく、RPi上で動かすつもりなので、今の設定ではまずい。設定上はリモート接続にしたい。

$ tinygo gdb  -target pico
error: failed to run openocd: exec: "openocd": executable file not found in %PATH%

tiny.goのメインと思われる、main.goを読む限り、リモート上で稼働するOpenOCDとTCP接続してgdbを起動するようなコードは見当たらず、gdbとopenOCDはどちらもローカル環境で動かすのが前提のようだ。だから、、(1)自分のような特殊な環境でも動作するように、main.goを改修する、(2)手動でopenOCDとgdbを起動してデバッグする、のいずれかとなる。go言語はほとんど分かっていないので、当面は後者の方法でデバッグすることにする。ただ、、シンボリックデバッグ等が可能なのかどうかも不明。実行形式に対して、デバッグ情報を含める、含めないを指定するオプションがあるのかどうか分からない。

公式サイトによると、-no-debug オプションを付けるとデバッグ情報を含めないようなので、このオプションがなければデバッグ情報が入っているはず。
Misc. Build Options | TinyGo

今後の開発手順は以下
tinygo buildで実行形式を作って、それをPicoに焼く(仮想ファイルシステムにコピーしてもいいし、OpenOCDを使ってFlash書き込みも可能)。デバッグ時、RPi上でOpenOCDを動作させ、Windows環境で起動したgdbからリモートで接続する。gdbデバッグ情報を含む実行形式を読み込んで、Pico上のプログラムをデバッグする。

第3の方法として、接続不可能なWindows上のOpenOCDを起動して、エラーを起こさせてから、gdbで再接続するという方法も考えられる。これをやってみた。

$ export PATH=/usr/local/openocd-0.10.0/bin:$PATH

$ tinygo gdb --target pico
GNU gdb (GNU Tools for ARM Embedded Processors) 7.6.0.20131129-cvs
Copyright (C) 2013 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=i586-mingw32 --target=arm-none-eabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\cygwin64\tmp\tinygo3499458027\main...Dwarf Error: wrong
version in compilation unit header (is 5, should be 2, 3, or 4) [in module C:\cy
gwin64\tmp\tinygo3499458027\main]
(no debugging symbols found)...done.
:3333: 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続
できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失
敗しました。

すると、、compilation unit headerというエラーが発生して、debugging symbolが読めない状況になった。
想像するに、LLVM経由でコンパイルされたDrawfのフォーマットが新しく、自分のgdbでは未対応ということではなかろうか。
デバッグシンボルのないデバッグってほとんど意味をなさないので、ここは解消が必要。Cygwin環境に最新のGDBを入れたら修正されるのではと想像するがだんだんと面倒になってきた。そもそもCygwin環境でどうにかしようというアプローチがまずいのではと思えてきた。Ubuntu 等の標準環境でコンパイラとデバッガ一式をそろえた方が最新版に統一されていいのではと思える。

■参考URL
Go でサブプロセスを起動する際は LookPath に気をつけろ!
サンプルで学ぶ Go 言語:Exec'ing Processes
exec package - os/exec - Go Packages

*1:原著者 Mark McGranaghan | 翻訳者:spinute

Pico+TinyGo用のデバッグ環境をOpenOCDで構築

目標:コンパイラ型言語で何かモノを作る時はデバッガがないとやってられないと思い、OpenOCDによるデバッグ環境を構築する。
取り組み:ST-Linkで試す、だめなら、RPi4上でOpenOCDを動かしてSWDで接続する
結果:ST-Linkはターゲット(Pico)と接続できなかった。RPi4上に構築したOpenOCDはターゲットと接続できた
課題:RPi上のGDB+OpenOCDの組み合わせではPico上のプログラムのデバッグができそうだった。一方、tinygo gdbによる起動ではエラーが出てgdbが起動できていない。configが不足しているのは明らかだが、なぜエラーなのか?原因が分からない

取り組み:
よくあるのは、PicoでPicoをデバッグするというやつなのだが、、以前買ったST-Link V2コンパチでデバッグできないかやってみた。

$ ./bin-x64/openocd.exe  -f ./scripts/interface/stlink-v2.cfg  -c "adapter_khz 4000"       -c 'set USE_CORE 0'  -f ./scripts/target/rp2040.cfg                  Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 4000 kHz
0
./scripts/target/rp2040.cfg:43: Error: invalid command name "dap"
in procedure 'script'
at file "embedded:startup.tcl", line 60
at file "./scripts/target/rp2040.cfg", line 43

適当にrp2040.cfgを取ってきて引数に指定してみたが、エラーになる。RP2040はマルチコアなのだが、ST-LINK V2のファームはマルチコアに対応していないのが原因らしい。ファームを更新すれば動くという記事もあり。
https://electronics.stackexchange.com/questions/592979/programming-rp2040-with-st-link
ファーム更新に失敗してST LINKを壊すのは避けたいので、、RPiにOpenOCDを入れてデバッグする方法を検討する。
GitHub - raspberrypi/openocd
RPi4上でOpenOCDを動かして、SWDで接続してPico上のプログラムをデバッグする方法が以下に記載されている。これによると、OpenOCDをビルドするようだ。。
https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf

GPIOとボードの接続は以下

GND (Pin 20)    <-> SWD GND
GPIO24 (Pin 18) <-> SWDIO
GPIO25 (Pin 22) <-> SWCLK

以下のオプションでOpenOCDが動くはず

openocd -f interface/raspberrypi-swd.cfg  -f target/rp2040.cfg

結線せずエラー前提で起動してみる。スクリプトの読み込み段階ではエラーがなく、DAP(Debug Adapter Protocol)で初期化エラーとなる(多分結線していないからだろう)

$  /usr/local/bin/openocd  -f /usr/local/share/openocd/scripts/interface/raspberrypi-swd.cfg -f /usr/local/share/openocd/scripts/target/rp2040.cfg

Open On-Chip Debugger 0.11.0-g228ede4-dirty (2022-12-10-18:01)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 1000 kHz

Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : RP2040 Flash Bank Command
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 1001 kHz
Info : Read incorrect DLIPDR 00000000 (possibly CTRL/STAT value) when selecting coreid 0
Info : DAP init failed

Info : Read incorrect DLIPDR 00000000 (possibly CTRL/STAT value) when selecting coreid 0

RPi4とPicoをSWDで接続してOpenOCDを起動する。以下の通り、3333番ポートでListenしてますと出ているので、ターゲットとは接続できたのだろう

root@raspberrypi:/usr/local/share/openocd/scripts/target# /usr/local/bin/openocd  -f /usr/local/share/openocd/scripts/interface/raspberrypi-swd.cfg -f /usr/local/share/openocd/scripts/target/rp2040.cfg
Open On-Chip Debugger 0.11.0-g228ede4-dirty (2022-12-10-18:01)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
adapter speed: 1000 kHz

Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : RP2040 Flash Bank Command
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 1001 kHz
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477
Info : SWD DLPIDR 0x10000001
Info : rp2040.core0: hardware has 4 breakpoints, 2 watchpoints
Info : rp2040.core1: hardware has 4 breakpoints, 2 watchpoints
Info : starting gdb server for rp2040.core0 on 3333
Info : Listening on port 3333 for gdb connections

GDBからOpenOCDを呼び出してみる。レジスタは表示できた

$ gdb
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

(gdb) target remote localhost:3333
Remote debugging using localhost:3333
warning: No executable has been specified and target does not support
determining executable automatically.  Try using the "file" command.
warning: multi-threaded target stopped without sending a thread-id, using first non-exited thread
0x10001a4c in ?? ()
(gdb) i r
r0             0x1cf99f64          486121316
r1             0x1                 1
r2             0x1                 1
r3             0x7a120             500000
r4             0x7a11d             499997
r5             0x40054010          1074085904
r6             0x1                 1
r7             0x20000b38          536873784
r8             0xffffffff          -1
r9             0xffffffff          -1
r10            0xffffffff          -1
r11            0xffffffff          -1
r12            0x4001801c          1073840156
sp             0x200007f8          0x200007f8
lr             0x10001a45          268442181
pc             0x10001a4c          0x10001a4c
xPSR           0x1000000           16777216
msp            0x200007f8          0x200007f8
psp            0x20001384          0x20001384
primask        0x0                 0
basepri        0x0                 0
faultmask      0x0                 0
control        0x0                 0

(gdb) x/i $pc
=> 0x10001a4c:  ldr     r5, [sp, #4]

今は、[GDB]--->[OpenODC]--->[RPi Pico] の形式で接続しているので、GDBをtinyGo版のGDBに置き換える必要があるのだろう。。多分

と思ったら違っていて、 コマンドプロンプトから tinygo gdb と打ち込むと、PATH上にある、gdbが起動されるようであった。しかし、どうやってプローブと接続指定をするのか不明。自分の環境だと、コンパイルWindows上で、OpenOCDはRPi4上なので、IPとPortを指定してGDBを起動する必要があるのだが。。
解説本を参考にtinygoからGDBを起動しようとするがエラーになる

$ tinygo.exe gdb --target pico
error: no gdb found configured in the target specification (gdb-multiarch, arm-n
one-eabi-gdb)

$ cat /usr/local/tinygo0.26.0.windows-amd64/tinygo/targets/rp2040.json
{
    "inherits": ["cortex-m0plus"],
    "build-tags": ["rp2040", "rp"],
    "flash-1200-bps-reset": "true",
    "flash-method": "msd",
    "serial": "usb",
    "msd-volume-name": "RPI-RP2",
    "msd-firmware-name": "firmware.uf2",
    "binary-format": "uf2",
    "uf2-family-id": "0xe48bff56",
    "rp2040-boot-patch": true,
    "extra-files": [
        "src/device/rp/rp2040.s"
    ],
    "openocd-interface": "picoprobe",
    "openocd-transport": "swd",
    "openocd-target": "rp2040"
}

openocd-interfaceがpicoprobeってのも気になる。tinygo gdb で単にGDBが起動されているだけなら、手動でODBを起動してもOKなのだが。

Gitにソースコードが公開されているので、gdbを指定した時の動きを見てみたい。gdbが見つけられないのか、あるいは、gdbは見つけたが、ターゲットをデバッグできる条件を満たさないのか。。
GitHub - tinygo-org/tinygo: Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.

RPi上でtinygoの環境を構築してgdbを起動してみた。gdbが無いとか怒られることなく動いたが、ターゲット制御?でエラーが出ている。

$ tinygo gdb --target pico
GNU gdb (Debian 10.1-1.7) 10.1.90.20210103-git
Copyright (C) 2021 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 "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://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"...
Reading symbols from /tmp/tinygo4028570371/main...

warning: Section .debug_aranges in /tmp/tinygo4028570371/main has duplicate debug_info_offset 0xee3, ignoring .debug_aranges.
:3333: Connection timed out.
"monitor" command not supported by this target.
You can't do that when your target is `exec'
"monitor" command not supported by this target.
(gdb) l
DW_FORM_rnglistx index pointing outside of .debug_rnglists offset array [in module /tmp/tinygo4028570371/main]
(gdb) list
error: failed to run gdb-multiarch with /tmp/tinygo4028570371/main: signal: aborted

TinyGoをRPi Pico上で動作させたい->LチカまではOK

背景:これまで組み込み用プログラミングではMicroPythonで緩くやってきた(とにかく楽なので)
課題:本屋でTinyGoの本を見つけて、言語仕様がコンパクトでコンパイル型言語(LLVM)ということで使ってみたくなった。MQTT等のライブラリもあるそうだ。RPiPico上でTinyGoを走らせて、ポーリング性能を測ったり、Lチカ等をやってみたい
取り組み:まずはWindows環境にTinyGoの開発環境を構築
結果:環境構築、Lチカまで行えた(トラブルなしに1時間程度で完了)

詳細:
まずGoをインストールする必要がある。Go 1.19.4をDL、Windows環境にインストール
Downloads - The Go Programming Language
次に、TinyGo binaryをDLしてパスを通す。
自分は普段Cygwin環境を使っていて、パスを通すと以下のように動作する。

$ tinygo version
tinygo version 0.26.0 windows/amd64 (using go version go1.19.4 and LLVM version
14.0.0)

試しにビルドしてみる。tinygoのZIP一式の中にサンプルコード集があり、LED点滅サンプルが入っているのでそれを使う。
file: cat blinky1.go

package main
// This is the most minimal blinky example and should run almost everywhere.
import (
        "machine"
        "time"
)
func main() {
        led := machine.LED
        led.Configure(machine.PinConfig{Mode: machine.PinOutput})
        for {
                led.Low()
                time.Sleep(time.Millisecond * 500)

                led.High()
                time.Sleep(time.Millisecond * 500)
        }
}

本に倣って、targetをwioterminalとしてビルドしてみる。。バイナリが生成されるまで結構時間がかかる。裏側で何パスも走っているからだろうか。。 多分RPi Pico用にtargetを変える必要があると思われる。

$ tinygo.exe build -o blink.uf2 -target wioterminal -size short blinky1.go
   code    data     bss |   flash     ram
   7396     108    6280 |    7504    6388

targetオプションは pico とする必要がありそうだ。あと、、picoのLEDってややこしかった記憶が。。その辺も吸収してくれるのか??
Raspberry Pi Pico | TinyGo
pico用にビルド実施

$ tinygo.exe build -o blink.uf2 -target pico -size short blinky1.go
   code    data     bss |   flash     ram
   8104     108    2880 |    8212    2988

uf2形式でファイルはできた。これをそのままpicoにDrug&Dropしたら動くのだろうか。。あるいは仮想Serialからflashツールで焼くのか?

picoはBOOTボタンを押しながら起動すると仮想ドライブとしてPCから見えるので、UF2形式のバイナリであればDrag&DropでコピーすればFlashに書き込める。ということで、そのようにしてみたが、LEDは点滅せず。暴走しているのか、ピン配置が異なるのか。。自分のボードには、GP15(20番Pin)にLEDを接続しているので、GP15をL/Hしてみる。
Pico用に修正したソースは以下。これをビルドして、Picoに書き込むと、LEDが点滅した。

package main

// This is the most minimal blinky example and should run almost everywhere.

import (
        "machine"
        "time"
)

func main() {
        //led := machine.LED
        led := machine.GP15
        led.Configure(machine.PinConfig{Mode: machine.PinOutput})
        for {
                led.Low()
                time.Sleep(time.Millisecond * 500)

                led.High()
                time.Sleep(time.Millisecond * 500)
        }
}

使ってみようと思って1時間ぐらいで環境構築とLチカまで進めることができた。解説本やTInyGoの公式サイトによる分かりやすい説明も助けになったが、TinyGoのビルド環境やライブラリ群がよく整備されていて使いやすいおかげと思う。また、Picoの場合、仮想ドライブが実現されていて、Flashへの書き込みもDrug&Dropで済み、書き込みツールは不要だ。はまりポイントはほとんどなく、手軽ですばらしいと思う。
ただ、、ビルドに結構時間がかかるのが難点か。自分のPCの性能が低いためかもしれないが。
OpenOCD+GDBによるデバッグ(SWDデバッグ)も可能らしいので、デバッグ環境も整えたい。
■参考URL
Windows | TinyGo
GDB | TinyGo
Windows用 RaspberryPi Pico デバッグ環境(C言語)の作り方(PicoProbe編)
Raspberry Pi Picoをデバッガーで動かす | neocode
https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf#page=19
GitHub - georgerobotics/cyw43-driver

Pico-WのWiFiモジュールは、CYW43439

Pythonを使ったMEEのプログラミング (絶対座標でブロックを配置)

仕様書がどこにあるのか分からず手探りなのだが、、絶対座標(World座標というのだろうか)でGRASSブロックを配置してみる

for ud in range(68,100,3):
    for ew in range(11,14):
        blocks.place(GRASS, world(ew, ud, 100))
        blocks.place(GRASS, world(ew, ud, 100))
        blocks.place(GRASS, world(ew, ud, 100))
        blocks.place(GRASS, world(ew, ud, 100))

絶対座標は(EastWest, UpDown, SouthNorth)の構成らしい

■追記
仕様書は以下 (Pythonも併記されている)
https://minecraft.makecode.com/reference

Minecraft Education EditionのPython Coding Courseをやってみる→ Lesson4 の餌やりで正解がわからない

課題:Minecraft Education Edition(MEE)が使えるようになったので、Python Coding Course(Python 101)をやってみた。Lesson4のActivity 2: Dietary requirementsでは犬に適切な餌をやるのだが、RedStoneの使い方がわからないせいか、どうやったら正解になるのかわからない。雛形コードが用意されているのだけど、雛形コードで指定されているLocationがどの位置なのかも分からず、途方に暮れる。
取り組み:教師用テキストがあるので解答を打ち込んでみる
結果: 教師用テキストの正解ソースコードはMakeCodeで動く仕様であり、Lessonで起動されるエディタのPythonではエラーになる(打ち間違いだったらすみません)。だから、エディタをMakeCodeに切り替えて、シンプルなコードで材料供給装置を動かした(リストを学ぶべきステージなのだが、動かすことを優先してリストは使わず)

以下の画面が、Lesson4の犬の餌やりプログラミングのシーン

教師用テキストを参照、以下が雛形コード

以下が正解例

見比べると、、RedStoneを所定の座標に置くように修正されている。2匹目の犬用コードが入ってしまっていてわかりにくい部分もあるが、1匹目は4種類の素材を与えればいいので、配列のインデックスと0〜3を指定するように編集すれば良いようだ。

材料が入った箱の上の空間(-21, 45, -31) ~ (-21, 45, -23)にRedstome Blockを配置することで、Redsotne回路が働いて、材料の箱から肉やビタミン等が落下して、前方の壁に置かれたキャビネットに格納される仕組みのようであった。キャビネットに入った材料は、自分で取り出しに行って、犬の餌箱に入れる手順となるようであった。

動作確認のため、雛形ソースは無視して、Minectaft用の標準的なPython環境で動かせるようエディタをMakeCodeに切り替えて以下を打ち込んで動かした。結果、一匹目の犬のための餌を集めることはできた。だが、エディタを切り替えたせいか、次の犬には切り替わらないようなので、元の設定されたエディタを使う必要がある*1

blocks.place(REDSTONE_BLOCK, world(-21, 45, -31))
blocks.place(REDSTONE_BLOCK, world(-21, 45, -29))
blocks.place(REDSTONE_BLOCK, world(-21, 45, -27))
blocks.place(REDSTONE_BLOCK, world(-21, 45, -25))

元から使えるエディタの場合、blocksオブジェクトを指定すると「不明な変数」とエラーになる。worldオブジェクトを使う必要があるようだ。worldオブジェクトってどこで定義されているのかも不明。

MakeCodeでプログラムすると次のステージへの扉(ガラスの扉?)が開かないので、以下のコードを実行してplayerを次のステージに移動させた(これもチートの一種だろうか。。)

player.teleport(world(-41, 40, -17))

次のステージに移ったものの、猫の名前を間違っていてなおして欲しいと言われるのだが、何をどうしたらいいのか、サンプルコードがないと全く分からない。エディタをMakeCodeにするとサンプルコードが表示されなくなるので、解きようがない。。(先生用のテキストを見て考える手はあるけど。。)

先生用のテキストを見ると、サンプルコードが掲載されていて、猫の名前を文字列としてリストに入れておいて、playser.say(Cats_Names[n])でプレーヤが発話するというものであった。画面からだけでは何をどうしたらいいのか全く推測もできず、サンプルコードを見ないと分からない。。教材としてこれはどうなのだろうか・・・

やることはだいたいわかったので、復習のため、MakeCodeに切り替えずに最初から組み込まれている環境でもう一度このコースを流してみたい。

■参考URL
MEEの教師用解説ページ
https://education.minecraft.net/ja-jp/lessons/python-101-lesson-4

*1:と思ったが、一匹目が成功したら、2匹目の設問に切り替わった。一方、3匹目の犬をクリアしても次のステージへのゲートが開かない

統計を理解しつつ、MATLABで描画する

目的:子供(といっても大学生なのだが)の授業(MATLABの課題)を支援する*1ため統計とMATLABを学ぶ。
結果:


2項分布の説明で、コイン投げの成功の確率(確率密度関数の形)がなぜ山形になるのか分からない。投げる回数が多いほうが出やすくなるのでは?? そもそもコイン投げにおける成功とは何なのか?? (参考URL等のサイト等を見て理解)
勘違いだったのは、x軸は投げる回数ではなく、成功する回数である。成功する確率とは、決めた条件が成立する確率で、例えば表になったら成功と定義する(コイン投げに絞って言うと、仮にコインを10回投げるとして、5回表になる確率がX軸が5の時のYの値)。そう理解してグラフを見ると、ほどほどの成功(10回中5回表)が一番確率が高く、失敗ばかり(裏ばかり)、あるいは成功ばかり(表ばかり)というのはまれであると、、そう考えると腑に落ちる。
整理すると、、コイン投げの成功とは、n回の試行中、X回表(または裏)になる場合をX軸にとり、その時の確率をY軸に取る。もし表の発生確率が50%だったら、確率分布の山頂は試行回数の中央になる。と理解。一方、発生確率が高い場合は、山頂が右にずれて(ほとんど成功するから、成功するピークはX軸の大きい方にずれる)、発生確率が低い場合は、山頂が左にずれる(まれにしか成功しないから成功するピークはX軸の小さい方にずれる)

以下のような感じで、ベータ分布の確率分布のグラフが書けるのでは?と思うのだが、、時間がなくてプログラムの試作ができず

X = 0:.01:1;
y = betapdf(X,4,4);
plot(X,y)
hold off   % need this??

風邪気味なのだが、、ちょっと動かしてみた。行末のセミコロンが必須かどうか不明

X = 0:.01:1;
y = betapdf(X,4,4);
r = betarnd(4,4,100,1);

yyaxis left;
plot(X,y);
hold on;
yyaxis right;
histogram(r);
hold off;

上記スクリプトで生成された図は以下

■参考URL
BASIC STUDY | AVILEN AI Trend
13-1. 二項分布 | 統計学の時間 | 統計WEB

*1:子供(大学生・・・)の課題を親がやって教育的にどうなのか??はおいといて、面白いのでやってみる。