I am using Salvo LE with a PIC18F452. I have a lot of tasks (about 7), but not all run all the time. In interrupts some data is gathered from the ADC, then on a complete round a task is called (semaphore), and on a specific condition this task signals another task, which waits for another semaphore. On that task I have something like:

code:

static unsigned long i;static unsigned long ticks;//delay1 is 3//delay2 is 2//count is 3

//override of default values for the following variables//#define OSENABLE_TIMEOUTS TRUE#define OSBYTES_OF_TICKS 4

When I run all this, it's not doing what is expected (do some pulsed action, then pause for a bigger period of time, then again, for 3 cycles). It either runs continuosly, or it never reaches PIN_OUT = 0...Looking at the rm-picc18.pdf file, I thought that I have to include slp87lta.h, but it doesn't work. I have tried to make it work for couple of days, but failed.

Can you please help me with a suggestion at least ? Thank you in advance !

1) When choosing between an 86 and an 87 library, you must ensure that the MPLAB build options (for the HI-TECH compiler and linker) match the options used when the library was built. You may have to consult the PICC-18 manual and use command-line options (in MPLAB) to ensure that either 16-bit or 24-bit pointers are in force for the 86 and 87 libraries, respectively. I.e. there are no changes to the salvocfg.h etc -- it's all in the compiler and linker options.

2) The problem you're having is that you are attempting to apply certain configuration options that are not allowed in library builds. See the Salvo user manual's Configuration chapter -- you'll see that there are two groups of configuration options. The first group (e.g. w/OSTASKS) applied to library and source-code builds. The second group (e.g. w/OSENABLE_SEMAPHORES) applies only to source-code builds. When you apply source-code-build-only configuration options to a project that's built with a library, you get unpredictable (and usually wrong) results.

I have corrected the configuration problem for the salvocfg.h file. But the results are the same. It seems that OStimerTicks is reset sometimes, so the while (OStimerTicks < ticks) is executed forever, and after the reset of OStimerTicks, the OS_Delay function don't work as expected...I'll quote the code for the timer interrupt:

code:

if (T0IF) { T0IF = 0; TMR0 -= TMR0_RELOAD; OSTimer (); }

TMR0_RELOAD is 195, for 100 Hz frequency at 20MHz. I am not using variable for OS_Delay, because it would be greater than one byte (3 * 100 for 3 seconds delay).

1) Assuming you have a "perfect" build with no warnings, delay-related problems are almost always tracable to problems in calling OSTimer() at the right rate. As long as you call OSTimer() at a nice, constant 100Hz rate, you should not have any problems with delays.

2) Remember that OSTimerTicks() is a free-running counter that will wrap around at overflow at 2^^32/100 seconds in your case. I don't think that's the problem, though.

3) 100Hz for TMR0 is TMR0_RELOAD = 156 at 4MHz. Unless you're using a prescalar, your TMR0_RELOAD at 20MHz should be 780 ...

4) In your code snippet, count, delay1 and delay2 are not declared. They must be static for your code to work ... because they must persist across context switches.

Salvo's timer is extremely robust, as long as you call it at the right rate, you don't disable interrupts for more than 255*tick period, and you don't have any other configuration problems (like OSTASKS = 5 and you run 6 tasks). I suspect the problem is perhaps in your long-delay algorithm.

Note that MPLAB's simulator is a great way to test this sort of thing. You can watch all the variables (including OStimerTicks) to figure out what's going on / wrong.

I am using a prescaler of 256, and the variables are some members of a global structure, so I think they should work. Just to test this thing, I will set them constant. I tried to use MPLAB SIM for this task, but unfortunately, I use I2C and it blocks in the functions there. Also, I need the real board to trigger all the tasks up to the last one with the delays...To note that sometimes, when I stop the run from the debugger, and then I run from where it was stopped, it can give me the delays in the while (OStimerTicks) cycle, but forever... I don't imagine any cause for OStimerTicks to get reset, but a watchdog timer, but it is stopped...

From what it looks like in my debugger, after the first call to OS_Delay, it never gets back...could this be from a bad library ? I am not using 24-bit pointers to ROM, so I guess slp86lta.lib should be fine, right ?

Yes, on an 'F452 an 86 library will be fine -- but make sure that the compiler and linker are generating 16-bit code for the rest of your application to match how the library was generated.

IIRC, you don't get a warning if there's a mismatch, but you will have runtime problems.

But in general, a failure to "get back" from OS_Delay() after the first call simply means that OSTimer() isn't being called ... the task remains in the delayed state, and the scheduler doesn't take tasks out of the delayed state and back into the eligible state because OSTimer() isn't being called.

You can test just the delay code (and not all the I2C code) in the SIM as a separate application ...

It's definitely something wrong with the libraries, because if I change it to 80lta, it gets past the first delay, and nicely does the cycling in while(OStimerTicks). But after some runtime, the delay times are distorted - I guess this sounds like a problem with the timer, but I can spot none. With this library, it does not get off the while(OStimerTicks) loop

Argggh, the behaviour is sooo strange...Maybe I should redesign the whole loop there...but in this way I guess it is more elegant. Basically, the code is for an alarm pulse of 3 seconds on/2 seconds off, within a bigger cycle of 3 minutes, with a big cycle of 1 minute pause.