探索TinyGo在arduino开发板
TinyGo是一款专为嵌入式系统和WebAssembly设计的Go编译器,因其优化了小代码体积和降低内存使用,使得Go语言能够在资源受限的环境中运行,例如微控制器和WebAssembly平台。这使得TinyGo成为物联网(IoT)和嵌入式系统应用开发的理想选择。
什么是 TinyGo?
TinyGo 不是一种新的编程语言,而是 Go 的一个轻量级编译器。它的目标是允许开发者在受限设备(如微控制器和嵌入式系统)以及 WebAssembly 上运行 Go 代码。TinyGo 通过使用 LLVM 后端生成更小的二进制文件,以适应内存、存储空间都非常有限的硬件环境。
举个例子,使用 Go 编写一个简单的 "Hello World" 程序可能生成一个约 800KB 的二进制文件,而通过 TinyGo 编译,同样的代码可以缩小到 10KB 左右。因此,TinyGo 非常适合在 Arduino、Raspberry Pi 等小型设备上运行 Go 代码,而这些平台往往无法支持标准的 Go 编译器。
尝试 TinyGo实现一个闪烁的LED(官方示例)
// 您可以编辑此代码!
package main
import (
"machine"
"time"
)
func main() {
led := machine.LED
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
for {
led.High()
time.Sleep(time.Second/2)
led.Low()
time.Sleep(time.Second/2)
}
}
TinyGo 刷 esp8266
# 安装 TinyGo
curl -sSf https://raw.githubusercontent.com/tinygo-org/tinygo/master/scripts/install.sh | bash
# 安装 esptool
pip install esptool
# 编译 Go 代码
tinygo build --target=esp8266 -o main.bin .
# 使用 esptool 擦除 ESP8266
esptool.py --port /dev/ttyUSB0 erase_flash
# 烧录二进制文件到 ESP8266
esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 main.bin
TinyGo的特点包括:
- 高效编译:TinyGo针对小代码体积和降低内存使用进行了优化,适用于资源受限的环境。
- 微控制器支持:TinyGo支持在微控制器上运行Go代码,适合物联网和嵌入式系统的应用开发。
- WebAssembly兼容性:TinyGo支持WebAssembly,允许在Web浏览器中直接运行Go代码,将Go的应用范围扩展到客户端Web开发。
- 简化的运行时:TinyGo提供了为目标平台特别设计的简化运行时,减少了资源受限环境中的开销和不必要的功能。
- 激进的优化:TinyGo采用激进的优化策略,减少函数调用开销并消除无用代码,产生精简高效的可执行文件。
- Go标准库支持:TinyGo与Go的标准库和包生态系统兼容,允许开发者在他们的TinyGo项目中利用现有的Go库和工具。
TinyGo 与 Go 的区别
虽然 TinyGo 和 Go 共享相同的语言和生态系统,但两者的编译器在性能和特性上有所不同。
二进制大小
TinyGo 的一个显著优势是它生成的二进制文件非常小,尤其适合嵌入式系统和 WebAssembly 场景。在这些环境中,减少二进制文件的大小至关重要,因为这些系统通常有严格的存储和内存限制。
性能对比
虽然 TinyGo 能生成更小的二进制文件,但在某些性能场景下,TinyGo 可能无法与 Go 的标准编译器媲美。特别是在垃圾回收、反射以及标准库的支持上,TinyGo 做了一些取舍,来换取更小的占用空间和资源效率。例如:
- 垃圾回收:TinyGo 的垃圾回收在小型芯片(如 AVR)和 WebAssembly 上表现不佳,而且比标准 Go 的垃圾回收器慢得多。这在需要频繁内存分配的情况下,可能会带来性能瓶颈。
- 反射支持:TinyGo 对 Go 标准库中的 reflect 包支持有限,这意味着依赖反射的代码在 TinyGo 中可能无法正常工作。
- 全局变量优化:TinyGo 编译器在编译时会计算全局变量,减少启动时间并优化内存使用。而 Go 编译器则采用了不同的方式处理全局变量。
TinyGo 的特性与限制
使用 TinyGo 时,开发者需要注意它的一些特性和限制:
- Cgo 支持有限:虽然 TinyGo 允许使用 import "C" 进行 Cgo 调用,但某些功能可能不受支持或工作方式与 Go 不同。因此,依赖 Cgo 的项目需要进行额外的兼容性测试。
- 标准库不完全支持:由于 TinyGo 的目标环境较为特殊,并且某些标准库功能依赖 Go 的特定运行时,TinyGo 并不支持所有 Go 标准库。虽然可以编译大多数包,但在使用时要注意这些包的功能是否完全可用。
- 映射性能较低:TinyGo 对映射(map)的支持可能会比标准 Go 语言慢,尤其是在对复杂结构体进行比较时。因为某些类型可能会使用反射进行比较,这会增加时间开销。
TinyGo 的应用场景
TinyGo 的设计初衷是为了应对资源受限的嵌入式环境和 WebAssembly 场景。对于那些需要开发高效、轻量级程序的项目,TinyGo 是一个理想的选择。以下是 TinyGo 的几个典型应用场景:
- 嵌入式系统和物联网 (IoT)
嵌入式系统和 IoT 设备通常对内存和存储空间有极高的要求,而 TinyGo 的二进制文件小巧,能够在诸如 Arduino、ESP32 这类微控制器上运行。 - WebAssembly
TinyGo 可以将 Go 代码编译成 WebAssembly(WASM),这使得开发者能够在浏览器中运行 Go 代码,并且因为 TinyGo 生成的 WASM 文件体积小,加载速度快,性能表现优异,非常适合前端的微服务场景。 - 轻量级微服务
在需要低资源占用的微服务架构中,TinyGo 编写的服务可以占用更少的资源,特别是在资源紧张的环境中,TinyGo 能提供更好的部署灵活性。
TinyGo 的局限性
虽然 TinyGo 有许多优势,但它也有一些局限性:
- 较慢的垃圾回收:由于垃圾回收机制在 TinyGo 上的表现不如 Go,频繁的内存分配操作可能会导致性能下降。
- 部分标准库不支持:TinyGo 仍在积极开发中,某些标准库包未被完全支持,开发者在迁移现有 Go 项目时需要注意这一点。
- 编译速度:TinyGo 的编译速度比标准的 Go 编译器要慢,尤其是在启用了垃圾回收和复杂优化选项时。
结论
作者:漏网的鱼
链接:https://www.csev.cn/share/soft/20241205539.html
来源:彩色动力-测试分享
版权声明:本文欢迎任何形式转载,转载时完整保留本声明信息(包含原文链接、原文出处、原文作者、版权声明)即可。本文后续所有修改都会第一时间在原始地址更新。
共有 0 条评论