Quality RTOS & Embedded Software

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


Loading

STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Werner Almesberger on July 22, 2013
portable/GCC/ARM_CM3/port.c:vPortValidateInterruptPriority requires that SCB_AIRCR.PRIGROUP be zero. It assumes that zero means that all the bits are used for group/preemption priority and none for a subpriority.

On STM32F2/4, only the values 3 through 7 are documented for PRIGROUP, with 3 meaning that there are no subpriority bits. I tried setting PRIGROUP to zero in an attempt to please vPortValidateInterruptPriority, but this causes great confusion in interrupt handling (I still get some interrupts, but others fire just once, never to be seen again).

Setting PRIGROUP to 3 and adapting the test in vPortValidateInterruptPriority accordingly makes things work as expected.

I suppose this has something to do with the STM32 only having four priority bits. Perhaps the correct value for PRIGRP should be calculated as (configPRIO_BITS == 8 ? 0 : 7-configPRIO_BITS) ?

The check for 8 is necessary because - according to Table 4.18 on http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/Cihehdge.html - even 0 still leaves one subpriority bit, so on a core that actually implemented all 8 bits, the calculation would wrap around 0.

I've seen this on an STM32F207 (CM3) and it seems that the same should also apply to STM32F4xxx (CM4F), and possibly others.

- Werner

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Richard on July 22, 2013
Thanks for your report. I can replicate this on an STM32 and will investigate further. The function was tested on Cortex-M parts from three different manufacturers (two with 4 priority bits, one with three priority bits), but not unfortunately the STM32, so it might be STM32 specific.

I will report back here when I have more information.

Regards.

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Richard on July 22, 2013
This looks like it might be related to a persistent incompatibility between the ST peripheral driver library and generic Cortex-M code.

The binary point (priority group) bits are actually defaulted to zero when the Cortex-M powers up, so on all implementations of the Cortex-M 0 is a valid number as that is Cortex-M specific, not STM32 specific. Zero is a generic value that will work on all chips, and is normally never changed during the lifetime of an application. vPortValidateInterruptPriority() checks that the value is zero. However....

Due to the implementation of the STM32 peripheral library we have always had to provide specific instruction to STM32 users (note numerous support request answers and the bold red text on FreeRTOS.org web pages specific to Cortex-M) to ensure they call NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ) before starting the scheduler. This is an extra step necessary for STM32 applications only. That call changes the binary point setting, and causes vPortValidateInterruptPriority() to trigger a failure, but is necessary in order to use other STM32 peripheral driver functions. A colleague of mine has just pointed out/reminded me as to why this is.

If you look at the implementation of the function NVIC_Init() library function you will see the following code:

    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
tmppre = (0x4 - tmppriority);


Now assume you pass the priority in as 15 when the binary point register is 0. tmppriority will then be calculated as:

tmppriority = (0x700 - 0) >> 8;
= 7;


On the next line the 4 is hard coded, resulting in tmppre being calculated as:
tmppre = 4 - 7;


... which is negative (actually as this is unsigned maths it is a huge positive), and you have a problem.



The question now is, what to do about this? We can't have a portable layer that is specific to the STM32, nor can we force users of all other chips to set a binary point value. I suspect we will have to issue a maintenance release that implements
vPortValidateInterruptPriority() to check for either 0 or an acceptable value given the number of implemented priority bits. That will naturally add some overhead.

I appreciate you pointed this out so quickly.

Regards.

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Werner Almesberger on July 22, 2013
Thanks for the amazingly quick analysis ! It is indeed unfortunate that this ST quirk produces a regression in FreeRTOS.

I think that allowing all values that produce the desired behaviour would be the best choice. With a decent compiler, a test for PRIGROUP >= (configPRIO_BITS == 8 ? 0 : 7-configPRIO_BITS) should have negligible overhead (if any) compared to the current check, since all the calculations are with constants anyway.

Thanks,
- Werner

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Richard on July 22, 2013
I have updated the code to perform a "less than or equal to a maximum permissible value" check in place of the "equals zero" check. I have tested this on the STM32 first this time :o)

Currently I have it in GCC only. Which compiler are you using? If you are using GCC I can send you the file to try. If you are using a different compiler then I will update the port layer for that compiler next so you can try it.

If you want to try it then send an email to the email address on the Real Time Engineers Contact page so I have your address. Please don't post your email address to this forum.

Regards.

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Werner Almesberger on July 22, 2013
Yes, I use GCC. I sent a mail to the info address (there's no openly visible e-mail address on the contact page). BTW, my e-mail address isn't exactly a secret, so getting an extra serving of spam wouldn't be a concern :)

Thanks,
- Werner

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Franz on July 23, 2013
Hi!

I assume this problem is also occuring with my setup: I am using an STM32F4, since the latest FreeRTOS 7.5.0 I get stuck with vPortValidateInterruptPriority(). The priority settings are right, as the documentation of FreeRTOS instructs it: (PRIORITY_GROUP to 4 and all my ISRs which use FreeRTOS API calls have a priority lower than configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 5). In my case the USART2 Priority is set to 9.

Can you please post your solution here, so that I can try it, or are the chages too much to post it here? I am also using GCC.

Kind regards,
franz

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Franz on July 24, 2013
Is there any chance to get an answer on this?

thanks in advance, regards
franz

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Richard on July 24, 2013
Sorry - I missed your email. The solution is already provided in the FreeRTOS V7.5.2 maintenance release available from Sourceforge.


Regards.

RE: STM32F2/4 vs. vPortValidateInterruptPriority

Posted by Franz on July 24, 2013
Thanks! I will try it!

Regards,
franz


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


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

Latest News

NXP tweet showing LPC5500 (ARMv8-M Cortex-M33) running FreeRTOS.

Meet Richard Barry and learn about running FreeRTOS on RISC-V at FOSDEM 2019

Version 10.1.1 of the FreeRTOS kernel is available for immediate download. MIT licensed.

View a recording of the "OTA Update Security and Reliability" webinar, presented by TI and AWS.


Careers

FreeRTOS and other embedded software careers at AWS.



FreeRTOS Partners

ARM Connected RTOS partner for all ARM microcontroller cores

Espressif ESP32

IAR Partner

Microchip Premier RTOS Partner

RTOS partner of NXP for all NXP ARM microcontrollers

Renesas

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

Xilinx Microblaze and Zynq partner