FreeRTOs with "error.h" ...

debugasm wrote on Wednesday, November 29, 2017:

Hi,

I use FreeRTOs v9.0.0 with Lwip v1.4.1 and socket thread uses “error.h” with error variable to get fault connection, timeout, ecc.

The question:

(1) The “error” variable is FreeRTOs Thread safe or reentrant ?

(2) How check if “error” is visible only for thread and not overwritten by other threads ?

Thanks very much.

debugasm

rtel wrote on Wednesday, November 29, 2017:

Sorry, don’t know, that is part of lwiP not FreeRTOS.

debugasm wrote on Thursday, November 30, 2017:

Hi,

Sorry, don’t know, that is part of lwiP not FreeRTOS.

You are right, but FreeRTOs is also used with “libc” that provides “errno”, perhaps one possibility is to modify the “get_errno” and “set_errno” routines to write the error in a task variable using “configNUM_THREAD_LOCAL_STORAGE_POINTERS”.

I can try to implement it.

Thanks.

debugasm

heinbali01 wrote on Thursday, November 30, 2017:

That’s indeed the way to go.

When defining configNUM_THREAD_LOCAL_STORAGE_POINTERS, a number of objects can be stored in the task’s context.

This object has the size of a pointer, but it does not have to be a pointer. An integer may be casted and stored as a pointer.

The FreeRTOS+FAT library already uses 3 of these storage pointers, one of the to stored the last errno seen. Another pointer stores the CWD (current working directory).

Here are the two access functions:

/* The errno is stored in a thread local buffer. */
static portINLINE void stdioSET_ERRNO( int iErrno )
{
	vTaskSetThreadLocalStoragePointer( NULL, ffconfigCWD_THREAD_LOCAL_INDEX, ( void * ) ( iErrno ) );
}

static portINLINE int stdioGET_ERRNO( void )
{
void *pvResult;

	pvResult = pvTaskGetThreadLocalStoragePointer( ( TaskHandle_t )NULL, ffconfigCWD_THREAD_LOCAL_INDEX );
	return ( int ) pvResult;
}

I know that in some environments errno has an instance per thread in some magic way, but I don’t think that it will work together with FreeRTOS.

Regards,

debugasm wrote on Thursday, November 30, 2017:

Hi,

I know that in some environments errno has an instance per thread in some magic way, but I
don’t think that it will work together with FreeRTOS.

The Lwip have a routine to set “errno”, I just need to modify this function to use FreeRTOs. It should not be difficult.

Thanks very much.

debugasm

heinbali01 wrote on Thursday, November 30, 2017:

Not everyone appreciates C++, but you could make a nice little class for errno.

class CErrno {
public:
    operator int()
    {
    void *pvResult;

        pvResult = pvTaskGetThreadLocalStoragePointer( ( TaskHandle_t )NULL, ffconfigCWD_THREAD_LOCAL_INDEX );
        return ( int ) pvResult;
    }
    int operator =(int aValue)
    {
        vTaskSetThreadLocalStoragePointer( NULL, ffconfigCWD_THREAD_LOCAL_INDEX, ( void * ) ( aValue ) );
        return aValue;
    }
};

CErrno myErrno;

Now the same instance of myErrno can be used by any task:

    myErrno = 0;
    /* call function */
    if( myErrno == 2 )
    {
    }

thomask wrote on Saturday, December 02, 2017:

Hein Tibosch wrote:

I know that in some environments errno has an instance per thread in some magic way,
but I don’t think that it will work together with FreeRTOS.

debugasm wrote:

The Lwip have a routine to set “errno”, I just need to modify this function to use FreeRTOs.

If you are using newlib, you only have to set

configUSE_NEWLIB_REENTRANT to 1

in your FreeRTOSConfig.h

In newlib,“errno” and other global variables like “stdout” are defined as macros and will actually point to a task local reent structure. On single core systems, there’s just a pointer called “_impure_ptr” that is updated by FreeRTOS on task switch (see task.c).

heinbali01 wrote on Sunday, December 03, 2017:

If you are using newlib, you only have to set
configUSE_NEWLIB_REENTRANT to 1
in your FreeRTOSConfig.h

Oops, yes, I had seen it but as I rarely use newlib, I forgot about it.

Thanks for this explanation.

debugasm wrote on Monday, December 04, 2017:

I use Xilinx SDK that use “libc”. I don’t have found a way to compile “newlibc” and use it in this environment. So I was building a new library to be used with FreeRTOs usable even in debugging unlike other libraries.

Why does FreeRTOS team not develop an internal library like “Micrium μc / os-xxx”, which integrates the main libraries and then free themselves from external bookcases ?