Go was designed at Google in 2007, the evolution of this language is tremendous. Nowadays we are almost can create any kind of application using Go, from API, tooling, game, library, and so on. So how about the embedded system or today hot term as IoT, can we use Golang for this kind of application? The answer is yes, we can.
We never expected Go to be an embedded language and so its got serious problems…
— Rob Pike, GopherCon 2014 Opening Keynote
We can use Go as the embedded language to create an application for an embedded system, the differences between embedded application and non-embedded application are :
There is a tool, TinyGo (https://github.com/tinygo-org/tinygo), which will be used in this article for us to compiling and flashing Go code into the microcontroller.
Let’s begin creating our first application using Go. The most common practice for creating or using a programming language for the first time and in all programming books is creating a “Hello World” program.
The “Hello world” program is considered to be the simplest kind of program that can be written. The purpose is to verify that you can write any kind of program at all. So let’s begin…
In this article, we are assuming :
Go is installed and configured, if not you can follow the instructions from https://golang.org/doc/install on how to install and configuring Go on your OS.TinyGo is installed, if not you can follow the instructions from https://tinygo.org/getting-started/ on how to install tinygo on your OS.
Create a project name “hello” in “examples” namespace of our Go workspace. The project structure will be like this
[src]
|-- [examples]
|-- [hello]
|--- main.go
Our first “Hello World” program in Go.
package main
import "fmt"
func main() {
fmt.Println("Hello tiny world")
}
Let’s explain the code line-by-line,
package main
A package in the Go programming language is the way that you organize code, that is intended to be kept together and used as a single unit. We also tell Go the name of the package that the rest of our code in that file belongs to. In this case, the “main” package.
func main()
In the Go language, the keyword func means that the program is defining a function, which consists of one or more lines of code that will be executed one by one in order when the function is called on. We named our function “main” to tell the compiler what to start doing first when running that program.
fmt.Println("Hello tiny world")
We use the Println() function to output a message, on Go language it will be printed or outputted to console. But since we compile it to use on a microcontroller which it does not have one, so the output will be sent to the serial port or UART of the microcontroller.
Compiling “Hello World” program same as compiling another Go code, the difference here we compile the code using tinygo tool rather than using go tools
To compile the code just simply run below command
$ tinygo build -o main.go
The command build tell the tools that we want to compile Go code, the -o flags define the output file (if any) and the input file of Go code that wants to compile. If we do not define the output file then it will be created with the same name as the Go code, in this case, main.go.
After the compile process success, there will be an executable file created
$ ls
main main.go
If we want to compile our code using a different name, we can simply run below command
$ tinygo build -o hello main.go
Above command will create a file hello which is the executable file of main.go.
In the above code, we only use “fmt” Go standard library, so it’s mean we can compile the code and run under terminal. But if we use specific API in tinyGo then we can’t compile using the command above, we have to add specified target board in our compile command.
Create another file name “LED.go”
package main
import (
"machine"
"time"
)
// start here at main function
func main() {
go blink(machine.LED1, 1000 * time.Millisecond)
go blink(machine.LED2, 750 * time.Millisecond)
}
// blink the LED with given duration
func blink(led machine.Pin, delay time.Duration) {
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
for {
led.Low()
time.Sleep(delay)
led.High()
time.Sleep(delay)
}
}
Above program can be compiled and run without modification on an Arduino Uno, an Adafruit ItsyBitsy M0, or any of the supported boards that have a built-in LED, just by setting the correct TinyGo compiler target. We can also run the code on tinyGo playground as seen below.
The tinyGo compiler will raise an error if we not set specified target board when compiling the code.
So to compile “LED.go”, we have to add target board when executing build command.
But as because we have specified the target board for the compiled program, we can’t run the program anymore under terminal because executable have specified target architecture (eg : Linux, Darwin, Windows, ARM, etc..)
To run the executable file, we have to “flash” it into microcontroller board.
Running the program on a microcontroller, you need to compile the program for that kind of board into a binary file, and then transfer that binary file onto the microcontroller.
Before we running the program we have to make sure the board is plugged into your computer’s USB port, and if we use for example Arduino Nano33, double click the “Reset” button on the board and finally run the following command :
<span id="dd68" class="jf hs ee bd pg b bv ph pi s pj" data-selectable-paragraph="" style="box-sizing: inherit; font-weight: 400; display: block; font-style: normal; font-size: 16px; color: rgba(0, 0, 0, 0.84); letter-spacing: -0.022em; line-height: 1.18; font-family: Menlo, Monaco, "Courier New", Courier, monospace; margin-top: -0.09em; margin-bottom: -0.09em; white-space: pre-wrap;">tinygo flash -target arduino-nano33 ./examples/hello/LED.go</span>
The command tinygo flash first uses the compiler to build a temporary binary file which is the executable version of that program before it uploads to whichever microcontroller is specified as the target. The microcontroller must be connected to the computer for the compiled program to be transferred to the microcontroller board.
However, there may be slight differences to flash a specific kind of microcontroller board. See the page https://tinygo.org/microcontrollers/ on the TinyGo website for details on how to flash any other kind of currently supported board.
References