- Code: Select all
_taskswap:
mov a,[_altsp]
swap a,sp
mov [_altsp],a
ret
To use this, one would set up the alternate task via something like:
- Code: Select all
char altsp;
char altstack[32];
{
...
altstack[0] = ((unsigned short)other_proc) >> 8;
altstack[1] = ((unsigned short)other_proc) & 255;
altsp = ((unsigned short)altstack) & 255;
...
}
Once this is done, user code can run until it's waiting for something, whereupon it can call taskswap(). The function other_proc() will then run until it calls taskswap() whereupon the main program will resume where it left off.
I've found this sort of artchitecture very handy on the 8x51 when writing code with two main tasks, both of which spent a lot of time "waiting" for things. I'd think such a thing should work well on the PSOC, but am curious whether anyone has done it. My biggest concern would be whether it would be necessary to save/restore the compiler registers, or if such registers never hold anything meaningful at sequence points. If saving/restoring registers is necessary, then task switching becomes more complicated. If not, though, it's often easier to task-switch whether or not it's needed than to decide when to do so. For example:
- Code: Select all
char getch(void)
{
while (!char_ready())
taskswap();
return input_char();
}
Even if there's no character ready, and even if the other task had something useful it could do when it called taskswap(), the overhead for switching tasks back and forth is probably less than the overhead that would be required for a more 'advanced' OS to decide that no task swap was needed.
Anyone else done anything similar on the PSOC? Does it look like a useful concept?
