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

Bug in AVR32 portmacro.h

Posted by johandc on May 22, 2014

Hi, i have discovered a bug in portRESTORE_CONTEXT() in the AVR32 port of FreeRTOS. The issue relates to both the official port and the one in 'atmel software framework'.

Problem: The portRESTORE_CONTEXT() call does not restore the status register and PC in one atomic operation. It first restores SR, then the PC. When restoring the SR, the interrupts will be enabled before the correct program counter has been set. This will allow any pending interrupt to be processed, and when the interrupt routine finishes the stack have been altered, which eventually will cause the call to set the program counter to crash the CPU.

Solution: By using the 'rets' instruction, the processor will pop both the SR and PC off the stack in one operation. And the pending interrupt will first be allowed to run after the PC have been set.

Here's a patch:

--- a/thirdparty/freertos/freertos-8.0.0/Source/portable/GCC/AVR32_UC3/portmacro.h
+++ b/thirdparty/freertos/freertos-8.0.0/Source/portable/GCC/AVR32_UC3/portmacro.h
@@ -215,18 +215,7 @@ extern void *pvPortRealloc( void *pv, size_t xSize );
     /* Restore R0..R7 */
     "ldm     sp++, r0-r7
-    /* R0-R7 should not be used below this line */
-    /* Skip PC and SR (will do it at the end) */
-    "sub     sp, -2*4
-    /* Restore R8..R12 and LR */
-    "ldm     sp++, r8-r12, lr
-    /* Restore SR */
-    "ld.w    r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */
-    "mtsr    %[SR], r0
-    /* Restore r0 */
-    "ld.w    r0, sp[-9*4]
-    /* Restore PC */
-    "ld.w    pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */
+    "rets"
     :
     : [ulCriticalNesting] "i" (&ulCriticalNesting),
       [pxCurrentTCB] "i" (&pxCurrentTCB),

Note: I know that this will also not set the R8...R12 and LR, but doing so would require a change of the initialStackLayout to set SR and PC at the top, not in the middle. But it proves the issue.

Steps to reproduce: 1) Setup freertos on avr32 target 2) Setup a perihperal interrupt in main.c. Do not enable the global interrupt. 3) Trigger the interrupt source, thus causing an interrupt to be pending. 4) call vTaskStartScheduler()

Problematic behaviour: 5) The system executes the ISR, then hangs.

Expected behaviour: 5) The system executes the ISR, then continues to the highest priority task.

Regards, Johan Christiansen


Bug in AVR32 portmacro.h

Posted by heinbali01 on May 22, 2014

Hi Johan,

Thanks for this patch!

I must admit that I have never set up any interrupt before starting the scheduler. My main() would just configure the clocks and memory and start the first task.

If you still want to load the complete initial stack (including R8...R12 and LR), and also use the rets instruction, this patch could be used:

--- a/portmacro.h +++ b/portmacro.h @@ -219,14 +219,9 @@ extern void pvPortRealloc( void *pv, size_t xSize ); / Skip PC and SR (will do it at the end) / "sub sp, -24" /* Restore R8..R12 and LR / - "ldm sp++, r8-r12, lr" - / Restore SR / - "ld.w r0, sp[-84]nt" /* R0 is modified, is restored later. / - "mtsr %[SR], r0" - / Restore r0 / - "ld.w r0, sp[-94]" - /* Restore PC / - "ld.w pc, sp[-74]" /* Get PC from stack - PC is the 7th register saved */ + "ldm sp, r8-r12, lr" + "sub sp, 8" + "rets : : [ulCriticalNesting] "i" (&ulCriticalNesting),

[pxCurrentTCB] "i" (&pxCurrentTCB),

1.9.1

Regards, Hein

Attachments


Bug in AVR32 portmacro.h

Posted by johandc on May 26, 2014

Thank you for your addition to my patch, together that will actually make a complete patch that we might get pushed upstream.

Just a single comment, shouldn't it be:

ldm sp++, r8-r12, lr
sub sp, 8
rets

By omitting the sp++, we might also just

ldm sp, r8-r12, lr
rets

Or am i wrong? I'm not currently at work and able to test it.


Bug in AVR32 portmacro.h

Posted by heinbali01 on May 27, 2014

Hi Johan,

Maybe my patch was a little confusing. I didn't know yet how to insert literal text in a post (between two lines containing 6 tildes).

I'll put it as a patch on top of your patch:

~~~~~~ --- a/portmacro.h +++ b/portmacro.h /* Restore R0..R7 / ldm sp++, r0-r7 + sub sp, -8 + / Restore R8..R12 and LR / + ldm sp, r8-r12, lr + sub sp, 8 / Pop SR and PC */

rets

~~~~~~

Writing "ldm sp++" with 6 registers would increase the stack pointer too much: 6x4 bytes in stead of 8

Regards, Hein


[ 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