[RISC-V技術ブログ連載第26回]TinyGoでLチカ

RISC-V

1.はじめに

 少し間があいてしまいましたが、こちらのブログではRISC-Vをさらに盛り上げるべく、お手軽にRISC-Vを試す方法を中心に、引き続きRISC-V関連の技術情報をお届けしていきたいと思います。今回はRISC-Vボードで手軽に試せるTinyGoについてお伝えします。

 前回お伝えしたRustと同様に注目度が高まっている言語としてGo言語というものがあります。Go言語は、Googleが2007年に開発したオープンソースのプログラミング言語で、C言語のような効率性やシンプルさを持ちつつ、Pythonのようなプログラミングのしやすさを兼ね備えており、並行処理が得意なため、Webアプリケーション開発や分散システムの開発での利用が進んでいます。その組込み版ともいえるのがTinyGoです。TinyGoはRISC-Vをサポートしており、各種RISC-Vボード用のサンプルプログラムが用意されていることから、本ブログで取り上げることにしました。 今回は、TinyGoの概要、TinyGoで作られたLチカプログラムをHiFive1 RevBボード上で動かすための環境構築、実際に動作する様子までをお伝えしたいと思います。

2.TinyGo概要

2.1.TinyGoとは

 TinyGoとは、Go言語をマイクロコントローラや小さなデバイス向けに最適化された、オープンソースのコンパイラです。Go言語は一般的に、サーバーやWebアプリケーション、ツールなどの大規模なアプリケーションの開発に使用されますが、TinyGoはそのような大規模なアプリケーションよりも、制御機器や組込みシステム向けの小さなアプリケーションに適しています。

 TinyGoは、Go言語の文法と機能の多くをサポートし、C/C++と同じように、コンパイルされたコードを直接ハードウェア上で実行できます。様々なマイクロコントローラや開発ボードで動作するものが用意されており、市販のRISC-Vボードを対象としたサンプルプログラムも用意されています。

2.2.TinyGoとRustそれぞれの長所・短所

 TinyGoはRustと同様に、組込みシステムやマイクロコントローラ向けに設計されたプログラミング言語であり、安全性、効率性、速度、並行性などの重要な要素を備えていますが、いくつかの異なる特徴を持っています。以下にそれぞれの長所と短所を挙げてみます。

長所短所
TinyGo・メモリ効率が高いため、小さなデバイスに最適
・Go言語に似た構文を使用しているため、Go言語に慣れている人にとっては学習が容易
・コンパイルが高速で、クロスコンパイルも容易
・Go言語に比べて機能が制限されているため、高度な処理を行う場合には不向き
・標準ライブラリの一部が未実装であるため、開発に手間がかかる場合がある
・ガベージコレクションが実行されるため、メモリ使用量が多くなる場合がある
Rust・メモリ安全性が高く、スレッドセーフであるため、セキュリティ上の問題が少ない
・ゼロコスト抽象化(※1)により、高速で効率的なプログラムを実現できる
・マルチパラダイムプログラミング言語(※2)であり、関数型プログラミングの手法も取り入れられるため、柔軟性が高い
・Rust言語自体の学習コストが高いため、初心者には敷居が高い
・コンパイル時間が長いため、大規模なプロジェクトでは手間がかかる場合がある
・メモリ安全性を保証するための厳格なシステムにより、プログラミングの自由度が低く、初めから考慮しなければならない要素が多い

※1 抽象化における実行時の追加のコスト(メモリの動的ディスパッチ)を最小限にするという考え方です。静的ディスパッチによって実現されるため、メモリの確保は動的に行われません。
※2 複数のパラダイム(プログラミングの考え方やルール、記述方法などの枠組み)に対応するプログラミング言語のことで、Rustは手続き型プログラミング,関数型プログラミング,オブジェクト指向プログラミングといった複数のパラダイム特性を持ちます。

3.環境構築

 TinyGoでは、簡単に環境構築するためにDockerイメージが提供されています。今回はそのDockerイメージを使い、HiFive1 RevBボードで動作するLチカ(LEDがチカチカ点滅する)プログラムを作成し、実際に動かしてみます。

3.1.用意するもの

 今回も、RISC-V技術ブログ連載第24回でお伝えした開発環境を引き続き利用します。追加で必要となるハードウェアおよびソフトウェアを以下に示します(※3)。

  • ハードウェア
    HiFive1 RevBボード
    USBケーブル(Type-A – micro-B)
  • ソフトウェア
    Docker version 23.0.3, build 3e7cbfd

※3 インターネット接続ができることを前提としており、そのための環境についての説明は省きます。

3.2.Dockerのインストール

 TinyGOは開発環境一式がDockerイメージで提供されているため、Dockerを用いることで容易に環境構築を行うことができます。Windows上で手軽にDockerを利用する手段として、Docker Desktopというツールが用意されていますが、Docker Desktopは2021年より商用利用の際には有料になってしまい、お手軽に使えるものではなくなりました。今回はVirtualBoxで構築したUbuntu上でDocker Engineを使うことにします。

 aptレポジトリを使ってDockerをインストールします。Ubuntu上で以下のコマンドを実行します。

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
apt-cache policy docker-ce
sudo apt install docker-ce
sudo systemctl status docker

 

