Quality RTOS & Embedded Software

 Real time embedded FreeRTOS RSS feed 
Real time embedded FreeRTOS mailing list 
Quick Start Supported MCUs PDF Books Trace Tools Ecosystem TCP & FAT Training




Loading

FreeRTOS in MPC8641D: Context Switch issue

Posted by LEO K YOHAN on February 9, 2013
Hi

I'm trying to port FreeRTOS in Freescale MPC8641D Board. I'm using codewarrior for compiling and debugging the project. I used the MPC860 example which was available in the FreeRTOS interactive forum as a reference. I know this issue is a bit port specific one. But any help in the FreeRTOS behaviour will be really useful.

As the first step in porting I was able to generate the hardware timer interrupt which is arriving at every 1ms and I called the function vTaskIncrementTick() in the handler.
Stack initialization functions are done according to the reference manual and the example provided. (I dont know whether any problems in that, but everything look fine).

Then I created 2 tasks of same priority both running in an infinite loop.
I have the following observations/issue in my port.

1. My first task is running properly. But context switch is not happening even though I have given vTaskDelay in the first task. When I give higher prority to the second task, that task is getting executed continuously and it is not context switching to the first task. Please note that #define configUSE_PREEMPTION is set as 1 for me and I'm using the interrupt vector table auto-genrated by codewarrior.

2. Inside the vTaskIncrementTick() function, first time it is going to the ++xTickCount; section and it is getting incremented, but from the next interrupt it is always going to the ++uxMissedTicks; section of the code.
( Here I'm getting a strange behaviour: If I'm putting a delay after the interrupt enable part of prvPortSetupInterrupts( void ) function, the control is going to the xTickCount section more than once according to the delay. When it is a big delay xTickCount is reaching more than 40000. But once the delay period is over it is going to the uxMissedTicks section even though the uxSchedulerSuspended value (which I can monitor in the codewarrior watch window) is zero. Then my first task is running in parallel to this I think.)

3. I double checked the timer interrupt and it is running continuously and generating an interrupt at every 1ms which is calling the vTaskIncrementTick.

4. When it is going to the missedTicks section in the readylist[0] it is showing the number of tasks as 3 (I think they are my 2 tasks + the idletask)

