2020/08/06 追記
本件は TinyGo 0.14 で修正されました。
以下は記録として残します。
Windows 版の TinyGo のみ SAMD5x の浮動小数点演算を使おうとするとクラッシュします。
この記事の対象は今のところ、 Windows 版の 0.12 ~ 0.13.x です。
他 OS 版はもともとクラッシュしないはずです。
この問題はおそらく TinyGo 0.14 で修正されますが、それまでの間の対策を記載します。
対策
以下のいずれかの対策をすることで、クラッシュしなくなります。
対策 1 : FPU を有効にする
以下を好きなファイル名 (*.go) で main パッケージのディレクトリに置いてください。
main() 関数が始まる前に FPU を有効化するコードが処理されクラッシュしなくなります。
ビルドする対象のプロジェクト毎に実施する必要があります。
gits にも置きました。
https://gist.github.com/sago35/95c2213093ac3565865be310e5c432a2
// +build atsamd51
// Put this file in the main package directory
// https://github.com/tinygo-org/tinygo/issues/944#issuecomment-597065613
// http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/BEHBJHIG.html
package main
import (
"runtime/volatile"
"unsafe"
)
func init() {
enableCortexM4FPU()
}
func enableCortexM4FPU() {
cpacraddr := (*uint32)(unsafe.Pointer(uintptr(0xE000ED88)))
tmp := *cpacraddr
tmp |= (0xF << 20)
volatile.StoreUint32(cpacraddr, tmp)
}
対策 2 : -mfloat-abi=soft
の設定をする
他の環境 (linux や macOS や docker) と同じバイナリを生成できます。
公式にこの設定が有効になるのはおそらく tinygo 0.14 になってからだと思われます。
ただ、自前で LLVM と tinygo.exe をビルドする必要があるので現実的には厳しいと思います。
以下の PR にて対策が行われつつあります。
- arm: make FPU configuraton consistent
原因
※本項目は読み飛ばして OK です
原因をざくっと書くと、
- Windows 版は LLVM 自前ビルドしていて
-mfloat-abi=soft
がデフォルトオプションになっていない- linux や macos はバイナリインストール版の LLVM を使っていてデフォルトとなっている
- ARM マイコン上の設定で FPU を有効にしていない状態で、 FPU を使った浮動小数点演算を実施する
という組み合わせになっているため、です。
FPU を使うコード (例: x += 0.1
等) があった場合に、 FPU を有効にしていないのに FPU を使おうとするためクラッシュします。
詳細は以下の Issue / PR に記載されていますので、気になる人は読んでみてください。
- SAM D5x based boards crash when using floating point operations
- runtime: Enable FPU of SAM D5x
- arm: make FPU configuraton consistent
まとめ
とりあえずは、 enablefpu.go
を置く対策をしておくと良いです。
tinygo 0.14 で修正されているとよいですね。