• Stars
    star
    1,031
  • Rank 42,897 (Top 0.9 %)
  • Language
    C
  • License
    BSD 3-Clause "New...
  • Created almost 10 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Emgo: Bare metal Go (language for programming embedded systems)

Emgo

Emgo consist of a compiler and the set of packages that allows you to run Go programs on small 32-bit microcontrollers. The compiler generates C as an intermediate code and uses C compiler to produce loadable binaries.

There is Embedded Go project that evolved from Emgo which is based on the reference Go compiler. It has much higher hardware requirements but it is also 100% compatible with the Go language specification. The main development process has moved to Embeadded Go but I still use Emgo for small MCUs so some things can be backported here.

How to start

First of all, to try Emgo you need the Go compiler installed. The current Emgo compiler and whole process described below requires also some kind of Unix-like operating system. There is a chance that Windows with Cygwin can be used but this was not tested.

You can probably use go get to install Emgo but the preferred way is to clone this repository using the git command:

git clone https://github.com/ziutek/emgo.git

Next you need to build and install egc (Emgo compiler):

cd emgo/egc
go install

For now, Emgo supports only ARM Cortex-M based MCUs. To build code for Cortex-M architecture, you need to install ARM embedded toolchain. You have two options: install a package included in your OS distribution (in case of Debian/Ubuntu Linux):

apt-get install gcc-arm-none-eabi

or better go to the GNU ARM Embedded Toolchain website and download most recent toolchain. This is preferred version of toolchain, try use it before report any bug with compilation.

Installed toolchain contains set of arm-none-eabi-* binaries. Find their location and set required enviroment variables:

export EGCC=path_to_arm_gcc            # eg. /usr/local/arm/bin/arm-none-eabi-gcc
export EGLD=path_to_arm_linker         # eg. /usr/local/arm/bin/arm-none-eabi-ld
export EGAR=path_to_arm_archiver       # eg. /usr/local/arm/bin/arm-none-eabi-ar

export EGROOT=path_to_egroot_directory # eg. $HOME/emgo/egroot
export EGPATH=path_to_egpath_directory # eg. $HOME/emgo/egpath

Load/debug helper scripts use also some other tools from the ARM toolchain (eg. arm-none-eabi-objcopy). If you downloaded the toolchain manually, you probably need also to add its bin directory to the PATH enviroment variable:

export PATH=$PATH:path_to_arm_bin_dir  # eg. /usr/local/arm/bin

Now you are ready to compile some example code. There are two directories that contain examples:

$EGPATH/src/stm32/examples

$EGPATH/src/nrf5/examples

Use one that contains example for your MCU/devboard.

For example, to build blinky for STM32 NUCLEO-F411RE board:

cd $EGPATH/src/stm32/examples/nucleo-f411re/blinky
../build.sh

The first compilation may take some time because egc must process all required libraries and runtime. If everything went well you obtain cortexm4f.elf binary file.

Compilation can produce two kind of binaries: binaries that should be loaded to RAM or loaded to Flash of your MCU.

Loading to RAM is useful in case of small programs, during working on the code and debuging. Loading to RAM is faster, allows unlimited number of breakpoints, allows to modify constants and even the code from debuger and saves your Flash, which has big but limited number of erase cycles.

To run program loaded to RAM you must change the MCU boot behavior. In case of most STM32 MCUs you simply need to set high BOOT0 and BOOT1 pins. Newer STM32 MCUs do not provide BOOT1 pin, insdead they require to program some persistant bits that change the default booting behavior when BOOT0 is set high.

However, eventually your program should be loaded to Flash. Sometimes you have no other alternative: your program is too big to fit into RAM or your MCU does not provide easy way to run program from RAM (eg. nRF51). Some bugs may only appear when the program runs from Flash or from RAM, so it is advisable to perform the final test of any new piece of code in both ways.

You need tools to load compiled binary to your MCU's RAM/Flash and allow to debug it. Such tools usually have a hardware part and a software part. In case of STM32 Nucleo or Discovery development boards the hardware part (ST-LINK programmer) is integrated with the board, so you only need the software part, which can be OpenOCD or Texane's stlink. You must install one of them or both before next steps (ensure that openocd and/or st-util binaries are on your PATH).

There is a set of scripts for any board in example directory that simplifies loding and debuging process. The load-oocd.sh and swo-oocd.sh scripts can handle SWO output from ITM (Instrumentation Trace Macrocell) but needs itmsplit to convert binary stream to readable messages. SWO is very useful for debuging and fmt.Print* functions by default use ITM trace port as standard output. Install itmsplit with the command:

go get github.com/ziutek/itmsplit

and ensure that produced binary is in your PATH.

You need the rights to the USB device that corresponds to your programming hardware. This can be done through adding appropriate udev rules. See example rules in Texane's stlink repository, in etc directory.

