Go 语言在极小硬件上的运用(二)( 二 )

我没有将 NRST 信号连接到编程器 , 因此无法使用 -reset 选项 , 必须按下复位按钮才能运行程序 。
Go 语言在极小硬件上的运用(二)文章插图
Interfaces
看来 , st-flash 与此板配合使用有点不可靠(通常需要复位 ST-LINK 加密狗) 。 此外 , 当前版本不会通过 SWD 发出复位命令(仅使用 NRST 信号) 。 软件复位是不现实的 , 但是它通常是有效的 , 缺少它会将会带来不便 。 对于 板卡程序员(board-programmer) 来说 OpenOCD 工作得更好 。
UARTUART( 通用异步收发传输器(Universal Aynchronous Receiver-Transmitter))仍然是当今微控制器最重要的外设之一 。 它的优点是以下属性的独特组合:

  • 相对较高的速度 ,
  • 仅两条信号线(在 半双工(half-duplex) 通信的情况下甚至一条) ,
  • 角色对称 ,
  • 关于新数据的 同步带内信令(synchronous in-band signaling)(起始位) ,
  • 在传输 字(words) 内的精确计时 。
这使得最初用于传输由 7-9 位的字组成的异步消息的 UART , 也被用于有效地实现各种其他物理协议 , 例如被 WS28xx LEDs 或 1-wire 设备使用的协议 。
但是 , 我们将以其通常的角色使用 UART:从程序中打印文本消息 。
package mainimport ("io""rtos""stm32/hal/dma""stm32/hal/gpio""stm32/hal/irq""stm32/hal/system""stm32/hal/system/timer/systick""stm32/hal/usart")var tts *usart.Driverfunc init() {system.SetupPLL(8, 1, 48/8)systick.Setup(2e6)gpio.A.EnableClock(true)tx := gpio.A.Pin(9)tx.Setup( --tt-darkmode-color: #7777BB;">请勿使用 RS232 端口或 USB 转 RS232 转换器!
STM32 系列使用 3.3V 逻辑 , 但是 RS232 可以产生 -15 V ~ +15 V 的电压 , 这可能会损坏你的 MCU 。 你需要使用 3.3V 逻辑的 USB 转 UART 转换器 。 流行的转换器基于 FT232 或 CP2102 芯片 。
Go 语言在极小硬件上的运用(二)文章插图
UART
你还需要一些终端仿真程序(我更喜欢 picocom ) 。 刷新新图像 , 运行终端仿真器 , 然后按几次复位按钮:
$ openocd -d0 -f interface/stlink.cfg -f target/stm32f0x.cfg -c 'init; program cortexm0.elf; reset run; exit'Open On-Chip Debugger 0.10.0+dev-00319-g8f1f912a (2018-03-07-19:20)Licensed under GNU GPL v2For bug reports, readdebug_level: 0adapter speed: 1000 kHzadapter_nsrst_delay: 100none separateadapter speed: 950 kHztarget halted due to debug-request, current mode: ThreadxPSR: 0xc1000000 pc: 0x080016f4 msp: 0x20000a20adapter speed: 4000 kHz** Programming Started **auto erase enabledtarget halted due to breakpoint, current mode: ThreadxPSR: 0x61000000 pc: 0x2000003a msp: 0x20000a20wrote 13312 bytes from file cortexm0.elf in 1.020185s (12.743 KiB/s)** Programming Finished **adapter speed: 950 kHz$$ picocom -b 115200 /dev/ttyUSB0picocom v3.1port is: /dev/ttyUSB0flowcontrol: nonebaudrate is: 115200parity is: nonedatabits are: 8stopbits are: 1escape is: C-alocal echo is: nonoinit is: nonoreset is: nohangup is: nonolock is: nosend_cmd is: sz -vvreceive_cmd is : rz -vv -Eimap is:omap is:emap is: crcrlf,delbs,logfile is: noneinitstring: noneexit_after is: not setexit is: noType [C-a] [C-h] to see available commandsTerminal readyHello, World!Hello, World!Hello, World!每次按下复位按钮都会产生新的 “Hello , World!”行 。 一切都在按预期进行 。
要查看此 MCU 的 双向(bi-directional) UART 代码 , 请查看 此示例。
io.Writer 接口io.Writer 接口可能是 Go 中第二种最常用的接口类型 , 仅次于 error 接口 。 其定义如下所示:
type Writer interface {Write(p []byte) (n int, err error)}usart.Driver 实现了 io.Writer , 因此我们可以替换:
tts.WriteString("Hello, World!\r\n")
io.WriteString(tts, "Hello, World!\r\n")此外 , 你需要将 io 包添加到 import 部分 。
io.WriteString 函数的声明如下所示:
func WriteString(w Writer, s string) (n int, err error)如你所见 , io.WriteString 允许使用实现了 io.Writer 接口的任何类型来编写字符串 。 在内部 , 它检查基础类型是否具有 WriteString 方法 , 并使用该方法代替 Write(如果可用) 。
让我们编译修改后的程序:
$ egc$ arm-none-eabi-size cortexm0.elftextdatabssdechex filename15456320248160243e98 cortexm0.elf如你所见 , io.WriteString 导致二进制文件的大小显着增加:15776-12964 = 2812 字节 。Flash 上没有太多空间了 。 是什么引起了这么大规模的增长?
使用这个命令:
arm-none-eabi-nm --print-size --size-sort --radix=d cortexm0.elf我们可以打印两种情况下按其大小排序的所有符号 。 通过过滤和分析获得的数据(awk , diff) , 我们可以找到大约 80 个新符号 。 最大的十个如下所示: