golang嵌入式系统开发语言插件库emgo的使用

Golang嵌入式系统开发语言插件库Emgo的使用

Emgo简介

Emgo包含一个编译器和一组包,允许你在小型32位微控制器上运行Go程序。该编译器生成C作为中间代码,并使用C编译器生成可加载的二进制文件。

如何开始

准备工作

  1. 首先需要安装Go编译器
  2. 当前Emgo编译器和整个流程需要类Unix操作系统支持(Windows+Cygwin可能可用但未经测试)

推荐使用git克隆仓库:

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

安装egc(Emgo编译器)

cd emgo/egc
go install

安装ARM嵌入式工具链

Emgo目前仅支持基于ARM Cortex-M的MCU。你需要安装ARM嵌入式工具链:

对于Debian/Ubuntu Linux:

apt-get install gcc-arm-none-eabi

或者从GNU ARM Embedded Toolchain网站下载最新工具链(推荐)。

设置环境变量

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

export EGROOT=path_to_egroot_directory # 例如$HOME/emgo/egroot
export EGPATH=path_to_egpath_directory # 例如$HOME/emgo/egpath

export PATH=$PATH:path_to_arm_bin_dir  # 例如/usr/local/arm/bin

示例项目

编译示例代码

示例代码位于:

  • $EGPATH/src/stm32/examples
  • $EGPATH/src/nrf5/examples

例如,为STM32 NUCLEO-F411RE开发板构建blinky示例:

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

首次编译可能需要一些时间,因为egc需要处理所有必需的库和运行时。成功编译后将生成cortexm4f.elf二进制文件。

加载和调试

你需要工具将编译后的二进制文件加载到MCU的RAM/Flash中并允许调试。对于STM32 Nucleo或Discovery开发板,可以使用OpenOCD或Texane的stlink。

安装itmsplit(用于处理SWO输出):

go get github.com/ziutek/itmsplit

使用Texane的stlink加载程序:

../load-stutil.sh

使用OpenOCD加载程序:

../load-oocd.sh

RAM与Flash加载

默认情况下,一些示例配置为从RAM运行。如果需要改为从Flash运行,编辑script.ld文件并修改:

INCLUDE stm32/loadflash

对于STM32F1xx系列,还需要注释两行:

// bootOffset = 0x1E0;
// ENTRY(bootRAM)

完整示例代码

以下是一个简单的STM32 LED闪烁示例:

package main

import (
    "delay"
    "stm32/hal/gpio"
    "stm32/hal/system"
    "stm32/hal/system/timer/systick"
)

var led gpio.Pin

func init() {
    system.SetupPLL(8, 1, 48/8)
    systick.Setup(2e6)

    gpio.A.EnableClock(false)
    led = gpio.A.Pin(5)

    cfg := &gpio.Config{Mode: gpio.Out, Driver: gpio.OpenDrain}
    led.Setup(cfg)
}

func main() {
    for {
        led.Clear()
        delay.Millisec(500)
        led.Set()
        delay.Millisec(500)
    }
}

文档资源

  • 标准库文档
  • STM32、nRF5等库文档

其他资源

  • 博客
  • YouTube频道
  • 论坛

更多关于golang嵌入式系统开发语言插件库emgo的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang嵌入式系统开发语言插件库emgo的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Emgo - Go语言嵌入式系统开发框架

Emgo是一个用于嵌入式系统开发的Go语言框架,它允许开发者使用Go语言语法来开发嵌入式应用程序。下面我将介绍Emgo的基本使用方法和示例代码。

Emgo简介

Emgo是专门为嵌入式系统设计的Go语言实现,它有以下特点:

  • 专为微控制器设计
  • 极小的内存占用
  • 直接硬件访问
  • 简洁的API设计

安装Emgo

  1. 首先安装Go语言环境
  2. 然后安装Emgo工具链:
go get -u github.com/ziutek/emgo

基本示例

1. 简单的LED闪烁程序

package main

import (
	"delay"
	"stm32/hal/gpio"
	"stm32/hal/system"
	"stm32/hal/system/timer/systick"
)

var led gpio.Pin

