FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [January 2015 Threads] Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 22, 2015 Hi,
I just started my first freeRTOS project, but I have some behavior I can't solve. In my task I alternately call a read and a write function. Both should wait/block until an special interrupt occurs. On first call I create a binary semaphore (one per function, read as an example):
~~~~~~
:::c
if (NULL == ReadSyncObj) {
if (NULL == (ReadSyncObj = xSemaphoreCreateBinary())) {
return (RES_NOTRDY);
}
xSemaphoreTake(ReadSyncObj, 10 );
}
~~~~~~
The interrupt handler is shared for both:
~~~~~~
:::c
static void _ISRHandler() {
status = GetIntStatus();
xHigherPTaskWokenRead = pdFALSE;
xHigherPTaskWokenWrite = pdFALSE;
if (status & READ_READY) {
ClearInterrupt(READ_READY);
(void)xSemaphoreGiveFromISR(ReadSyncObj, &xHigherPTaskWokenRead);
portYIELD_FROM_ISR(xHigherPTaskWokenRead);
return;
}
if (status & WRITE_READY) {
ClearInterrupt(WRITE_READY);
(void)xSemaphoreGiveFromISR(WriteSyncObj, &xHigherPTaskWokenWrite);
portYIELD_FROM_ISR(xHigherPTaskWokenWrite);
return;
}
}
~~~~~~
In the read and write functions I have the transfer started and the I take the semaphore:
~~~~~~
:::c
startReadOperation();
//fprintf(stdout, "r1\r\n");
(void)xSemaphoreTake(ReadSyncObj, portMAX_DELAY);
//fprintf(stdout, "r2\r\n");
~~~~~~
My problem is, that I can't get past the xSemaphoreTake very often and never leave the idle task again. This behavior never occurrs if the fprintf functions are used, everything is working fine then.
My task has a priority of one and should meet the
~~~~~~
:::c
define configMAXSYSCALLINTERRUPT_PRIORITY ( 1 << 5 )
~~~~~~
requirement.
I am grateful for any suggestion
Jon
Function didn't get past xSemaphoreTake ... sometimesPosted by davedoors on January 22, 2015 Nothing obviously wrong. Do you have configASSERT() defined?
Is it possible both READREADY and WRITEREADY get set at the same time in your interrupt handler? If so it would be better to remove the return calls. You can then use the same HigherPriorityTaskWoken variable in both xSemaphoreGiveFromISR() calls and only call portYIELDFROMISR() once at the end of the function.
If you are stuck on xSemaphoreTake() I guess the interrupt just has not executed. Is that the case? It is best not to use portMAX_DELAY in this case because your program will hang if the interrupt does not execute. Better to use a finite delay then clean up if xSemaphoreTake() times out without taking the semaphore.
In the latest FreeRTOS you can use a task notification instead of a semaphore http://www.freertos.org/RTOSTaskNotificationAsBinary_Semaphore.html
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 23, 2015 Hi Dave,
thanks for your response!
Nothing obviously wrong. Do you have configASSERT() defined?
No, it is not defined.
Is it possible both READREADY and WRITEREADY get set at the same time in your interrupt handler? If so it would be better to remove the return calls. You can then use the same HigherPriorityTaskWoken variable in both xSemaphoreGiveFromISR() calls and only call portYIELDFROMISR() once at the end of the function.
They should never appear at the same time. But who knows? ;-)
If you are stuck on xSemaphoreTake() I guess the interrupt just has not executed. Is that the case? It is best not to use portMAX_DELAY in this case because your program will hang if the interrupt does not execute. Better to use a finite delay then clean up if xSemaphoreTake() times out without taking the semaphore.
I believe, that's not the case. If I delay the execution with "fprintf" everything is fine. It feels like some kind of timing problem, the interrupt might happen while xSemaphoreTake is in progress. Could that be a problem?
In the latest FreeRTOS you can use a task notification instead of a semaphore http://www.freertos.org/RTOSTaskNotificationAsBinary_Semaphore.html
Unfortunately I can't update my freeRTOS (8.0.1) at the moment.
Thanks again
Jon
Function didn't get past xSemaphoreTake ... sometimesPosted by rtel on January 23, 2015 Semaphores are designed to be accessible from interrupts and tasks
simultaneously - but that will only work if you interrupt priorities are
set correctly, so that is the first thing to double check.
Please defined configASSERT()
(http://www.freertos.org/a00110.html#configASSERT) as a first step. In
V8.0.1 that should trap and incorrect priority - let us know if that is
hit or not.
Regards.
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 23, 2015 Had to find a solution working with ccs, but it's up now.
Unfortunately I have no clue about the assembler part and what's going on. I get an assertion at "configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );" with ucCurrentPriority = 0x00 and ucMaxSysCallPriority = 32.
freeRTOSConfig.h:
~~~~~~
:::c
ifdef ccs
void vAssertCalled(const char *pcFile, unsigned long ulLine );
#define configASSERT(expr) if ( (expr) == 0) {
vAssertCalled( FILE , LINE );
}
endif
~~~~~~
port.c:
~~~~~~
:::c
if( configASSERT_DEFINED == 1 )
extern unsigned long ipsrFunc(void);
__asm(" .sect ".text:ipsrFunc"n"
" .clinkn"
" .thumbfunc ipsrFuncn"
" .thumbn"
" .global ipsrFuncn"
"ipsrFunc:n"
" mrs r0, ipsrn"
" bx lrn");
void vPortValidateInterruptPriority( void )
{
uint32_t ulCurrentInterrupt;
uint8_t ucCurrentPriority;
/* Obtain the number of the currently executing interrupt. */
#if defined(ccs)
ulCurrentInterrupt = ipsrFunc();
#else
/* Obtain the number of the currently executing interrupt. */
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
#endif
/* Is the interrupt number a user defined interrupt? */
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
{
~~~~~~
Function didn't get past xSemaphoreTake ... sometimesPosted by rtel on January 23, 2015 There isn't an official CCS port so I can tell you if your use of
ipsrFunc() is correct or not, but if it is then it looks as if interrupt
priorities are indeed your problem.
As different Cortex-M devices have a different number of priority bits
the first thing to do is ensure the hardware is described correctly in
the FreeRTOSConfig.h file. You can see an example between the lines 53
and 176 in this file:
http://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEXM4FATSAM4EAtmelStudio/src/config/FreeRTOSConfig.h
Next ensure you have read http://www.freertos.org/RTOS-Cortex-M3-M4.html
- especially the bits about ensuring you don't leave an interrupt
priority at its default value.
Regards.
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 23, 2015 Sorry for the following noob question, but how do I actually set the interrupt priority?
Function didn't get past xSemaphoreTake ... sometimesPosted by rtel on January 23, 2015 If you system is using CMSIS compatible libraries then there is a
function NVIC_SetPriority(). If you are using propriatory libraries
supplied by your chip or compiler vendor then check whatever
documentation they supplied. You can of course reference the Cortex-M
hardware manual, then peek and poke the priority registers yourself, but
I would not recommend that.
All the demos supplied by FreeRTOS will set a priority somewhere, so
that provides another reference.
Regards.
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 23, 2015 Ok thanks. I thought there has to be some kind of vPortSetInterruptPriority I have to modify/find/use.
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 23, 2015 I've managed to set the priority level of my interrupt handler and the assert is gone. Unfortunately the original problem still exists.
Function didn't get past xSemaphoreTake ... sometimesPosted by jon20015 on January 27, 2015 Sorry, I have forgotten to mention my current interrupt priority
~~~~~~
:::c
define INTPRIORITYLVL_1 0x20
~~~~~~
on Cortex M4. Any ideas are welcome.
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|