TinyGo 报错 unsupported compiler 因其是独立编译器,不支持 //go:build 等指令且标准库被裁剪;需用 tinygo build -target 指定硬件平台,避免 os/net 等包,并正确配置 Pin 和 UART。

tinygo build 为什么报错 unsupported compiler
因为 TinyGo 不是 Go 的子集或插件,而是完全独立的编译器——它不调用 go build,也不读取 go.mod 里的某些语义(比如 //go:embed、//go:build 条件编译行在部分 target 下被忽略)。你用 go build 能过的代码,tinygo build 很可能直接失败。
常见错误现象:error: unsupported compiler directive: //go:build 或 undefined: os.Stdout;本质是标准库被裁剪了,os、net、fmt 等包在 bare-metal target(如 arduino、atsamd21)里默认不可用。
- 用
tinygo build -target=arduino -o firmware.hex main.go替代go build - 避免导入
os、log、net/http等依赖系统调用的包;改用machine包操作 GPIO、UART - 字符串格式化优先用
fmt.Printf(仅当 target 支持 UART 时),但更稳妥的是unsafe.String+ 手动写串口寄存器,或用machine.Serial.Write() - 检查
tinygo targets输出,确认你的芯片型号有对应 target(比如 ESP32-C3 是esp32c3,不是esp32)
machine.Pin.Configure 怎么设置推挽输出和上拉输入
machine.Pin 是 TinyGo 对硬件引脚的抽象,但配置逻辑和 Arduino 的 pinMode() 不同:它必须显式调用 Configure(),且参数组合容易错。
典型场景:点亮 LED(推挽输出)、读按键(上拉输入+下降沿检测)。
立即学习“go语言免费学习笔记(深入)”;
- 推挽输出:
led.Configure(machine.PinConfig{Mode: machine.PinOutput});之后用led.High()/led.Low() - 上拉输入:
button.Configure(machine.PinConfig{Mode: machine.PinInputPullup});注意不是PinInput+ 外部电阻——PinInputPullup才启用内部上拉 - 有些芯片(如 RP2040)还支持
PinInputPulldown,但 ATSAMD 系列不支持,硬配会静默失效 - 配置必须在
main()开头做,不能在函数内重复调用 Configure —— 多数 target 不允许运行时重配模式
怎么把程序烧录到 STM32F4 Discovery 板
TinyGo 默认不生成可直接烧录的 .bin 或 .hex,而且 STM32F4 Discovery 没有原生 CDC/DFU,得靠 ST-Link 或 OpenOCD。
关键不是“能不能编译”,而是“生成什么格式”和“用什么工具刷”。漏掉任一环都会卡在“板子没反应”。
- 先生成裸机二进制:
tinygo build -target=stm32f4disco -o firmware.bin -x main.go(-x表示不链接启动文件,由 target 自带) - 确认
firmware.bin起始地址对齐:STM32F4 的 Flash 通常从0x08000000开始,TinyGo target 已预设,不用手动加-ldflags="-Ttext=0x08000000" - 用
openocd烧录:openocd -f interface/stlink-v2-1.cfg -f target/stm32f4x.cfg -c "program firmware.bin verify reset exit" - 如果用 ST-Link Utility,需转换格式:
arm-none-eabi-objcopy -O ihex firmware.bin firmware.hex,再拖入烧录
为什么 UART 打印没输出,但 LED 能亮
能亮灯说明程序跑起来了,UART 没输出大概率是串口引脚、时钟、或初始化顺序错了——不是代码逻辑问题,而是硬件映射没对上。
尤其在非开发板(比如自定义 PCB)上,TX/RX 引脚容易接错,而 TinyGo 不做引脚复用自动协商。
- 查 target 文档确认默认 UART 引脚:例如
stm32f4disco用PA9/PA10(USART1),不是 PB6/PB7;arduino-uno实际走machine.Serial对应PD0/PD1 - 确保调用
machine.Serial.Configure(),哪怕只传空结构体:machine.Serial.Configure(machine.UARTConfig{});不调用则寄存器保持复位值,发不出数据 - 波特率不匹配很隐蔽:
machine.Serial.Configure(machine.UARTConfig{BaudRate: 115200})必须和串口工具一致;STM32 在 HSE=8MHz 下,115200 容易有 ±3% 误差,换 9600 更稳 - 某些 target(如
feather-m0)的Serial其实是 USB CDC,不是 UART——此时要插 USB 线,且设备识别为/dev/cu.usbmodem*,不是/dev/ttyUSB*
最常被忽略的是:UART 初始化必须在所有其他外设(尤其是 SysTick 或定时器)之前完成。一旦中断提前使能,串口发送可能被挂起,且无错误提示。


















