Any interest in Spin2 interrupts?
cgracey
Posts: 14,206
Ahle2 asked me if it would be possible to have interrupt service routines written in Spin2.
At first, I thought it was kind of impossible, but I've gone through the interpreter and figured out that there are 36 longs which would need to be saved and restored for a complete context switch between main Spin2 and interrupt-routine Spin2.
To set it up, you would provide a method pointer to the interrupt routine and a stack pointer which points to at least 50 longs.
The context switch would probably take 70 clocks in and 80 clocks out. That's only half a microsecond at 300 MHz.
Doing interrupts in PASM is much more efficient, but if you need to run Spin2 code, this is how it could work.
Are many of you interested in this?
Comments
May be useful. Not everything has to be written in asm
I used to communicate between COGs via a pointer list and expanded this to transparent communication between COGs on multiple chips (did it only once as an experiment) Having interrupts in SPIN would allow to have virtual cogs by using this scheme for inter interrupt routine communication. So yes, would be fine to have it!
Oh, you just brought up something really interesting, ErNa!
This mechanism could be used on a timer interrupt to preemptively multitask many different Spin2 programs on a single cog. That didn't occur to me.
I don't really need it at the moment. But 70/80 clocks is still very good. A 300MHz ARM needs about the same time to enter/leave an interrupt but in assembler! Doing the same in an interpreted language is awesome. This shows how superior the P2 is, again.
There is a big potential issue, and that is any objects that you use in a program with interrupts will have to be carefully scrutinized for use of the CORDIC and for potentially problematic things like REP in inline assembly. This could really trip up newcomers who take an object that works fine in isolation but which doesn't play well at all with interrupt enabled code. Their code could appear to work correctly but then randomly crash, and if they're not experts on the P2 interrupt system and assembly language they'll have a heck of a time figuring out what's going wrong.
I’m definitely not enthused by the idea
I think it also widens the gap between compiled spin with flexprop and interpreted spin with pnut/PropTool even further.
And there are much more “urgent” things that are needed! We don’t even have the basics in your compiler like include and define/ifdef which were standard inclusions back in the 80’s.
The Spin2 interpreter shields all CORDIC operations from interrupts by using REP. Any assembly language program would have to do something similar.
@ersmith and @Cluso99
I really do understand your concerns and this is not an easy matter. Maybe we could have a mechanism to use a _constant to enable the feature or not. If not defined it should default back to not be enabled. A verbose compiler error could be thrown when compiling code that uses Spin2 interrupts, to make the user understand what's wrong. Only the top object should be able to set this _constant.
I guess I didn't express myself well. I know the interpreter itself is safe. My concern is with end-user objects. Anybody who wants to use Spin in interrupts will have to vet all of their Spin objects to make sure that all of the inline assembly is interrupt safe. This isn't something that's obvious for newbies.
One of the nice things about Spin is that you can just pick up objects and mix and match them... if interrupts come into the mix that'll no longer be the case, any object with ORG..END inline assembly (and there are lots of those) will become suspect. Worse, they'll fail in random ways and at random times.
I'm sure expert users could adjust well, but it really seems like a way for inexperienced users to shoot themselves in the foot.
I think what we'd need is a constant in each object that explicitly says "this object is interrupt safe". Then if you want to enable interrupts, the compiler would have to scan every object in the program and verify that all of them are interrupt safe. If any object is missing the magic constant, the compiler would throw an error.
But then, how many programmers would set the constant in their objects? And what if someone tries to work around the error by adding the constant to the object, even though it isn't really interrupt safe?
Would it make sense to flag any object that does have inline PASM?
If the past is any indicator, a high level timer driven set of objects sharing a COG will see a lot of use. I understand the allure.
If code, be it compiled or interpreted, can be made safe, telling people where the wild programming is does not seem too burdensome.
The flag can be something to the effect of, this will probably work but we can't be sure because it contains in line assembly language code.
That plus a point or two some documentation on interrupts how they work in assembly, at least tells people where to look. Otherwise it will probably work because the code can be made safe, and the problems are the same ordinary problems everyone has. The mostly self-inflicted kind.
I think one issue can be solved by the interrupt handler though: I think basic CORDIC state can be saved and restored by doing GETQX/GETQY on IRQ entry and doing a QROTATE over zero when returning. Would that work?
To overcome the problems that arise from careless usage of interrupts, parallel processing is the means of choice. If there are not enough processors, the fall back solution is interrupt. And so the pits return. Therefor the concept of virtual cogs. The spin language could take care of the sync problems that arrive from multible usage of single hardware. But even now I have to take care that I do not use a serial connection from two processes, and not to interrupt ESC sequences to the terminal...
If each virtual cog doing inline PASM were to use a different ORG, or it could be made dynamic at run-time, there would be no code-space conflict. Shielding CORDIC operations from interrupts would just always have to be done.
The alternative is for the interpreter to do a STALLI at the start of the inline-PASM process, then an ALLOWI afterwards.
As a second REP inside a REP block cancels the first REP, just wondering whether you could run inline PASM inside a big repeat-once REP block, exited by RET. Or maybe have two versions of inline PASM?
Yes please Chip, it will help those that are not so adept in PASM.
You can caveat it with 'Use with caution' but at least it will be available if you wanted to use it.