This can be very useful for some purposes:
* It makes it possible to disable the UART in cases where it is not
needed or needs to be disabled to conserve power.
* It makes it possible to disable the serial output to reduce code
size, which may be important for some chips. Sometimes, a few kB can
be saved this way.
* It makes it possible to override the default, for example you might
want to use an actual UART to debug the USB-CDC implementation.
It also lowers the dependency on having machine.Serial defined, which is
often not defined when targeting a chip. Eventually, we might want to
make it possible to write `-target=nrf52` or `-target=atmega328p` for
example to target the chip itself with no board specific assumptions.
The defaults don't change. I checked this by running `make smoketest`
before and after and comparing the results.
Instead of specifying explicit commands, most of these commands have
been replaced by more specific properties.
This is work that will be necessary for an eventual -programmer flag to
the compiler, with which it is possible to select which programmer to
use to flash or debug a chip. That's not very useful for boards that
already include a programmer or bootloader for that purpose, but is very
useful for novel boards or single-purpose boards that are not already
included in TinyGo.
This avoids a ton of duplication and makes it easier to change a generic
target (for example, the "cortex-m" target) for all boards that use it.
Also, by making it possible to inherit properties from a parent target
specification, it is easier to support out-of-tree boards that don't
have to be updated so often. A target specification for a
special-purpose board can simply inherit the specification of a
supported chip and override the properites it needs to override (like
the programming interface).
Let the standard library think that it is compiling for js/wasm.
The most correct way of supporting bare metal Cortex-M targets would be
using the 'arm' build tag and specifying no OS or an 'undefined' OS
(perhaps GOOS=noos?). However, there is no build tag for specifying no
OS at all, the closest possible is GOOS=js which makes very few
assumptions.
Sadly GOOS=js also makes some assumptions: it assumes to be running with
GOARCH=wasm. This would not be such a problem, just add js, wasm and arm
as build tags. However, having two GOARCH build tags leads to an error
in internal/cpu: it defines variables for both architectures which then
conflict.
To work around these problems, the 'arm' target has been renamed to
'tinygo.arm', which should work around these problems. In the future, a
GOOS=noos (or similar) should be added which can work with any
architecture and doesn't implement OS-specific stuff.
This is kind of dirty with that huge list of linker params, but it works
and it produces smaller object files (probably because GCC is better
optimized for size).