Quality RTOS & Embedded Software

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




Loading

Compiling problem with IAR's new EWAVR3...

Posted by Jorge Navarro Gonzalez on September 3, 2013
Hello,

I'm using the AVR32 AT32UC3C0512C Microcontroller and ASF 3.11 Framework. I'm having some issues with the IAR compiler after updating IAR Workbench from 4.10 to 4.20 new version.

I realized, there have been made some changes in the compiler as shown here (Acuallly not for EWAVR32 but EWAVR):

"Error [Og005] + [Og006] when using inline assembler:

Labels must be referred in the same assembler statement as they are declared. The behavior was not correct in earlier versions of the compiler platform. The new release uses a new internal compiler platform which is a bit more strict."

I'm having the same issue but the code, which is not able to compile belongs to the FreeRTOS port. I assume that the compiler does not recognize the label LABEL_INT_SKIP_RESTORE_CONTEXT_ because it is not defined in the same asm statement. So, I mailed IAR to get more information about this problem (I was actually able to compile the same code with the old version 4.10) and I've got the following answer:

"The label functionality is intentional. It resolves an issue where functions containing inline assembler statements with labels would cause compilation to fail (label defined multiple times in the same function) by making all labels in one inline assembler block unique and local to that block.

We currently have no plans to allow labels to be reused between inline assembler blocks.

It is also worth noting that this problem is not part of ASF. It is part of the FreeRTOS code. The way the inline assembler code is used in that macro can only be labeled as "less than ideal". The code relies heavily on compiler implementation behavior meaning that the likelihood that code breaks on new versions of the compiler is high."

Hier is the code, that you can easily find in the ASF as a FreeRTOS example (...asf-3.11.0\common\services\usb\class\msc\device\example_freertos\at32uc3c0512c_uc3c_ek\iar\example_freertos.eww)

#define portRESTORE_CONTEXT_OS_INT()                                                                      \
{ \
extern volatile unsigned portLONG ulCriticalNesting; \
extern volatile void *volatile pxCurrentTCB; \
\
/* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */ \
/* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
/* level and allow other lower interrupt level to occur). */ \
/* In this case we don't want to do a task switch because we don't know what the stack */ \
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
/* will just be restoring the interrupt handler, no way!!! */ \
__asm__ __volatile__ ( \
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */\
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */\
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */\
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__) \
); \
\
/* Else */ \
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
portENTER_CRITICAL(); \
vTaskSwitchContext(); \
portEXIT_CRITICAL(); \
\
/* Restore all registers */ \
\
__asm__ __volatile__ ( \
/* Set SP to point to new stack */ \
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t" \
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t" \
"ld.w r0, r8[0]\n\t" \
"ld.w sp, r0[0]\n" \
\
"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t" \
\
/* Restore ulCriticalNesting variable */ \
"ld.w r0, sp++\n\t" \
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t" \
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t" \
"st.w r8[0], r0\n\t" \
\
/* Restore R0..R7 */ \
"ldm sp++, r0-r7\n\t" \
\
/* Now, the stack should be R8..R12, LR, PC and SR */ \
"rete" \
); \
\
/* Force import of global symbols from assembly */ \
ulCriticalNesting; \
pxCurrentTCB; \
}

#endif


The compiler reports the following error:

Error[As011]: Undefined symbol: LABEL_INT_SKIP_RESTORE_CONTEXT_215
Error[As011]: Undefined symbol: LABEL_INT_SKIP_RESTORE_CONTEXT_215

I've been thinking to try to call switch the context inside the asm statement but I'm not sure if this is the best option and if it really would work. So, it would be great to get some advice here, how to restore the context in another way and avoid the compiling error.

Thank you so much

RE: Compiling problem with IAR's new EWAVR3...

Posted by Jorge Navarro Gonzalez on September 3, 2013
Sorry about the format of the code before... now it yould be better :)

#define portRESTORE_CONTEXT_OS_INT()
{
extern volatile unsigned portLONG ulCriticalNesting;
extern volatile void *volatile pxCurrentTCB;

/* Check if AVR32_INTC_INT0 or higher were being handled (case where the OS tick interrupted another */
/* interrupt handler (which was of a higher priority level but decided to lower its priority */
/* level and allow other lower interrupt level to occur). */
/* In this case we don't want to do a task switch because we don't know what the stack */
/* currently looks like (we don't know what the interrupted interrupt handler was doing). */
/* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */
/* will just be restoring the interrupt handler, no way!!! */
__asm__ __volatile__ (
"ld.w r0, sp[9*4]\n\t" /* Read SR in stack */
"bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */
"cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */
"brhi LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)
);

/* Else */
/* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */
/* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */
portENTER_CRITICAL();
vTaskSwitchContext();
portEXIT_CRITICAL();

/* Restore all registers */

__asm__ __volatile__ (
/* Set SP to point to new stack */
"mov r8, LWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"orh r8, HWRD("ASTRINGZ(pxCurrentTCB)")\n\t"
"ld.w r0, r8[0]\n\t"
"ld.w sp, r0[0]\n"

"LABEL_INT_SKIP_RESTORE_CONTEXT_"ASTRINGZ(__LINE__)":\n\t"

/* Restore ulCriticalNesting variable */
"ld.w r0, sp++\n\t"
"mov r8, LWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"orh r8, HWRD("ASTRINGZ(ulCriticalNesting)")\n\t"
"st.w r8[0], r0\n\t"

/* Restore R0..R7 */
"ldm sp++, r0-r7\n\t"

/* Now, the stack should be R8..R12, LR, PC and SR */
"rete"
);

/* Force import of global symbols from assembly */
ulCriticalNesting;
pxCurrentTCB;
}

#endif


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




Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.

Latest News

FreeRTOS kernel V10 is available for immediate download. Now MIT licensed.


FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

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

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

OpenRTOS and SafeRTOS