пользуюсь версией - FreeRTOS.org V5.0.3
мк. - STM32F103.
хочу организовать прием с последовательного порта в кольцевой буфер и по достижению "тишины" на порте, больше заданной (скажем 10мс), либо при заполнении кольцевого буфера более чем на 60% начать разбор принятых данных
тик оси = 1 мс.
в прерывании USART1:
Код
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( SET == USART_GetITStatus( USART1, USART_IT_RXNE ) )
{
u16 b;
USART_ClearITPendingBit( USART1, USART_IT_RXNE );
b = USART_ReceiveData( USART1 );
if( !(USART1->SR & (USART_FLAG_ORE | USART_FLAG_FE | USART_FLAG_PE | USART_FLAG_NE) ) )
{
CB_Push( cb_rx, b );// помещает байт в конец циклического буфера
// использую очередь для индикации "приема"
xQueueSendFromISR( rx_q, &b, &xHigherPriorityTaskWoken);
}
}
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
if( SET == USART_GetITStatus( USART1, USART_IT_RXNE ) )
{
u16 b;
USART_ClearITPendingBit( USART1, USART_IT_RXNE );
b = USART_ReceiveData( USART1 );
if( !(USART1->SR & (USART_FLAG_ORE | USART_FLAG_FE | USART_FLAG_PE | USART_FLAG_NE) ) )
{
CB_Push( cb_rx, b );// помещает байт в конец циклического буфера
// использую очередь для индикации "приема"
xQueueSendFromISR( rx_q, &b, &xHigherPriorityTaskWoken);
}
}
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
задача обработчик:
Код
void Task( void * pvParameters)
{
u16 q_mes;
for(;; )
{
if( pdFALSE == xQueueReceive( rx_q, (void *)&q_mes, 10 )
|| CB_GetFreeSize(cb_rx) < 100 )
{
// если здесь значит за 10 мс не было байт либо в буфере осталось
// место для < 100 байт
}
}
}
{
u16 q_mes;
for(;; )
{
if( pdFALSE == xQueueReceive( rx_q, (void *)&q_mes, 10 )
|| CB_GetFreeSize(cb_rx) < 100 )
{
// если здесь значит за 10 мс не было байт либо в буфере осталось
// место для < 100 байт
}
}
}
в результате зацикливается тут FreeRTOS\Source\list.c :
Код
void vListInsert( xList *pxList, xListItem *pxNewListItem )
{
volatile xListItem *pxIterator;
portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */
xValueOfInsertion = pxNewListItem->xItemValue;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
// <-------------- из этого цикла не выходит по причине
// pxIterator = pxIterator->pxNext, в итоге указывает на самого же себя и соотв. если
// pxIterator->pxNext->xItemValue <= xValueOfInsertion то уже и не выйдет никогда...
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
{
volatile xListItem *pxIterator;
portTickType xValueOfInsertion;
/* Insert the new list item into the list, sorted in ulListItem order. */
xValueOfInsertion = pxNewListItem->xItemValue;
/* If the list already contains a list item with the same item value then
the new list item should be placed after it. This ensures that TCB's which
are stored in ready lists (all of which have the same ulListItem value)
get an equal share of the CPU. However, if the xItemValue is the same as
the back marker the iteration loop below will not end. This means we need
to guard against this by checking the value first and modifying the
algorithm slightly if necessary. */
if( xValueOfInsertion == portMAX_DELAY )
{
pxIterator = pxList->xListEnd.pxPrevious;
}
else
{
for( pxIterator = ( xListItem * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
{
/* There is nothing to do here, we are just iterating to the
wanted insertion position. */
// <-------------- из этого цикла не выходит по причине
// pxIterator = pxIterator->pxNext, в итоге указывает на самого же себя и соотв. если
// pxIterator->pxNext->xItemValue <= xValueOfInsertion то уже и не выйдет никогда...
}
}
pxNewListItem->pxNext = pxIterator->pxNext;
pxNewListItem->pxNext->pxPrevious = ( volatile xListItem * ) pxNewListItem;
pxNewListItem->pxPrevious = pxIterator;
pxIterator->pxNext = ( volatile xListItem * ) pxNewListItem;
/* Remember which list the item is in. This allows fast removal of the
item later. */
pxNewListItem->pvContainer = ( void * ) pxList;
( pxList->uxNumberOfItems )++;
}
объясните пожалуйста где моя ошибка и как кто организует работу последовательного порта средствами FreeRTOS.
З.Ы. я смотрел примеры когда принятые данные помещаются в очередь FreeRTOS, а затем в отдельном потоке извлекаются, но в моем случае не вижу смысла организовывать работу таким образом.