3.3.共有フォルダの用意

 HiFive1 RevBボードへのプログラムの書き込みは、Windows上の操作で行うことにします。そのため、VitrualBoxのUbuntu上からWindows上へプログラムを転送するための共有フォルダを用意します。

  • Windowsでの作業
    “c:\share”フォルダを作成します。
  • VirtualBoxでの作業
    以下の画像のように[共有フォルダー]の設定を行います。
VirtualBoxでの[共有フォルダー]の設定
  • Ubuntuでの作業
    以下のコマンドを実行し、vboxsfグループにユーザー(この場合はubuntuユーザー)を追加します。
sudo adduser ubuntu vboxsf

4.HiFive1 RevBボードによるLチカプログラムの実行

 環境構築ができたので、ここからはHiFive1 RevBボードでLチカプログラムを動かす手順についてご説明します。

4.1.Lチカプログラムの作成

 以下に示すようなLチカプログラムを作成します。

package main

import (
	"machine"
	"time"
)

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

 VirtualBoxのUbuntu上にsampleディレクトリを作成し、そこにこのプログラムを、”sample.go”というファイル名で保存します。 

4.2.ビルド

 以下に示すような手順でDockerを起動し、ビルドします。

#Docker起動
sudo docker run -it -v $PWD:/src tinygo/tinygo:latest /bin/bash
cd /src/sample
#Goモジュール設定
go mod init sample
go mod tidy
#ビルド
tinygo build -target=hifive1b -o sample.hex
#docker終了

 ビルドが無事完了すると、”sample.hex”というHiFive1 Revボード上で実行可能なファイルができあがるので、ubuntu上の操作で共有フォルダへコピーします。

cp sample/sample.hex /mnt/share/.

4.3.Lチカプログラムの実行

 HiFive1 RevBボードとPCをUSBケーブルで接続します。すると、以下のようなHiFiveフォルダがWindows上に現れます。

HiFiveフォルダ

 HiFive1 RevBボードは、このHiFiveフォルダにドラッグ&ドロップすることでプログラムを内蔵Flashメモリへ書き込み、実行する便利な機能が用意されています。では、ここにWindows上で作成したフォルダ”c:\share”にある”sample.hex”をドラッグ&ドロップしてみます。

 しばらく待つと、以下の画像のようにHiFive1 RevBボード上のLEDが1秒ごとに点灯、消灯を繰り返し点滅(Lチカ)する動作を確認することができます。

Lチカの様子

4.4.おまけ

 実は今回使用したDockerイメージにはあらかじめいくつものサンプルプログラム(※4)のソースコードが含まれており、それらをビルド、実行することでより簡単に動作確認を行うことができます。例えば、blink2というサンプルプログラムをビルドするには、Ubuntu上で以下のようにします。

#Docker起動
sudo docker run -it -v $PWD:/src tinygo/tinygo:latest /bin/bash
cd /src
#ビルド
tinygo build -target=hifive1b -o blink2.hex examples/blinky2
#docker終了
exit

 ビルドが無事完了すると、”blink2.hex”というHiFive1 Revボード上で実行可能なファイルができあがるので、引き続きubuntu上の操作で共有フォルダへコピーします。

cp blink2.hex /mnt/share/.

 次に、前項で説明した方法で、HiFiveフォルダへドラッグ&ドロップすると以下の画像のように先ほどとは異なるパターンでLEDが点灯するLチカ動作を確認することができます。

blink2実行の様子

※4 こちらでサンプルプログラムを確認することができます

5.まとめ

 いかがでしたでしょうか。今回はRustと並んで組込みシステムやマイクロコントローラ向け言語として注目度の高いTinyGoを取り上げ、手軽にRISC-Vボードで動作確認ができる様子をお伝えしました。次回は、RISC-Vを含むSoC環境を構築することができるLiteXについてお伝えする予定です。ご期待ください!

 本ブログについてのより詳しい内容のご質問は、こちらまでお問合せください。
   info-lsi@dts-insight.co.jp

著作権および商標
Linux は、Linus Torvalds の米国およびその他の国における登録商標です。
Ubuntuは、Canonical Ltd.の商標または登録商標です。
VirtualBox は、Oracle VM VirtualBox の略です。
Oracle VM VirtualBox は、Oracle Corporation の登録商標です。
QEMUはFabrice Bellard氏の登録商標です
その他、本ブログに記載する製品名は、一般に各開発メーカーの商標または登録商標です。
なお、本文中には™ および ® マークは表記していません。

■■DTSインサイトの「システムLSI設計ソリューションサービス」■■
 DTSインサイトでは、システムLSI/FPGA設計の受託も行っています。
 当社のノウハウを活かした、ソフトウェアの移行(マイグレーション)
 サービスも提供しておりますので、お気軽にご相談ください。

システムLSI設計ソリューションサービス紹介は こちら