Reputation: 503
I am programming PIC microcontrollers and I do not have access to the stack. So, in order to create a very simple and easy cooperative multitasking system, I want to try this trick.
I am going to label some of the lines of a function, so that when I come back to the function which is in a loop, I want to continue from where I left.
So, for example, if the status is 2, then the function will have goto point2; in its first line and if the status is 3, then the function will have goto point3; in its first line etc.
I could not manage to create this. Could anyone lead me to a direction?
#define resume_from(x) goto point##x
unsigned char status = 0;
unsigned char x = 0;
unsigned char y = 0;
void my_func(void)
{
resume_from(status);
point0:
status = 1;
return;
point1:
x++;
status = 2;
return;
point2:
x += 2;
status = 3;
return;
point3:
x += 3;
status = 0;
}
void main(void)
{
while (1)
{
my_func();
y++;
}
}
Upvotes: 0
Views: 661
Reputation: 1
You may be interested in continuation passing style. Probably, CPC should interest you. Please notice that CPS transformation is a whole program transformation. Read also wikipages on continuations, coroutines, cooperative multitasking, non-preemptive multitasking, callbacks ...
Read Andrew Appel's old book on Compiling with Continuations and the more recent paper Compiling with Continuations, Continued by A.Kennedy.
You could use computed Goto-s. In standard C99 it is not possible, but some compilers (notably GCC) provide labels as values with indirect goto
as an extension. This enables threaded code (for interpreters).
I have no idea if your compiler on PIC is giving you all that. Perhaps you should consider implementing your own whole program source to source transformer (or find a language and a compiler more suited to your needs, or develop your own PIC compiler, which is an interesting project as such. See also ocapic...).
Perhaps you should consider porting CPC to your system or compiler....
your original code
#define resume_from(x) goto point##x
unsigned char status = 0;
void my_func(void) {
resume_from(status);
should not even compile. The last line is expanded by the C preprocessor
as goto pointstatus;
and you don't have any pointstatus
label. Try to get the preprocessed form (e.g. with gcc -C -E
or the equivalent). You probably want a switch
or a computed goto (if your compiler gives you that).
Upvotes: 2