tinyvision-ai-inc / pico-ice

Raspberry Pi PICO board + Lattice iCE40 FPGA's
MIT License
142 stars 26 forks source link

Fixed 10ms per-byte delay #43

Closed MrJake222 closed 4 months ago

MrJake222 commented 4 months ago

Fixes #42

Replaced call to getchar with delay 0 Now "timeout" is handled in main loop Repl responds only to valid characters (not timeouts)

josuah commented 4 months ago

I like this change as it brings back the control to the main loop.

This is some long-term topic in embedded: without an RTOS, it is not possible to use threads. So it becomes necessary to have some workaround to be able to run multiple tasks in parallel.

The quick hack we did here is run the periodic USB task wherever waiting was needed.

The proper solution would be putting the USB task in an USB interrupt. No idea why this is not done by the pico-sdk...

An alternative is to use Coroutines so that "sleep" switches to the next task, without using threads for this. https://en.wikipedia.org/wiki/Coroutine#C

MrJake222 commented 4 months ago

USB task in an USB interrupt. No idea why this is not done by the pico-sdk...

Probably to keep interrupts short. It's another golden rule of embedded. Interrupts should notify the main thread and not block.

An alternative is to use Coroutines so that "sleep" switches to the next task, without using threads for this.

Coroutines are cooperative programming, but you'd still need an RTOS to handle task switches.

This is some long-term topic in embedded: without an RTOS, it is not possible to use threads.

Why no RTOS then? I get it, now it'd be a long shot to implement it, but it simplifies weird things like this. For me it's a must have in bigger projects now.

josuah commented 4 months ago

Coroutines are cooperative programming, but you'd still need an RTOS to handle task switches.

Well... there are hacks to bring it to C, but you are right, RTOS is what allows to have a plain C programming environment.

It's another golden rule of embedded.

Good to be reminded there! I might have been assuming an RTOS while calling something that sleep()s in main().

Why no RTOS then?

It could be better with an RTOS at the global level, but the pico-ice-sdk is built to be as portable as possible so that it is just a pico-sdk library. Maybe for the main firmware an RTOS can be used. I still prefer your fix as it is less intrusive and even if an RTOS was used, it would cover the entire migration period.

Another consideration was using MicroPython, which has asyncio.