- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>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
}