Wiced sdk using freertos semaphore fundamental error

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Problem:

Wiced with freertos working incorectly, because using counting semaphore.

Quick way to resolve in fuction hostinitsemaphore create mutex with xCreateSemaphoreBinary.

And need remove 2 assert in hostsetsemaphore and it must allways return true.

Example problem:

1. Uart init semaphore and enable interupt

2. Interupt occurs - counting semaphore increase self value to 1

3. UartReceive fuction getsemaphore for waiting data - semaphore decrease it value to 0 but not block. Uart receive 0 bytes or not full pscket..

4. Goto 2 point....

After correction:

1. Uart init semaphore and enable interupt

2. Interupt occurs - unlock semaphore

3. UartReceive fuction getsemaphore (lock) for waiting data  in block mode.

4. Interupt fullrx occurs setsemaphore (unlock)  task in 3 point receive full packet.

Similar scenarious can occurs anywhere.

0 Likes
2 Replies
AxLi_1746341
Level 7
Level 7
10 comments on KBA 5 comments on KBA First comment on KBA

Do you mean change the implement of host_rtos_init_semaphore():

to use xSemaphoreCreateBinary() instead of xSemaphoreCreateCounting()?

The host_rtos_init_semaphore() is used in many places, you need to make sure

it works for all users with your change.

I don't quite understand that you mentioned:

3. semaphore decrease it value to 0 but not block. Uart receive 0 bytes or not full pscket..

BTW, any chance to post the code you changed?

0 Likes
Anonymous
Not applicable

>The host_rtos_init_semaphore() is used in many places, you need to make sure

>it works for all users with your change.

Sorry, I can't guarantee nothing, but with this changes system with FreeRtos working Ok for me.  (some days)

I found in one place inserted "brilliant" workaround code  in exmp.

platform_result_t platform_uart_transmit_bytes( platform_uart_driver_t* driver, const uint8_t* data_out, uint32_t size )

{......

     host_rtos_get_semaphore( &driver->tx_complete, NEVER_TIMEOUT, WICED_TRUE );//darius posible not blocked

     while ( ( driver->peripheral->port->SR & USART_SR_TC ) == 0 )//darius workaround - system polling state bit.... so system overloaded

     {

     }

......

}

>I don't quite understand that you mentioned:

>>3. semaphore decrease it value to 0 but not block. Uart receive 0 bytes or not full pscket..  

counting semaphore  will stay in block mode, when it counter is zero, and  user want take it.

exmp.

semaphore = xSemaphoreCreateCounting( (unsigned portBASE_TYPE) 0x7fffffff, (unsigned portBASE_TYPE) 0 );

xSemaphoreGive( semaphore );  //blocked

semaphore = xSemaphoreCreateCounting( (unsigned portBASE_TYPE) 0x7fffffff, (unsigned portBASE_TYPE) 0 );

xSemaphoreTake(semaphore);//increment from 0 to 1

xSemaphoreGive(semaphore );  ///not blocked  decrement from 1 to 0

xSemaphoreGive( semaphore );  //blocked nothing to Give

semaphore = xSemaphoreCreateCounting( (unsigned portBASE_TYPE) 0x7fffffff, (unsigned portBASE_TYPE) 0 );

xSemaphoreTake(semaphore);//increment from 0 to 1

xSemaphoreTake(semaphore);//increment from 1 to 2

xSemaphoreGive(semaphore );  ///not blocked  decrement from 2 to 1

xSemaphoreGive(semaphore );  ///not blocked  decrement from 1 to 0

xSemaphoreGive( semaphore );  //blocked

>>BTW, any chance to post the code you changed?

No problem.

wwd_result_t host_rtos_init_semaphore(  /*@special@*/ /*@out@*/ host_semaphore_type_t* semaphore ) /*@allocates *semaphore@*/  /*@defines **semaphore@*/

{

    /*

     Note that binary semaphores created using

     * the vSemaphoreCreateBinary() macro are created in a state such that the

     * first call to 'take' the semaphore would pass, whereas binary semaphores

     * created using xSemaphoreCreateBinary() are created in a state such that the

     * the semaphore must first be 'given' before it can be 'taken'.

    */

    *semaphore =xSemaphoreCreateBinary();

    //darius counting semaphore with not limited counter

    //*semaphore = xSemaphoreCreateCounting( (unsigned portBASE_TYPE) 0x7fffffff, (unsigned portBASE_TYPE) 0 );

    /*@-compdef@*/ /* Lint doesnt realise allocation has occurred */

    return ( *semaphore != NULL ) ? WWD_SUCCESS : WWD_SEMAPHORE_ERROR;

    /*@+compdef@*/

}

//darius need remove  2 asserts and allways return true

wwd_result_t host_rtos_set_semaphore( host_semaphore_type_t* semaphore, wiced_bool_t called_from_ISR )

{

#if 0

    signed portBASE_TYPE result;

    if ( called_from_ISR == WICED_TRUE )

    {

        signed portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE;//darius darome init

        result = xSemaphoreGiveFromISR( *semaphore, &xHigherPriorityTaskWoken );

        wiced_assert( "Unable to set semaphore", result == pdTRUE );

        /* If xSemaphoreGiveFromISR() unblocked a task, and the unblocked task has

         * a higher priority than the currently executing task, then

         * xHigherPriorityTaskWoken will have been set to pdTRUE and this ISR should

         * return directly to the higher priority unblocked task.

         */

        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

    }

    else

    {

        result = xSemaphoreGive( *semaphore );

        wiced_assert( "Unable to set semaphore", result == pdTRUE );

    }

    return ( result == pdPASS )? WWD_SUCCESS : WWD_SEMAPHORE_ERROR;

#else

    if ( called_from_ISR == WICED_TRUE )

    {

        signed portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE;//darius darome init

        xSemaphoreGiveFromISR( *semaphore, &xHigherPriorityTaskWoken );

        //wiced_assert( "Unable to set semaphore", result == pdTRUE );

        /* If xSemaphoreGiveFromISR() unblocked a task, and the unblocked task has

         * a higher priority than the currently executing task, then

         * xHigherPriorityTaskWoken will have been set to pdTRUE and this ISR should

         * return directly to the higher priority unblocked task.

         */

        portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );

    }

    else

    {

        xSemaphoreGive( *semaphore );

    }

    //darius   if give more times  its  Ok

    return WWD_SUCCESS;

#endif

}

0 Likes