Page 1 of 1

OS services from ISR and main line code

PostPosted: Thu Jan 21, 2010 3:33 am
by larsbn
Dear Sir,
I use Salvo RTOS Lite in a PIC18F458 controller. I use MPLAB IDE 8.30 and the HI-TECH PICC18-compiler (std). I have a problem when I try to use OS-function calls from interrupt routines. You can see the code below (I have remove some of the code to make it easier to read). As you can see, I use the OS-function “OSSignalBinSem” both in the main program and in the interrupt routine.
I do understand the danger of this: If there is an interrupt while OSSignalBinSem is executed in the main program, data may be lost. The compiler accordingly produces an error:

Error[472] : non-reentrant function "_OSSignalBinSem" appears in multiple call graphs: rooted at "_CardDrawn" and "_main"

However, the Salvo manual treats this problem specifically: I’m supposed to use the “OSCALL_Xyz configuration parameters in order to call Salvo services from both main-line code and an ISR”.
This is where I can’t seem to get things right. I’ve tried inserting the “OSCALL_SIGNALEVENT” command with parameter “OSFROM_ANYWHERE”, but the program will not compile (illegal parameter value). I’m missing something crucial here, or I might just get the syntax wrong.
Could you please give me some hints or preferably an example of how to write the program and/or the salvocfg-file, in order to be able to call OS services both from main line code and from ISR:s?
Sincerely,
Ass prof. Lars Bengtsson
ps. I use 16-bit memory pointer, small memory model and library file sfp86ea.

#include <pic18.h>
:

char i,card[5],code[4];
:
void interrupt CardDrawn(void);

:

//Definition av Tasks
void TaskWaitForCard(void) {
while(1) {
:

if (strcmp(card,goodcard1) && strcmp(card,goodcard2)) {
RC2=1; //Tänd röd diod
OSSignalBinSem(OSECBP(3));
}
else {
RC1=1; //Tänd gul diod
OSSignalBinSem(OSECBP(2));
}
}
}

void TaskGoodCard(void) {
while(1) {
OS_WaitBinSem(OSECBP(2),OSNO_TIMEOUT,TaskGoodCard1);
for(i=0;i<4;i++) {
while(!RC3);
code[i]=PORTB&0x0F;
}
if( (!strcmp(card,goodcard1) && !strcmp(code,code1)) ||
(!strcmp(card,goodcard1) && !strcmp(code,code1)) ) {
:
}
else {
RC2=1; //Tänd röd diod
OSSignalBinSem(OSECBP(3));
}
}
}

void TaskBadCard(void) {
while(1) {
OS_WaitBinSem(OSECBP(3),OSNO_TIMEOUT,TaskBadCard1);
: //Släck röd diod
}
}

void main() {
:
OSInit();
OSCreateTask(TaskWaitForCard,OSTCBP(1),8);
OSCreateTask(TaskGoodCard,OSTCBP(2),8);
OSCreateTask(TaskBadCard,OSTCBP(3),8);
OSCreateBinSem(OSECBP(1),0); //initieras till TRUE
OSCreateBinSem(OSECBP(2),0);
OSCreateBinSem(OSECBP(3),0);
OSEi();
while(1) {
OSSched();
}
}

void interrupt CardDrawn(void) {
if(RCREG==';')
OSSignalBinSem(OSECBP(1));
else {
DelayMs(100);
CREN=0;
DelayMs(100);
CREN=1;
}
RCIF=0;
}