Quality RTOS & Embedded Software

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




Loading

_impure_ptr not setup when entering first task

Posted by beginend1 on October 4, 2013

Did I missed something or impureptr only is initialized in vTaskSwitchContext(). This makes (on my SMT32f4 uC) that before first context switch REENT points at global imputedata variable instead of first task reent variable.

Second: I think, that you should use REENT macro instead of _impureptr directly.

FreeRTOS version 7.5.2


_impure_ptr not setup when entering first task

Posted by richardbarry on October 4, 2013

Did I missed something or impureptr only is initialized in vTaskSwitchContext().

Hopefully you missed something, but like I say in the comments, I don't use the newlib stuff myself so I am reliant on the people who requested its existence to let me know if anything is wrong.

prvInitialiseTCBVariables() (in tasks.c) is called to initialise the task control block of a task when the task is created - not when the task is first switched in. prvInitialiseTCBVariables() contains the following code which, I think, means each task has its own initialised impure_ptr.

#if ( configUSE_NEWLIB_REENTRANT == 1 )
{
    /* Initialise this task's Newlib reent structure. */
    _REENT_INIT_PTR( ( &( pxTCB->xNewLib_reent ) ) );
}
#endif /* configUSE_NEWLIB_REENTRANT */

Second: I think, that you should use REENT macro instead of _impureptr directly

So the line: impureptr = &( pxCurrentTCB->xNewLib_reent );

should become?: REENT = &( pxCurrentTCB->xNewLibreent );

Is that right? Will everything else still compile ok?

Regards.


_impure_ptr not setup when entering first task

Posted by beginend1 on October 4, 2013

I am no talking about allocation of reent struct but initialization of _impureptr. Task switching properly changes impureptr but first task doesn't use the vTaskSwitchContext() but prvPortStartFirstTask() which is port specific, and this function does not touch impureptr. I've looked at the code and there is no clean solution. The impureptr can't be initialized in prvPortStartFirstTask() becouse tskTCB is opaque there. The only solution came up is initialization of impureptr just before call to prvPortStartFirstTask() and somehow in xTaskResumeAll() and/or in xTaskGenericCreate().


_impure_ptr not setup when entering first task

Posted by richardbarry on October 4, 2013

Ok, I understand now. So it is just the first execution of the first task that the pointer is not configured, not the first execution of every task.

When xPortStartScheduler() is called pxCurrentTCB already points to the task that will be started first, so I think the following code added before xPortStartScheduler() should do what you want.

#if ( configUSE_NEWLIB_REENTRANT == 1 )
{
	/* Switch Newlib's _impure_ptr variable to point to the _reent
	structure specific to the task that will run first. */
	_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
}
#endif /* configUSE_NEWLIB_REENTRANT */

Do you agree?

Regards.


_impure_ptr not setup when entering first task

Posted by beginend1 on October 4, 2013

Yes, this code is needed but NOT BEFORE calling xPortStartScheduler(). Some code may want to do something before creating tasks and starting scheduler. If you switch impureptr there you can mess up a lot of things (eg. stdin/out/err will be different, different errno variable, etc.). This must be done inside xPortStartScheduler(). I don't know FreeRTOS source so good to tell you if xPortStartScheduler() is the only place where _REEN should be guarded. Generally speaking, all places where pxCurrentTCB is changed and task is switched should follow _REEN synchronization with new task. My doubts are also places where you create/delete tasks when scheduler is suspended, this is the reason why I pointed out xTaskResumeAll() and xTaskGenericCreate().

And at the end I think that REENT = &( pxCurrentTCB->xNewLibreent ); will be ok :P


_impure_ptr not setup when entering first task

Posted by richardbarry on October 4, 2013

I understand your point, but I'm not sure I understand the danger of where I have placed the code.

The sequence is as follows:

1) Interrupts are disabled. 2) The pointer is set to be correct for the first task. 3) xPortStartScheduler() is called. 4) The first task starts to run

Interrupt are not enabled until the point that the first task start to run - and all the code executed in between steps 1 and 4 is FreeRTOS code. There is no possibility of any application code running during this time, so no possibility of any inadvertent calls to newlib.

I would be grateful if you could elaborate using this scenario so I can get a better understanding.

Regards.


_impure_ptr not setup when entering first task

Posted by beginend1 on October 5, 2013

Ok, looked again and you are right. I was thinking about vTaskStartScheduler() instead of xPortStartScheduler(). Your solution should work.


[ 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