5. I think sometimes it is hanging after the control going to the uxMissedTicks. (I'm not confident about this observation)

Below is the code I wrote for prvPortSetupInterrupts and vPortIntHandler.

static void prvPortSetupInterrupts( void )
{

register long aMSR;


IMMR_port->im_pic.tfrr = 0x000003E8;
IMMR_port->im_pic.gtdr0 = 0x00000001;
IMMR_port->im_pic.gtvpr0 |= 0x800F0040;
IMMR_port->im_pic.ctpr0 = 0x00000000;

//interrupt reset
while (IMMR_port->im_pic.gcr & MPC86xx_PICGCR_RST);
IMMR_port->im_pic.gcr = MPC86xx_PICGCR_MODE;


//timer setup
IMMR_port->im_pic.tcr = 0x00000000;
IMMR_port->im_pic.gtbcr0 = 0x0000A299;
IMMR_port->im_pic.gtvpr0 &= 0x7FFFFFFF;

//Enable Interrupt
asm
{
mfmsr aMSR
ori aMSR, aMSR, 0x8000
mtmsr aMSR
sync
}


//here I put a Delay for xtickcount to get incremented (dont know why this behaviour)

}


void vPortIntHandler( )
{
regist=IMMR_port->im_pic.iack0; //Interrupt Acknowledgement

vTaskIncrementTick();

#if ( configUSE_PREEMPTION == 1 )
{
vTaskSwitchContext();
}
#endif



IMMR_port->im_pic.eoi0=0; //end of interrupt

//reset timer
IMMR_port->im_pic.gtbcr0 |= 0x80000000;
IMMR_port->im_pic.gtbcr0 &= 0x7FFFFFFF;
}

As I don't know what exactly the problem is, any inputs which point out what can cause this type of behaviour will be really useful.


Thanks & Regards
LEO

RE: FreeRTOS in MPC8641D: Context Switch issue

Posted by Richard on February 9, 2013
“1. My first task is running properly. But context switch is not happening even though I have given vTaskDelay in the first task.
When I give higher prority to the second task, that task is getting executed continuously and it is not context switching to the first task. Please note that #define configUSE_PREEMPTION is set as 1 for me and I'm using the interrupt vector table auto-genrated by codewarrior.


Context switching happens in two ways, from an interrupt (like the tick interrupt) and when a task yields. Calling vTaskDelay() will cause the task to yeild internally within the delay function. You have verified that your task is starting to run, but have you verified that the context of the task is correct when it starts to run, and have you verified that your yield implementation is working?

Start without using any API functions and configUSE_PREEMPTION set to 0. Then have two tasks that have the following structure:


volatile uint32_t ulVar1 = 0, ulVar2 = 0;

void vTask1( void *pvParameters )
{
for( ;; )
{
ulVar1++;
taskYIELD();
}
}

void vTask2( void *pvParameters )
{
for( ;; )
{
ulVar2++;
taskYIELD();
}
}


Running this code without preemption should show ulVar1 and ulVar2 being incremented at the same rate as the two tasks yield to each other.

Once you have that running correctly you can add in the API calls.


“2. Inside the vTaskIncrementTick() function, first time it is going to the ++xTickCount; section and it is getting incremented, but from the next interrupt it is always going to the ++uxMissedTicks; section of the code.


That would imply that uxSchedulerSuspended was non zero, but your code is not suspending the scheduler anywhere by calling vTaskDelay(), which would then imply that uxSchedulerSuspended was getting corrupted somewhere. Can you see when uxSchedulerSuspended is written to?

“( Here I'm getting a strange behaviour: If I'm putting a delay after the interrupt enable part of prvPortSetupInterrupts( void ) function,”


I don't know what that function is, as it is in your port layer, but generally interrupts would be disabled when the port layer is starting the first task.


“3. I double checked the timer interrupt and it is running continuously and generating an interrupt at every 1ms which is calling the vTaskIncrementTick.


If you are getting stuck in a task even though it has called vTaskDelay() then it is doubtful that the tick interrupt is your problem (yet) as vTaskDelay() should call taskYIELD(), but that is evidently not yielding.

Regards.


[ Back to the top ]    [ About FreeRTOS ]    [ Sitemap ]    [ ]




Copyright (C) 2004-2010 Richard Barry. Copyright (C) 2010-2016 Real Time Engineers Ltd.
Any and all data, files, source code, html content and documentation included in the FreeRTOSTM distribution or available on this site are the exclusive property of Real Time Engineers Ltd.. See the files license.txt (included in the distribution) and this copyright notice for more information. FreeRTOSTM and FreeRTOS.orgTM are trade marks of Real Time Engineers Ltd.

Latest News:

FreeRTOS V9.0.0 is now available for download.


Free TCP/IP and file system demos for the RTOS


Sponsored Links

⇓ Now With No Code Size Limit! ⇓
⇑ Free Download Without Registering ⇑


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Renesas Electronics Gold Alliance RTOS Partner.jpg

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Atmel RTOS partner supporting ARM Cortex-M3 and AVR32 microcontrollers

STMicro RTOS partner supporting ARM7, ARM Cortex-M3, ARM Cortex-M4 and ARM Cortex-M0

Xilinx Microblaze and Zynq partner

Silicon Labs low power RTOS partner

Altera RTOS partner for Nios II and Cortex-A9 SoC

Freescale Alliance RTOS Member supporting ARM and ColdFire microcontrollers

Infineon ARM Cortex-M microcontrollers

Texas Instruments MCU Developer Network RTOS partner for ARM and MSP430 microcontrollers

Cypress RTOS partner supporting ARM Cortex-M3

Fujitsu RTOS partner supporting ARM Cortex-M3 and FM3

Microsemi (previously Actel) RTOS partner supporting ARM Cortex-M3

Atollic Partner

IAR Partner

Keil ARM Partner

Embedded Artists