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

Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 24, 2007
Hello,

I constantly get Prefetch Aborts supposedly pointing to the memory range allocated to vTaskSuspend()--using preemption, by the way. I've tried increasing the heap size, the task stack sizes, etc. and nothing appears to work. I'm using the YAGARTO toolchain and an Atmel AT91SAM7SE. Do the ARM mode stack sizes set up in the assembly startup file make any difference? Any tips on things to try would be appreciated.

Thanks,
Darrik

RE: Prefetch Aborts within vTaskSuspend()

Posted by Dave on July 24, 2007
I just replied to your post on the other thread. It may provide the answer you want. If not write back.

Dave.

RE: Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 24, 2007
Yes, I have read the memory configuration doc ( http://www.freertos.org/a00111.html ). I am using heap_2.c in my application. If I do NOT allow one of my tasks to be handled (which is resumed from an IRQ0 ISR using xTaskResumeFromISR() with the task handle), then most everything works okay. However, when I DO handle the task it will cause the Prefetch Abort at least at some point. I don't know if it is the hierarchy of functions calls in the task (which I assumed could use up the stack, so I increased it to 2000 units = 8000 bytes with no change in behavior). So the only thing I could assume is that the PIT causes a context switch which maybe hits another task and causes ITS stack to overflow. I don't know. I then tried to use the critical API calls in this particular task, but then it caused a Data Abort. I just can't seem to win. Since the critical API calls seemed to be worse I removed those calls from within the task. Here's my task which calls my ISR handler (a deferred interrupt handler where the interrupt is edge-triggered and only triggers once, but should get cleared when handled):

void my_InterruptTask(void *pvParameters)
{
/* Just to stop compiler warnings. */
( void ) pvParameters;

for( ;; )
{
vTaskSuspend( NULL );

// portENTER_CRITICAL();

my_HandleISR();

// portEXIT_CRITICAL();
}
}

RE: Prefetch Aborts within vTaskSuspend()

Posted by Richard on July 25, 2007
I cannot see why the code you have posted should cause a prefetch abort, but don't know what is going on in my_HandlerISR(). Prefetch abort would be very unusual. Stack problems would normally result in a data abort.

I don't think it is related to your problem, but depending on the rate at which your interrupts are arriving, there is the potential for a race condition when using the task suspend/resume mechanism in this manner. Should another interrupt arrive prior to my_InterruptTask() calling vTaskSuspend() then the ISR will have attempted to resume the task before it was ever suspended. This can result in the interrupt handling being missed as the task will eventually get around to calling vTaskSuspend() without anything telling it that an interrupt has already arrived. Using a semaphore to wake a task from an ISR would fix this.

Regards.

RE: Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 25, 2007
I delayed enabling the IRQ0 interrupt until after the majority of the code started up and that changed the behavior. Keep in mind I am using preemption (not cooperative). Now instead of the Prefetch Abort in vTaskSuspend() I am getting a Data Abort in xTaskRemoveFromEventList(). Since I wasn't getting the second interrupt (as you thought might happen) I am trying the semaphore method. However, when I take the semaphore after the task has just been serviced, the OS goes to suspend the task (and it does), but then it fails to switch tasks and performs a data abort. Here is the code now:

void my_InterruptTask(void *pvParameters)
{
/* Just to stop compiler warnings. */
( void ) pvParameters;

for( ;; )
{
uart_TxString(AT91C_BASE_US0,"my_InterruptTask: wait\r\n"); // DJS test

// vTaskSuspend( NULL );
xSemaphoreTake( xOSSemaphoreHandle[S_MYIRQ], ( portTickType ) portMAX_DELAY );

// portENTER_CRITICAL();

uart_TxString(AT91C_BASE_US0,"my_InterruptTask: ISR\r\n"); // DJS test

my_HandleISR();

// portEXIT_CRITICAL();
}
}


The result is the following:
my_InterruptTask: ISR
my_HandleISR: ulMyIrq=80000000
my_HandleISR: i=0
my_InterruptTask: wait
Data Abort at 0x2000469A 0xData Abort at 0x20000348 0xE5941000
Current task = MY_IRQ


0x2000469A is within xTaskRemoveFromEventList() and since the current task after the data abort is still MY_IRQ then it appears the switch to another ready task has not yet happened (the Data Abort strings and Current task strings are printed from the data abort ISR).

Any ideas?

RE: Prefetch Aborts within vTaskSuspend()

Posted by Dave on July 26, 2007
I'm guessing you are, but I'll ask the question anyway as I cannot see anything else wrong: Are you using the xSemaphoreGiveFromISR() macro from within your interrupt? ie the one with "FromISR" on the end.

RE: Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 26, 2007
Yes, I'm using the FromISR version. Here's that code as well (this is an ARM-compiled file (not THUMB) and the handler is declared as "naked"):

void irq_Irq0ISR(void)
{
/* IRQ0 ISR. This can cause a context switch so is not defined as a
standard ISR using the __irq keyword. See the port documentation on the
FreeRTOS.org website for more information. */

/* This ISR can cause a context switch, so the first statement must be a
call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
variable declarations. */
portENTER_SWITCHING_ISR();

portBASE_TYPE xTaskWokenByPost = pdFALSE;

/* Clear the edge-triggered interrupt */
AT91C_BASE_AIC->AIC_ICCR = 0x1 << AT91C_ID_IRQ0;

// xTaskWokenByPost = xTaskResumeFromISR( xMYIRQTaskHandle );
xTaskWokenByPost = xSemaphoreGiveFromISR(xOSSemaphoreHandle[S_MYIRQ],xTaskWokenByPost);

/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = 0;

/* If a task was woken by either a character being received or a character
being transmitted then we may need to switch to another task. */
portEXIT_SWITCHING_ISR( xTaskWokenByPost );
}

RE: Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 26, 2007
Okay, I believe that the prefetch aborts are the result of using printf-related calls. For example, I have a UART and a logging printf type of call and when those were being called during the task then FreeRTOS's kernel would always blow up with the prefetch abort. My code looked like this:

int cnt;
char buffer[255];
va_list arg_ptr;

va_start(arg_ptr, msg);
cnt = vsprintf(&buffer[0], msg, arg_ptr);
va_end(arg_ptr);


I don't know if an interrupt happening during this code caused the problem, but I am suspect of this since some of the prefetch aborts pointed to the tick handler.

Can anyone explain what is happening? I assume it must be related to how stack/heap is used for the variable parameter lists or printf code and that caused major chaos with FreeRTOS. Any ideas?

RE: Prefetch Aborts within vTaskSuspend()

Posted by Dave on July 27, 2007
A couple of things here.

First char buffer[255], is this declared on the stack? If so, have you allocated that much stack to the task? You might be better off declaring it static, but be careful of reentrancy problems if you do.

Second, any printf related GCC library is going to use masses of stack because the functions were never originally written for use in embedded systems. There are some small implementations around that you could use instead. FreeRTOS\Demo\CORTEX_LM3S6965_GCC\LuminaryDrivers\ustdlib.c might be of help, but Luminary might not be too happy if you use the code on an ARM7.

RE: Prefetch Aborts within vTaskSuspend()

Posted by Darrik Spaude on July 27, 2007
It looks like it is a combination of using buffer[255] and the standard library's vsprintf(). If I use vsprintf() using a buffer from a pool, then I don't get the prefetch abort. When I use buffer[256] (rather than 255) and my own vsprintf() routine, then I don't get the prefetch abort.

I have almost 2 MB of memory to use and my stacks are quite large, so 256 bytes isn't that much. However, I figured I should try to narrow it down to the real offender here and it appears to be both. I think I will just use my own vsprintf() routine but still use the 256-byte in-stack buffer because in the routine using it I need speed and allocating a block of memory (and then freeing it) will add a lot of time.

Thanks for your input!


[ 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