Shop OBEX P1 Docs P2 Docs Learn Events
Any interest in Spin2 interrupts? — Parallax Forums

Any interest in Spin2 interrupts?

cgraceycgracey Posts: 14,206
edited 2021-03-05 07:01 in Propeller 2

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

  • pik33pik33 Posts: 2,383

    May be useful. Not everything has to be written in asm :)

  • ErNaErNa Posts: 1,752

    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!

  • cgraceycgracey Posts: 14,206

    @ErNa said:
    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.

  • @cgracey said:
    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.

    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.

  • Cluso99Cluso99 Posts: 18,069

    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.

  • cgraceycgracey Posts: 14,206
    edited 2021-03-05 15:03

    @ersmith said:
    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.

    The Spin2 interpreter shields all CORDIC operations from interrupts by using REP. Any assembly language program would have to do something similar.

  • Ahle2Ahle2 Posts: 1,179
    edited 2021-03-05 15:21

    @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.

  • ersmithersmith Posts: 6,068
    edited 2021-03-05 15:23

    @cgracey said:

    @ersmith said:
    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.

    The Spin2 interpreter shields all CORDIC operations from interrupts by using REP. Any assembly language program would have to do something similar.

    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.

  • @Ahle2 said:
    @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 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?

  • potatoheadpotatohead Posts: 10,261
    edited 2021-03-05 15:38

    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.

  • Wuerfel_21Wuerfel_21 Posts: 5,105
    edited 2021-03-05 16:18

    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?

  • ErNaErNa Posts: 1,752

    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...

  • cgraceycgracey Posts: 14,206
    edited 2021-03-05 21:03

    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.

  • TonyB_TonyB_ Posts: 2,193
    edited 2021-03-07 11:23

    @cgracey said:
    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?

  • ColeyColey Posts: 1,110

    @cgracey said:
    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?

    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.

Sign In or Register to comment.