func init() {
	system.Setup(8, 1, 72/8) // 8 MHz外部晶振,PLL到72MHz
	systick.Setup()          // 配置SysTick定时器

	// 初始化GPIO
	gpio.A.EnableClock(false)
	led = gpio.A.Pin(5) // 通常PA5是板载LED

	// 配置LED引脚为输出模式
	cfg := &gpio.Config{Mode: gpio.Out, Speed: gpio.Low}
	led.Setup(cfg)
}

func main() {
	for {
		led.Set()      // 打开LED
		delay.Millisec(500)
		led.Clear()    // 关闭LED
		delay.Millisec(500)
	}
}

2. 使用UART通信

package main

import (
	"io"
	"stm32/hal/gpio"
	"stm32/hal/system"
	"stm32/hal/system/timer/systick"
	"stm32/hal/usart"
)

var (
	uart *usart.Driver
	tx   gpio.Pin
	rx   gpio.Pin
)

func init() {
	system.Setup(8, 1, 72/8)
	systick.Setup()

	// 初始化UART引脚
	gpio.A.EnableClock(true)
	tx = gpio.A.Pin(9)
	rx = gpio.A.Pin(10)

	// 配置UART引脚
	tx.Setup(&gpio.Config{Mode: gpio.Alt})
	rx.Setup(&gpio.Config{Mode: gpio.AltIn, Pull: gpio.PullUp})
	
	// 初始化UART
	uart = usart.USART1
	uart.EnableClock(true)
	uart.SetBaudRate(115200)
	uart.SetConf(usart.Word8b, usart.Stop1b, usart.NoParity, usart.NoFlowCtrl)
	uart.Enable()
}

func main() {
	// 发送欢迎消息
	io.WriteString(uart, "Hello from Emgo!\r\n")
	
	// 简单的回显程序
	var buf [1]byte
	for {
		n, err := uart.Read(buf[:])
		if err == nil && n == 1 {
			uart.Write(buf[:])
		}
	}
}

3. 使用PWM控制LED亮度

package main

import (
	"delay"
	"stm32/hal/gpio"
	"stm32/hal/pwm"
	"stm32/hal/system"
	"stm32/hal/system/timer/systick"
)

var (
	pwmChannel *pwm.Channel
)

func init() {
	system.Setup(8, 1, 72/8)
	systick.Setup()

	// 初始化PWM引脚
	gpio.A.EnableClock(true)
	pin := gpio.A.Pin(8) // 通常TIM1_CH1在PA8
	
	// 配置PWM引脚
	pin.Setup(&gpio.Config{Mode: gpio.Alt, Speed: gpio.High})

	// 初始化PWM
	tim := pwm.TIM1
	tim.EnableClock(true)
	pwmChannel = tim.Channel(1) // 通道1
	
	// 配置PWM
	tim.Setup(pwm.CenterAligned | pwm.Up, 1000, 0) // 1kHz PWM频率
	pwmChannel.SetPolarity(pwm.High)
	pwmChannel.Enable()
	tim.Enable()
}

func main() {
	for {
		// 渐亮
		for i := 0; i <= 1000; i += 10 {
			pwmChannel.SetCompare(i)
			delay.Millisec(10)
		}
		
		// 渐暗
		for i := 1000; i >= 0; i -= 10 {
			pwmChannel.SetCompare(i)
			delay.Millisec(10)
		}
	}
}

Emgo的优势

  1. 内存效率:Emgo专为资源受限的嵌入式系统设计,运行时占用内存极小
  2. 直接硬件访问:提供直接访问寄存器的能力,无需复杂的抽象层
  3. 并发支持:利用Go语言的goroutine实现轻量级并发
  4. 丰富的硬件支持:支持多种STM32系列微控制器

注意事项

  1. Emgo目前主要支持STM32系列微控制器
  2. 由于嵌入式系统的限制,不是所有Go语言特性都可用
  3. 需要仔细管理内存使用,避免动态内存分配

Emgo为嵌入式开发者提供了一种使用Go语言进行开发的途径,结合了Go语言的简洁性和嵌入式系统的实时性要求。

回到顶部