Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Machine API #9

Closed
aykevl opened this issue Sep 15, 2018 · 14 comments
Closed

Machine API #9

aykevl opened this issue Sep 15, 2018 · 14 comments

Comments

@aykevl
Copy link
Member

aykevl commented Sep 15, 2018

Maybe it is a good idea to actually design an API for the "machine" module, similar to the (mostly) cross-platform MicroPython hardware API.

@aykevl
Copy link
Member Author

aykevl commented Sep 16, 2018

Here it is:
https://github.com/aykevl/tinygo/wiki/Machine-API

Feel free to comment on it.

@deadprogram
Copy link
Member

deadprogram commented Nov 30, 2018

The wiki needs to be updated based on the I2C interface that we ended up using.

Also, I would like to startup the conversation about a proposed SPI interface.

type SPIConfig struct {
    SCK uint8
    MOSI uint8
    MISO uint8
    Frequency uint32
    MSBFirst bool
    Mode uint8
}

type SPI {
    Configure(c SPIConfig)
    Tx(w, r []byte) error
}

@aykevl
Copy link
Member Author

aykevl commented Nov 30, 2018

What does the "mode" field mean? And can MSBFirst be merged into it? (This depends somewhat on how the hardware implements SPI mode).

Other than that, this interface looks good.

@deadprogram
Copy link
Member

Mode refers to the standard SPI modes: http://www.rosseeld.be/DRO/PIC/SPI_Timing.htm

The bit order (MSB first or LSB first) is implemented differently depending on the target, so it seemed like a good idea to keep separate.

@deadprogram
Copy link
Member

This is my WIP branch with the nrf5x SPI support: https://github.com/hybridgroup/tinygo/tree/feature/nrf-spi

@aykevl
Copy link
Member Author

aykevl commented Nov 30, 2018

FYI: I have made the wiki editable by everyone.

@deadprogram
Copy link
Member

Thanks for doing that. I recently updated both the I2C and SPI interface details on the wiki.

@m-chichikalov
Copy link
Contributor

May I make couple nitices | suggestion?

1: the Pin interface lack of external IRQ (config, assignment callback ... )
2: I used to classify Uart,Spi,I2C and other drivers as Synch, Asynch( asynch might be with supporting some RTOS ).
Not sure how the asynch dirvers would integrate with goroutines: How the Goroutin would block on it? Or Drivers should accept channels as pipes? could someone spread light on it?

@aykevl
Copy link
Member Author

aykevl commented Jun 16, 2019

  1. Yes, good point. My plan is to expose interrupts in a nice way, to make the runtime (and perhaps even the compiler if necessary) aware of interrupts. Once that is done, adding support for pin interrupts should be a lot easier. Support obviously varies by chip (family), because some chips have a single interrupt for all pins, some have special interrupts for some pins, and some chips even have a separate interrupt handler for each pin. My plan is to abstract this all away, so that you could do something like the following:
func init() {
    machine.BUTTON1.Configure(...)
    machine.BUTTON1.SetInterrupt(machine.PinChange, machine.PriorityHigh, func(pin machine.Pin) {
        machine.LED1.High(machine.BUTTON1.Get())
    })
}
  1. Yes, this would be best solved using goroutines. The convention in Go is to use blocking operations everywhere and let the scheduler take care of everything, and this is how I imagine the TinyGo runtime will grow - because this is very easy to reason about. So for example when one goroutine reads from UART0 but no data is coming in, the scheduler will automatically switch over to a different goroutine that is runnable (for example, because it was sending on the SPI bus and all data has been sent now).
    I'm not yet sure what the implementation will look like but it could use some sort of semaphore: it could block on it and wait until an interrupt handler unblocks it to continue the goroutine.
    Unfortunately, Go has no concept of goroutine priorities so that's a bit unfortunate, but perhaps we can come up with a way to set it anyway with runtime calls.

@m-chichikalov
Copy link
Contributor

Good plans.
In my humble opinion the FreeRTOS's tasks and queues looks very similar to goroutines and channels. Maybe you already think to reuse FreeRTOS as core for runtime scheduler? Seems that it really can speedup everything as long as it is already implemented for hundreds different mcu families.
What do you think?

@niaow
Copy link
Member

niaow commented Aug 19, 2019

Notes about possible interactions of interrupts:

  1. One way that some goroutines could interact with interrupts is that certain interrupts could do non-blocking channel sends. Like if you want a stream of all ADC values. However, this would require channel code to be interrupt-aware.
  2. Another way to facilitate using an interrupt to unblock would be by writing into some variable associated with the interrupt. Before going to sleep, the scheduler could temporarily disable interrupts and if one is present add it to the scheduler queue and cancel going to sleep. After awakening, we could then repeat this check.
  3. What happens if an interrupt function blocks? Should we move it to the scheduler? Should we spawn another copy of it if the first is still running?

@m-chichikalov
Copy link
Contributor

3. What happens if an interrupt function blocks? Should we move it to the scheduler? Should we spawn another copy of it if the first is still running?

Just side question:
An interrupt function executes in isr context or it's associated with this interrupt the routine in scheduler?

@deadprogram
Copy link
Member

This issue has really been replaced with the wiki, and specific Prs like that around interrupts #782

I propose that we close it now.

@aykevl
Copy link
Member Author

aykevl commented Dec 30, 2019

Sounds good. Closing.

An interrupt function executes in isr context or it's associated with this interrupt the routine in scheduler?

I think the most sensible approach is to just run ISRs as they arrive: not running them immediately (in interrupt context) will often cause too much delays and you'll often want to respond to interrupts ASAP.

@aykevl aykevl closed this as completed Dec 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants