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

vPortYield and barriers on Cortex M0 port

Posted by evading on March 9, 2015

I have a question regarding vPortYield and the __asm volatile( "dsb" ); instructions. As I understand it that is purely a hardware memory barrier that prevents the CPU from reordering instructions as it executes them. Shouldn't there also be a __asm volatile("" ::: "memory"); (in the GCC case) to prevent the compiler from reordering instructions at compile time?


vPortYield and barriers on Cortex M0 port

Posted by rtel on March 9, 2015

I think in the case of the M0 the barrier instructions are not necessary - in fact that is true for the majority of M3 and M4 implementations on the market too. Although barriers are required to be strictly in conformance with what a Cortex-M core could do, in a different implementation, it is only really now with the M7 cores that there are actual implementations that need them.

Shouldn't there also be a __asm volatile("" ::: "memory"); (in the GCC case) to prevent the compiler from reordering instructions at compile time?

Please elaborate on your rationale for that - so we can determine if it is necessary, as your comment seems to be related more to the compiler than the hardware.

Regards.


vPortYield and barriers on Cortex M0 port

Posted by evading on March 9, 2015

I'm no sure about this but since the compiler could do instruction scheduling at compile time for some optimization levels, maybe a hardware barrier instruction is not sufficient in all cases. Or maybe the software barrier is implied when using a hardware barrier instruction?

I'm sorry I can't be more specific but I'm trying to figure this out myself.


vPortYield and barriers on Cortex M0 port

Posted by jasonrlund on March 9, 2015

I believe the "volatile" keyword in the ASM call signals the compiler to not reorder in such a way where causality is broken for that function.


vPortYield and barriers on Cortex M0 port

Posted by evading on March 10, 2015

Yes, as I understand it (from this source for example http://www.ethernut.de/en/documents/arm-inline-asm.html) that is only for the asm instructions in that asm statement, without a memory barrier the setting of portNVICINTCTRL could actually be moved (by the compiler) to after the asm instructions. Unless the compiler implicitly see the hardware barriers as a software barrier as well.


vPortYield and barriers on Cortex M0 port

Posted by andymcc0 on March 10, 2015

No, that is not what the volatile storage class qualifier explicitly does. It tells the compiler that it cannot assume that a previously read value of the volatile variable is still valid, and so it must be re-read, so the second or subsequent read in the code must not be optimised out. An obvious example is when the variable is a hardware status register that is being polled for a bit to change state. It does not guarantee that 'out of order execution' will not occur.

The dsb and dmb ARM assembler instructions will guarantee that all memory accesses will happen before any subsequent memory accesses or instructions, respectively. The isb instruction will guarantee that the subsequent instructions will be re-fetched, bypassing any pipeline. None makes any guarantee about the order before or after. The use of these instructions in relation to the volatile keyword is entirely compiler dependent, so if this is important for your application, you will have to include these instructions as required in your code.

I clearly (even painfully) remember having to scatter EIEIO* instructions all over some PowerPC code that was heavily interractive with hardware via a bus-bridge with a posted write capability. I have had no such problems (yet) with ARM Cortex-M based processors, but I've only used M3/4.

* (tm) Old MacDonald Farm Enterprises Inc.


vPortYield and barriers on Cortex M0 port

Posted by rtel on March 10, 2015

Here is the docs on the use of volatile with an asm statement:

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile


vPortYield and barriers on Cortex M0 port

Posted by jasonrlund on March 11, 2015

Admittedly, although I understand the volatile storage class qualifier I did not understand the use of it as a qualifier to an ASM function and took a low-grade guess at it. Thank you for the clarification.


vPortYield and barriers on Cortex M0 port

Posted by evading on March 11, 2015

Yes, and that doc contains the statement that "Note that the compiler can move even volatile asm instructions relative to other code, including across jump instructions."

So basically, unless the "dsb" and "isb" instructions imply a software barrier, the vPortYield code:

/* Set a PendSV to request a context switch. */                                                       
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;                                                          

/* Barriers are normally not required but do ensure the code is completely                            
within the specified behaviour for the architecture. */                                               
__asm volatile( "dsb" );                                                                                                     
__asm volatile( "isb" );   

could potentially be rearanged by the optimizer to be equivalent to

/* Barriers are normally not required but do ensure the code is completely                            
within the specified behaviour for the architecture. */                                               
__asm volatile( "dsb" );                                                                              
__asm volatile( "isb" );

/* Set a PendSV to request a context switch. */                                                       
*( portNVIC_INT_CTRL ) = portNVIC_PENDSVSET;                                                          

Or could it?

A barrier like: asm volatile("":::"memory"); would guarantee it, but I don't know enough about GCC to say for sure that it is needed.

I just noted that this is how linux kernel does it:

173 #define isb() __asm__ __volatile__ ("isb" : : : "memory")
174 #define dsb() __asm__ __volatile__ ("dsb" : : : "memory")


[ 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