Pumpkin, Inc.

Pumpkin User Forums

Salvo Task Switching

If you have a general question or comment regarding Salvo, post it here.

Salvo Task Switching

Postby ben » Tue Oct 30, 2007 7:06 am

I seem to have some basic config problem that prevents proper task switching. I have stripped the system to just 2 tasks that do nothing but print a message and then attempt to allow a context switch.
Symptoms:
Using OS_Yield(), the scheduler gets called, and if the tasks are the same priority, they switch round-robin. If one task is a higher priority, the other task never runs.
Switching using binary semaphores, the scheduler is only called once, then the higher priority task executes continuously, even though the semaphore it waits on is held by the other task which never runs and both semaphores are created in a reset state (i.e. '0'). If the tasks have the same priority, still only one of them executes continuously.

Here is my salvocfg.h. I'm working with a microchip PIC24F64.

#define OSUSE_LIBRARY FALSE
//#define OSLIBRARY_TYPE OSL
//#define OSLIBRARY_CONFIG OSA

#define OSEVENTS 9
#define OSEVENT_FLAGS 1
#define OSMESSAGE_QUEUES 2
#define OSTASKS 2
#define OSBYTES_OF_DELAYS 4
#define OSBYTES_OF_TICKS 4

#define OSENABLE_BINARY_SEMAPHORES TRUE
#define OSENABLE_TIMEOUTS TRUE

#define OSENABLE_ARRAYS TRUE

#define OSENABLE_TICKS TRUE
#define OSENABLE_DELAYS TRUE

#define TASK_KEYPAD_P OSTCBP(1) /* "" #1 */
#define PRIO_KEYPAD 5 /* "" */
#define BINSEM_OKAY_TO_WFI_P OSECBP(1) /* binSem #1 */
#define BINSEM_KEYPAD_INPUT_INT_P OSECBP(2) /* binSem #2 */

#define TASK_LCD_P OSTCBP(2) /* "" #2 */
#define PRIO_LCD 5 /* "" */
#define BINSEM_LCD_SPI_READ OSECBP(3) /* binSem #3 */
#define BINSEM_LCD_INPUT_INT_P OSECBP(4) /* binSem #4 */

Ideas?

ben
 
Posts: 2
Joined: Mon Oct 29, 2007 11:00 pm

Re: Salvo Task Switching

Postby aek » Tue Oct 30, 2007 7:38 am

Seeing your code would help ... also knowing your target, compiler, version #, etc.

1) Start with a Library build -- not a source-code build. Your salvocfg.h should have only

code:
#define OSUSE_LIBRARY TRUE
#define OSLIBRARY_TYPE OSL
#define OSLIBRARY_CONFIG OSA

#define OSEVENTS 2
#define OSEVENT_FLAGS 0
#define OSMESSAGE_QUEUES 0
#define OSTASKS 2


for an "a" lib build.

2) The behavior you describe is correct when using only OS_Yield(). Why? Because the Salvo scheduler always follows a very simple rule -- run the most eligible task. When you have two tasks at the same priority that yield, both of them are eligible and both of them are at the same priority, so both of them run. If you lower one of the priorities, then the other one is always eligible AND and has the highest priority, so only it runs.

3) Your third situation is likely a coding error, because OSSched() should be running "all the time". Not having OSSched() runs means that you are stuck in the task and have not yielded back to the scheduler.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Salvo Task Switching

Postby ben » Tue Oct 30, 2007 9:02 am

Thanks for the explaination. The OS_Yield operation makes sense.

I tried the library compilation idea, but got the same result. Below is my code with all of the actual task functionality other than status indications and task switching sripped out. I am compiling with Microchip MPLAB-30 v.7.62.

code:
int main (void)
{
unsigned int i;

CLKDIV = 0x0;
AD1PCFG = 0xffff;

APTimerInit();
// API2CInit();

__asm__ volatile("disi #0x0000");
/* Interrupt Control (disable ints) */

mcu_lcd_init();

lcd_flash();
lcd_clear_screen(0x07e0);
lcd_println("Init main()");

/* Initialize the OS */
OSInit();

lcd_println("OS Init");

/* Initialize the Keypad task and its semaphore(s) */
OSCreateTask(TaskKeyPad, TASK_KEYPAD_P, PRIO_KEYPAD);
OSCreateBinSem(BINSEM_KEYPAD_INPUT_INT_P, 0);
#if 1
OSCreateTask(lcdProc, TASK_LCD_P, PRIO_LCD);
OSCreateBinSem(BINSEM_LCD_SPI_READ, 0);
#endif
__asm__ volatile("disi #0x0000");
i = 0;
for (; ;) {
OSSched();
}
}

void TaskKeyPad(void)
{
unsigned int Key, i;

KeypadTaskInit();

lcd_println("KP Init Done");

i = 0;
while (1)
{

lcd_println("KeyPad Task");

/* Suspend - wait for keypad interrupt */
/* Context-switch so other tasks can run. */

lcd_println("KP Yield");
// OS_Yield();
OSSignalBinSem(BINSEM_LCD_INPUT_INT_P);
OSWaitBinSem(BINSEM_KEYPAD_INPUT_INT_P, OSNO_TIMEOUT);

lcd_println("KP Yield Done");
}
}
void lcdProc(void)
{
unsigned int i = 0;
while (1) {
/* Suspend - wait for keypad interrupt */
/* Context-switch so other tasks can run. */

lcd_println("LCD Yield");
// OS_Yield();
OSSignalBinSem(BINSEM_KEYPAD_INPUT_INT_P);
OSWaitBinSem(BINSEM_LCD_INPUT_INT_P, OSNO_TIMEOUT);
lcd_println("LCD Yield Done");
}
}


[This message has been edited by aek (edited October 30, 2007).]

ben
 
Posts: 2
Joined: Mon Oct 29, 2007 11:00 pm

Re: Salvo Task Switching

Postby aek » Tue Oct 30, 2007 9:48 am

Typo -- you need OS_WaitBinSem(), not OSWaitBinSem().

Also, it looks like you're not using interrupts. Once you do, you'll need to define savlvohook_interrupt.c properly based on which ISRs call Salvo services.

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm


Return to General

Who is online

Users browsing this forum: No registered users and 2 guests

cron