Quality RTOS & Embedded Software

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




Loading

Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 15, 2013

I make only one task with priority 3.

define configUSE_PREEMPTION 1

My task is bloked by waiting byte from queue.

xQueueReceive(uart485Queue, &byte, portMAX_DELAY);

Byte is sending to queue from ISR

void USART1IRQHandler(void) { static uint8t byte; static portBASETYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; if(USART1SRbit.RXNE == 1) { byte = USART1DR; xQueueSendToBackFromISR(uart485Queue, &byte, &xHigherPriorityTaskWoken); } //portENDSWITCHINGISR(xHigherPriorityTaskWoken == pdTRUE ); }

After calling xQueueSendToBackFromISR() my task changes state and gets READY. If i call portENDSWITCHINGISR() in the end of the USART1IRQHandler, that my task gives CPU, changes state and gets RUNNING. My task continue works. But if i don't call portENDSWITCHING_ISR(), my task must gets CPU in the end of system tick. In the hendler of the system timer must call scheduler. But scheduler does call and switch context no occur. Why? My singular task is ready and only IDLE running all times. Why? Where in the hendler of the system timer calling scheduler and where checking for tasks ready?

The same code works with FreeRTOS v7.2.0 and early.

ps FreeRTOS 7.6.0, port Cortex-M3, IAR.


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by rtel on December 15, 2013

Please confirm that all the RTOS code you are running is from the V7.6.0 distribution. What I think you are describing could be the case if you updated the core files found in FreeRTOS/source from V7.2.0 to V7.6.0, but left the port layer files found in FreeRTOS/source/portable/IAR/ARM_CM3 at V7.2.0.

Please ensure you report back even if that is your problem so we can be assured there are no issues.

Regards.


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 16, 2013

I am sure the files from V7.2.0 use in project with V7.2.0, and the files from V7.6.0 use in project with V7.6.0. Initially, i was doing project with V7.6.0. By accident i detected that one of my task with highest priority didn't work. Its state was READY. I studied of rtos source code and found out that the scheduler isn't calling from the hendler of the system timer. Then i downdated FreeRTOS/source from V7.6.0 to V7.2.0 and my task worked.

You can see and compare hendler V7.6.0 ( FreeRTOSV7.6.0FreeRTOSSourceportableIARARM_CM3port.c )

void xPortSysTickHandler( void ) { /* The SysTick runs at the lowest interrupt priority, so when this interrupt executes all interrupts must be unmasked. There is therefore no need to save and then restore the interrupt mask value as its value is already known. / ( void ) portSETINTERRUPTMASKFROMISR(); { / Increment the RTOS tick. / if( xTaskIncrementTick() != pdFALSE ) { / A context switch is required. Context switching is performed in the PendSV interrupt. Pend the PendSV interrupt. */ portNVICINTCTRLREG = portNVICPENDSVSETBIT; } } portCLEARINTERRUPTMASKFROM_ISR( 0 ); }

...compare with hendler V7.2.0 ( FreeRTOSV7.2.0FreeRTOSSourceportableIARARM_CM3port.c )

void xPortSysTickHandler( void ) { unsigned long ulDummy;

/* If using preemption, also force a context switch. */
#if configUSE_PREEMPTION == 1
	*(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;	
#endif

ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();
{
	vTaskIncrementTick();
}
portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );

}

Where calling scheduler in V7.6.0? Also i studied of rtos source code another ports. For example ATMega323: V7.2.0 vPortYieldFromTick: portSAVECONTEXT ; Save the context of the current task. call vTaskIncrementTick ; Call the timer tick function. call vTaskSwitchContext ; Call the scheduler. portRESTORECONTEXT ; Restore the context of whichever task the ... ret ; ... scheduler decided should run.

V7.6.0 vPortYieldFromTick: portSAVECONTEXT ; Save the context of the current task. call xTaskIncrementTick ; Call the timer tick function. tst r16 breq SkipTaskSwitch call vTaskSwitchContext ; Call the scheduler. SkipTaskSwitch: portRESTORECONTEXT ; Restore the context of whichever task the ... ret ; ... scheduler decided should run.

Why in the V7.6.0 is SkipTaskSwitch?


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by rtel on December 16, 2013

