雑食エンジニアの気まぐれレシピ

日ごろ身に着けた技術や見知った知識などの備忘録的なまとめ.主にRaspberry Piやマイコンを使った電子工作について綴っていく予定.機械学習についても書けるといいな.

Go言語+RaspberryPiをWindowsのVSCodeで開発する

室内の環境把握用にサーバを立てようと思い立ったんですが,せっかくだから何か新しいコトをやろうということで,Go言語を導入してみることにしました.

その際にやったことを備忘録がてら整理しておこうかと思います.

Go言語について

Go言語はかのGoogleが作った言語で,最近バックエンド側の言語として注目されているらしいです.スクリプト言語のような手軽さで,コンパイル言語のような速度が出せるとかなんとか.

その他にも色々な特徴はありますが,個人的に注目している性質はクロスプラットフォーム対応が容易という点だと思います.

Go言語はコンパイル時にターゲットプラットフォームを指定することで,そのプラットフォームで動作するバイナリとしてコンパイルを行うことができます.windowsでいうところのexeファイルが作られるようなものなので,そのままクリックするだけで実行できます.

Javaのようなクロスプラットフォーム言語は実行側のOSにJREがインストールされていないと実行できないので,そこに大きな違いがあります.

はてさてターゲットプラットフォームの指定ですが,GO言語用の環境変数によって制御できます.

GOOS=linux
GOARCH=arm
GOARM=7

そのうえで,

go build "ソースのパス"

とやればそのターゲットに向けたビルドが行えます.

なおGORARCHはアーキテクチャのことで,GOARMはarmのバージョンです.ラズパイがどのバージョンかどうかはターミナルに"arch"と打ち込めば得られます.

ちなみにラズパイがどのアーキテクチャ/バージョンなのかはWikipediaに載っていますが,どうも私のラズパイ3Bはv7だったので,記載と異なっていました.archコマンドで取得したほうが確実だと思われます.
Raspberry Pi - Wikipedia

VSCodeのセットアップ

というわけでgo言語を使ったラズパイ用の開発はどこでやってもよいことになるので,今回は母艦のWindowsからVSCodeで開発することにしました.

VSCodeでのGo言語をつかった開発自体は
VSCodeでGo言語の開発環境を構築する - Qiita
様のエントリが非常に分かりやすかったです.
今回はこの上で,

  1. ラズパイをターゲットに指定したビルド
  2. 実行ファイルをラズパイにコピー

までを一連の動作として仕込みます.

VSCodeでのこの辺りの処理はtasks.josnというファイルに記載することで実現できます.tasks.jsonの初期化は下記エントリが分かりやすいです.
VSCode のタスクを作成する

で,そこに下記のようなタスクを書き込みました.

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "go build",
            "type": "shell",
            "command": "go",
            "args": [
                "build",
                "-o",
                "./bin/${workspaceFolderBasename}",
                "-v",
                "./..."
            ],
            "options": {
                "env": {
                    "GOARM": 7,
                    "GOARCH": "arm",
                    "GOOS": "linux",
                }
            }
        },
        {
            "label": "copy",
            "type": "shell",
            "command": "xcopy",
            "args": [
                "/y",
                "/I",
                ".\\bin",
                "\\\\lnld-pi3.local\\pi\\scripts\\go\\bin"
                //↑はラズパイのパス.windowsの共有フォルダ.
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "dependsOn": [
                "go build"
            ]
        },
    ]
}

軽く解説するとポイントは下記でしょうか.

  • typeでshellを指定しておくと,ターミナルコマンドが実行できる
  • optionsのenvで環境変数を指定できる
    • ここでターゲットプラットフォームを指定する
  • groupでbuildを指定したコマンドがビルド時に呼び出される.
    • ショートカット的には"ctrl + shift + B"
    • isDefarultをtrueにしたコマンドがデフォルトで呼び出される
  • dependsOnでタスクの依存関係を指定できる
    • ラベルで指定したタスクを先に実行し,成功したらこのタスクを実行する.

つまり上記のコードでは次の順番でタスクが実行されます.

  1. ctrl+shift+Bを押すと"copy"が呼び出される,が,
  2. それが依存する"go build"が先に実行される
  3. そして"go build"が成功すると,"copy"が実行される

という感じになります.dependsOnが先に呼び出されるのはまぁ当然ではあるんですが,何となく違和感があるような.

さておき,これでWindowsVSCodeからGo言語によりラズパイ用のコードを開発することができるようになりました.
なおリモートデバッグ機能はdelveを使えばできるかと思いましたが,raspbian(=32bit arm)では対応していないらしいです.

おまけ I/Oの利用

gobotというフレームワークを使うと,go言語でもラズパイのI/Oが使えます.
Raspberry Pi with Gobot

なおピン番号はラズパイのピン番号を直接指定します.
(GPIO番号ではないので注意).

おわりに

というわけで,今回は環境構築編でした.
室内環境モニタリングのためのプロトは一応進んでいるので,次回はそれについて書きたいと思います.
それでは.