The system stack is only needed when we're not on it. So we can directly
call task.SystemStack() without problems.
This also saves a tiny bit of binary size.
This type can be used to jump back to a previous position in a program
from inside an interrupt. This is useful for baremetal systems that
implement wfi but not wfe, and therefore have no easy (race-free) way to
wait until a flag gets changed inside an interrupt. This is an issue on
RISC-V, where this is racy (the interrupt might happen after the check
but before the wfi instruction):
configureInterrupt()
for flag.Load() != 0 {
riscv.Asm("wfi")
}
Accessing the same variable from multiple goroutines is unsafe, and will
fail with parallelism. A lightweight way to avoid issues is by using
atomic variables.
* machine: add support for BTT SKR Pico
Adds support for the BigTreeTech SKR Pico 3D-printer mainboard.
This board uses the RP2040.
* Fix build tag
* Add I2C defaults
* Run UART test instead of blinky1
* Use NoPin for I2C and SPI on BTT SKR Pico
* Cleanup comments
* Don't use ADC pin names
* Fix DMA to SPI transfers on RP2350
DMA DREQ line numbers for "flow control" between SPI bus and DMA channels on RP2350 differ from RP2040.
Tested with st7789 driver for Pico-1.14-LCD from Waveshare on Pico 2W. Without this fix func st7789.tx() blocks indefinitely while attempting to use DMA to SPI transfers.
* Add definitions for DMA DREQ "handshake" lines
Specific for RP2350, missing in generated src/device/rp/rp2350.go
* Add definitions for DMA DREQ "handshake" lines
Specific for RP2040, missing in generated src/device/rp/rp2040.go
* Complete table
* Complete table
* Remove redundant DMA_ prefix
* Correct name of Datasheet
* Correct name of Datasheet
* Refactor
Move global definitions to device/rp/
* Refactor
* Refactor
* Refacture
* Refacture
* Fix comments
* go fmt
* rename new non-generated files
This commit changes signal handling in a few ways:
* It stubs signals for all wasm targets (not just wasi) and baremetal,
since none of those have traditional POSIX signals. And moves the
code for that into a single file, instead of duplicating it.
* It removes the stub for signal_ignored since the value `false` might
be wrong in some cases and it doesn't usually seem to be called (it
is not called in tsgo). Should be trivial to re-add if it is shown
to be needed.
* It adds a stub for `os/signal.signalWaitUntilIdle` which _is_ called
by tsgo.
With `-opt=2`, WriteByte gets inlined everywhere a println statement
exists. This blows up binary size for very little gain. In my case, the
binary size roughly doubled. Instead, don't inline it so that the binary
size remains somewhat reasonable. This might slow down WriteByte a tiny
bit, but likely not by any significant amount.
Errors are part of API, and the exported rp2 errors seemed arbitrary.
For example, the very particular ErrRP2040I2CDisable was exported, but
errI2CWriteTimeout (which is defined on all platforms) is not.
While here, remove "RP2040" from an error name and make the messages
consistent and idiomatic.
The `gosched` call introduce arbitrary long delays in general, and in
TinyGo particular because the goroutine scheduler is cooperative and
doesn't preempt busy (e.g. compute-heavy) goroutines.
Before this change, the timeout logic would read, simplified:
deadline := now() + timeout
startTX()
for !txDone() {
if now() > deadline { return timeoutError }
gosched() // (1)
}
startRx() // (2)
for !rxDone() {
// (3)
if now() > deadline { return timeoutError }
gosched()
}
What could happen in a busy system is:
- The gosched marked (1) would push now() to be > than deadline.
- startRx is called (2), but the call to rxDone immediately after would
report it not yet done.
- The check marked (3) would fail, even though only a miniscule amount
of time has passed between startRx and the check.
This change ensures that the timeout clock discounts time spent in
`gosched`. The logic now reads, around every call to `gosched`:
deadline := now() + timeout
startTX()
for !txDone() {
if now() > deadline { return timeoutError }
before := now()
gosched()
deadline += now() - before
}
I tested this change by simulating a busy goroutine:
go func() {
for {
// Busy.
before := time.Now()
for time.Since(before) < 100*time.Millisecond {
}
// Sleep.
time.Sleep(100 * time.Millisecond)
}
}()
and testing that I2C transfers would no longer time out.
Fixes#4884 by upgrading the ssa package.
The fix is in v0.26.0, which also bumps the minimum Go to 1.22. The
latest x/tools module still depending on 1.22 is v0.30.0.
I only discovered this issue after a while. All the baremetal PWM
implementations use pointers to a PWM instance, instead of the PWM
instance itself. For consistency (and because it's a better idea in
general), the simulated PWMs need to work the same.
This is useful for the TinyGo Playground: with this change it can show
the error span like in an IDE, instead of just the (single) error
position. Errors become a bit more readable as a result.
This changes the -json flag for build/run/flash/gdb etc commands to not
print `compileopts.Config` but instead match upstream Go and print build
errors in a structured way.
For more details, see the proposal:
https://github.com/golang/go/issues/62067
This adds support for the 'go install' case, where we link against the
system LLVM (Homebrew, Linux distro version, etc). This does not have an
effect on `make`, which still uses LLVM 19 for now.
The main reason for doing this is because newer distros like Fedora 42
and Homebrew have switched to LLVM 20, so switching to this newer
version helps those people. (I'm one of those people, I'm on Fedora 42).
There are two small changes for WebAssembly included:
* nontrapping-fptoint was enabled in the wasmbuiltin library used for
wasm-unknown. This matches wasm-unknown which already had this
enabled, so it doesn't add any new instructions.
* bulk-memory was enabled in wasi-libc. This was previously enabled in
all the other WebAssembly targets (wasm, wasip1, wasip2) so this
does't add any new instructions. I think it was also enabled in the
wasi-libc build before
https://github.com/tinygo-org/tinygo/pull/4820 but I don't know for
sure.
Without this change, a pending interrupt would spuriously trigger
immediately after enabling. This happens if an interrupt is triggered
during flashing (e.g. by DMA), which survives the subsequent reset.
This behaviour matches e.g. `machine.irqSet` in machine_rp2_rp2350.go.
See 7f970a45, whose symptoms were likely caused by spurious interrupts.
For the threads scheduler, it makes sense to have NumCPU available.
For all other schedulers, the number of available CPUs is practically
limited to one by the scheduler (even though the system might have more
CPUs).
A race condition was possible because the 'acquire' goroutine might not
have started in 4 milliseconds which changed the ordering of the test.
This patch fixes it by making sure the goroutine has started (and locked
the mutex) before continuing with the test.
This variable is only necessary on the cooperative and none scheduler.
It is not used on the threads scheduler.
The reason for moving is that the upcoming multicore baremetal scheduler
also needs mainExited but of a different type: an atomic variable
instead of a plain boolean.