Please try the following sequence when you build with portENDSWITCHINGISR() commented out, and report back where you think the problem occurs.

  1. Put a break point on your call to xQueueSendToBackFromISR(), then run the code until the break point is hit.
  2. In the debugger, step into the xQueueSendToBackFromISR() function, you should enter the xQueueGenericSendFromISR() function, from which xTaskRemoveFromEventList() is called. Step into xTaskRemoveFromEventList().
  3. Inside cTaskRemoveFromEventList() there is the line of code:
    if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )
    which, if there is a task waiting on the queue, and the task's priority is above the idle priority, should evaluate to true, which in turn will cause xYieldPending to be set to pdTRUE.
  4. When you get to the line that sets xYieldPending to pdTRUE, put a break point on the first line of xTaskIncrementTick() which is in tasks.c. Run the code again until the new break point is hit.
  5. At the very end of xTaskIncrementTick() you will find the following lines of code:
    if( xYieldPending != pdFALSE )
    {
        xSwitchRequired = pdTRUE;
    }
    
    xSwitchRequired is the functions return value.
  6. Step out of xTaskIncrementTick() and you will end up in the code you posted in your previous post.
    if( xTaskIncrementTick() != pdFALSE )
    {
        / A context switch is required. Context switching is performed in
        the PendSV interrupt. Pend the PendSV interrupt. /
        portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
    }
    
    As xTaskIncrementTick() returns pdTRUE (because xSwitchRequired equaled pdTRUE) the PendSV interrupt is pended to request a context switch.

So the logic shows a context switch should happen. At which point do you see the actual behaviour deviate from this sequence? Please ensure to report back as it is very important to know if you think there is an error somewhere.

Regards.


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 16, 2013

Hello. Thank you for replay and help. I try you steps in the debbug mode and ..... and make several screenshort... step-by-step. You can see them in attach. I don't understand.... where and when xYieldPending must be set to pdTRUE?

ps if you need I can send my project

Attachments

Bug%20FreeRTOS.pdf (1137196 bytes)

Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by rtel on December 16, 2013

Thanks for such detailed screen shots. I can see in image 9 that this is not FreeRTOS V7.6.0, as V7.6.0 contains the following code:

if( pxUnblockedTCB->uxPriority >= pxCurrentTCB->uxPriority )
{
    /* Return true if the task removed from the event list has
    a higher priority than the calling task.  This allows
    the calling task to know if it should force a context
    switch now. */
    xReturn = pdTRUE;

    /* Mark that a yield is pending in case the user is not using the
    "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */
    xYieldPending = pdTRUE;
}
else
{
    xReturn = pdFALSE;
}

The lines in red are missing in your code.

Regards.

[edit the red didn't come out - but it is the code with the comment "mark that a yield...." that is missing in your code - this forum is hard to post code too!]


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 16, 2013

Thank you for you help. I deleted all source of FreeRTOS and load V7.6.0 again. My task works. Thank yo very match and i'm sorry for my mistake made through lack of attention.

But happiness was short. I was sending bytes whit period 1 sec to my programm. For the short haul my task worked, than it hang. I stoped running and begin step in the debag mode. My task was READY, queue was full and xYieldPending == 0. Something was wrong, and context doesn't switch to my task. In the handler of system timer no check tasks for ready. Why?

Attachments

FreeRTOS%202.pdf (386441 bytes)

Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by edwards3 on December 16, 2013

If this happened after it has been running for a while then the most likely cause is a bad interrupt priority assignment. Do you have configASSERT() defined?


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 16, 2013

No. I don't have configASSERT() defined. I copy-past FreeRTOSConfig.h from FreeRTOSV7.6.0FreeRTOSDemoCORTEXSTM32F103IAR


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by edwards3 on December 16, 2013

I will rephrase that. If you don't have configASSERT() defined then define it because it will help trap bad interrupt priority assignments. http://www.freertos.org/FAQHelp.html


Why scheduler does wokr in FreeRTOS from 7.5 version

Posted by juvf on December 17, 2013

You are right. configASSERT() shows that I made mistakes with assignt peripheries priority.

Freertos works excellent.

Thank you for your help.


[ 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