LoginSignup
3
0

More than 3 years have passed since last update.

Windows 版の TinyGo で SAMD5x CPU の浮動小数点演算でクラッシュする問題への対策

Last updated at Posted at 2020-05-22

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

enablefpu.go
// +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 にて対策が行われつつあります。

原因

※本項目は読み飛ばして OK です

原因をざくっと書くと、

  • Windows 版は LLVM 自前ビルドしていて -mfloat-abi=soft がデフォルトオプションになっていない
    • linux や macos はバイナリインストール版の LLVM を使っていてデフォルトとなっている
  • ARM マイコン上の設定で FPU を有効にしていない状態で、 FPU を使った浮動小数点演算を実施する

という組み合わせになっているため、です。
FPU を使うコード (例: x += 0.1 等) があった場合に、 FPU を有効にしていないのに FPU を使おうとするためクラッシュします。

詳細は以下の Issue / PR に記載されていますので、気になる人は読んでみてください。

まとめ

とりあえずは、 enablefpu.go を置く対策をしておくと良いです。
tinygo 0.14 で修正されているとよいですね。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0