mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-05 19:43:44 +00:00
all: add compiler support for interrupts
This commit lets the compiler know about interrupts and allows optimizations to be performed based on that: interrupts are eliminated when they appear to be unused in a program. This is done with a new pseudo-call (runtime/interrupt.New) that is treated specially by the compiler.
This commit is contained in:
committed by
Ron Evans
parent
3729fcfa9e
commit
a5ed993f8d
@@ -0,0 +1,38 @@
|
||||
// Package interrupt provides access to hardware interrupts. It provides a way
|
||||
// to define interrupts and to enable/disable them.
|
||||
package interrupt
|
||||
|
||||
// Interrupt provides direct access to hardware interrupts. You can configure
|
||||
// this interrupt through this interface.
|
||||
//
|
||||
// Do not use the zero value of an Interrupt object. Instead, call New to obtain
|
||||
// an interrupt handle.
|
||||
type Interrupt struct {
|
||||
// Make this number unexported so it cannot be set directly. This provides
|
||||
// some encapsulation.
|
||||
num int
|
||||
}
|
||||
|
||||
// New is a compiler intrinsic that creates a new Interrupt object. You may call
|
||||
// it only once, and must pass constant parameters to it. That means that the
|
||||
// interrupt ID must be a Go constant and that the handler must be a simple
|
||||
// function: closures are not supported.
|
||||
func New(id int, handler func(Interrupt)) Interrupt
|
||||
|
||||
// Register is used to declare an interrupt. You should not normally call this
|
||||
// function: it is only for telling the compiler about the mapping between an
|
||||
// interrupt number and the interrupt handler name.
|
||||
func Register(id int, handlerName string) int
|
||||
|
||||
// handle is used internally, between IR generation and interrupt lowering. The
|
||||
// frontend will create runtime/interrupt.handle objects, cast them to an int,
|
||||
// and use that in an Interrupt object. That way the compiler will be able to
|
||||
// optimize away all interrupt handles that are never used in a program.
|
||||
// This system only works when interrupts need to be enabled before use and this
|
||||
// is done only through calling Enable() on this object. If interrups cannot
|
||||
// individually be enabled/disabled, the compiler should create a pseudo-call
|
||||
// (like runtime/interrupt.use()) that keeps the interrupt alive.
|
||||
type handle struct {
|
||||
handler func(Interrupt)
|
||||
Interrupt
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// +build cortexm
|
||||
|
||||
package interrupt
|
||||
|
||||
import (
|
||||
"device/arm"
|
||||
)
|
||||
|
||||
// Enable enables this interrupt. Right after calling this function, the
|
||||
// interrupt may be invoked if it was already pending.
|
||||
func (irq Interrupt) Enable() {
|
||||
arm.EnableIRQ(uint32(irq.num))
|
||||
}
|
||||
|
||||
// SetPriority sets the interrupt priority for this interrupt. A lower number
|
||||
// means a higher priority. Additionally, most hardware doesn't implement all
|
||||
// priority bits (only the uppoer bits).
|
||||
//
|
||||
// Examples: 0xff (lowest priority), 0xc0 (low priority), 0x00 (highest possible
|
||||
// priority).
|
||||
func (irq Interrupt) SetPriority(priority uint8) {
|
||||
arm.SetPriority(uint32(irq.num), uint32(priority))
|
||||
}
|
||||
Reference in New Issue
Block a user