waitfor and wfd issues

I am facing a trouble concerning usage of waitfor and waitfordone in our program, which was initially written for Rabbit 2000, but now being modified to be used at Rabbit 6000.

The program utilizes costates. It has several cofunctions, which are called one from another with wfd.These functions use waitfor(DelayMs) statements to yield before processing further.

The expected behavior is that after the defined time passes, it would continue from the waitfor statement further along the function. But what I get is the program does not return to the function in question, but instead moves on from the wfd statement like if the function has completed its work. In shorter words, the program understands yielding as completion, which is obviously incorrect behavior and stops the program from functioning properly. The same result is achieved if I use “yield” keyword instead of “waitfor”.

I am trying to read the value returned by “wfd”, but the result does not match my expectations either. While the manual describes possible values as “1, 2, …” for completion of a corresponding function, and negative values for abortion, I receive sometimes 0, sometimes some other illogical value (like 10, while I have only one function called in this wfd).
This does not depend on the code of the function called, but rather happens since the specific level of enclosure (3 in my case).

What might be a cause here? And how would I be able to correct it?

I am using Rabbit 6000 microcontroller with the RCM6700 module, with Dynamic C ver.10.72.

Thank you!

The structure itself looks like that:
costate
{
…
wfd cof_f1(…);
…
}
costate
…
cofunc int cof_f1(…)
{
…
wfd cof_f2(…);
…
}
cofunc int cof_f2(…)
{…
i = -99;
i = wfd cof_f3(…);
//after all other costates have yielded, it proceeds to the next line instead of returning to cof_f3, like if this function has already completed or aborted.
//the returned value of wfd is unexpected, like 0 or 10.
…
}
cofunc int cof_f3(…);
{…
waitfor(DelayMs(10));
//here it yields, but never proceeds further
…
}

Hello, Did you check sample applications related to co functions? You can find the samples at below path
C:\DCRABBIT_10.72A\Samples\COFUNC

If you provide sample application and expected behavior I can check on my module.

1 Like

Looks like the problem is in using Return statements nearby, even if they never get to work (like in an ex, but just being in the code.

I may illustrate it by a following example, derived from one of the samples.

cofunc int cof_L5 (int spd)
{
int i;
int j;

    d = -99;
if (d == -1)
	return 0;
d = wfd {
	i = cof_LedOn(spd);
}

;
return i;
}

cofunc int cof_LedOn(int spd)
{
BitWrPortI(PDDR, &PDDRShadow, 1, DS1); // LED off
waitfor(DelayMs(spd200 + 50));
BitWrPortI(PDDR, &PDDRShadow, 0, DS1); // LED on
waitfor(DelayMs(spd
200 + 50));
return 1;
}

It works perfectly when the following lines in cof_L5 don’t exist or are commented out, but starts behaving abnormally when they are in place:
if (d == -1)
return 0;
Since it is never “true”, it should not affect the algorithm anyhow. But instead, it produces the behaviour I mentioned (after reaching the first waitfor in cof_LedOn function, it never continues from the same spot, but instead goes further after wfd in cof_L5).

I could not find any documentation on such behaviour anywhere, so it looks like a compiler bug. A strange sort of. It can be bypassed though by removing the need of a premature “return”.

As documented, each cofunction can only have a single return statement. Unfortunately, the compiler doesn’t generate an error or warning if there are multiple returns. You need to structure cofunctions to set a return value and eventually reach a single return statement at the end of the function.

That answers my question. Thank you!