To program your MCU using Texane's stlink run:

../load-stutil.sh

If you want to use OpenOCD, run:

../load-oocd.sh

Some examples by default are configured to run from RAM. If you have problem to setup your board to run from RAM, edit script.ld file and change the line:

INCLUDE stm32/loadram

to

INCLUDE stm32/loadflash

More editing is need for STM32F1xx series: you additionally have to comment two lines:

bootOffset = 0x1E0;
ENTRY(bootRAM)

You can also load your program during debug session in gdb. Run ../debug-stutil.sh or ../debug-oocd.sh and next invoke load command.

There are also scripts for Black Magic Probe: load-bmp.sh, debug-bmp.sh.

If you played with examples and enjoyed Emgo you probably want to write your first program from scratch, compile it and load without all these magical scripts. This blog post presents how to do it.

You may encounter a problem where st-util or openocd can not connect to your board. This is often the case for boards without integrated programmer/debuger, when the external programmer has no connection to the reset pin. If you can not make such connection, simply press and hold the reset button on your board, next run load/debug script and after the script finishes printing anything, release the reset.

Documentation

Standard library

Libraries for STM32, nRF5 and other

Other resources

Blog

YouTube

Forum

More Repositories

1

mymysql

MySQL Client API written entirely in Go
Go
727
star
2

gst

Go bindings for GStreamer (retired: currently I don't use/develop this package)
Go
168
star
3

blas

Go implementation of BLAS (Basic Linear Algebra Subprograms)
Assembly
149
star
4

rrd

Bindings to rrdtool
Go
146
star
5

telnet

Package to handle a telnet connection
Go
134
star
6

dvb

DVB/MPEG-TS library (pure Go)
Go
90
star
7

kasia.go

Templating system for HTML and other text documents - go implementation
Go
74
star
8

syslog

With this package you can create your own syslog server with your own handlers for different kind of syslog messages
Go
66
star
9

mdtwm

Mouse-driven Tiling Window Manager
Go
63
star
10

simple_go_wiki

Tutorial which explain how to write the database-driven Web application using kasia.go, kview and mymysql
Go
46
star
11

glib

Go bindings for GLib type system.
Go
24
star
12

web_bench

Benchmarking Go and Python Web servers
Python
24
star
13

ftdi

Go binding for libFTDI
C
24
star
14

soap

Some SOAP related functions.
Go
21
star
15

hiperus

Hiperus API in Go (http://devel.hiperus.pl/)
Go
18
star
16

gogammu

Go binding for gammu
Go
15
star
17

serial

Serial ports handlig
Go
14
star
18

utils

Useful tools
Go
10
star
19

kview

Simple wrapper for kasia.go templates. I write all my web apps using this package
Go
9
star
20

de

Differential evolution optimization library
Go
8
star
21

matrix

Matrix library for Go
Go
7
star
22

plan9

Plan9 / p9p related stuff
Shell
5
star
23

tuntap

Simple ptp tunnel with AES encryption that uses TUN or TAP device.
Go
4
star
24

gtk

Example Go bindings for GTK
Go
4
star
25

agf

gofmt/indent in acme window (supports Go, C/C++, Java, assembler)
Go
3
star
26

usbread

Utility that allows to read from USB bulk endpoint
Go
3
star
27

pyview

kview counterpart for web.py templates
Python
3
star
28

arm-none-eabi

GNU ARM Embedded Toolchain for Linux/ARM64
3
star
29

avt414

AVT414 USB I/O card (http://ep.com.pl/files/4241.pdf)
Go
3
star
30

vimrc

My vim configuration files
Vim Script
2
star
31

ummmalloc

Go
2
star
32

wakeonlan

Simple wake on lan command
Go
2
star
33

eagle

Go API for original it950x driver.
C
2
star
34

ft8xx

Proof of concept Go driver to FTDI FT800 embedded video engine
Go
1
star
35

basic_fpga

Python
1
star
36

ziutek.github.io

HTML
1
star
37

kbdstat

Key hit statistic for X11
Python
1
star
38

nrf

Go library for nRF24L01(+) transceivers
Go
1
star
39

rysunki_dom

1
star
40

cutils

C
1
star
41

itmsplit

Parses output from ARM ITM and splits it to multiple files.
Go
1
star
42

textenc

textenc provides functions to decode non-UTF8 text strings
Go
1
star
43

thread

For manage OS thread parameters
Go
1
star
44

WinISD

Drivers and projects
Gnuplot
1
star
45

gdk

Go
1
star
46

genie_echo_server

Simple threaded echo server written in Genie language
Vim Script
1
star
47

charstat

Counts UTF-8 runes in specified directories
Go
1
star
48

crypto

Simple encryption algorithms for Go
Go
1
star