Перейти к содержанию
    

Проблемы с двоичным семафором

В main создаю семафор, в прерываниях использую xSemaphoreGiveFromISR(), в задаче-обработчике использую xSemaphoreTake() и принудительное переключение контекста vPortYieldFromISR()

 

возникает проблема в этом месте

 

signed portBASE_TYPE xQueueGenericSendFromISR( xQueueHandle pxQueue, const void * const pvItemToQueue, signed portBASE_TYPE *pxHigherPriorityTaskWoken, portBASE_TYPE xCopyPosition )

{

signed portBASE_TYPE xReturn;

unsigned portBASE_TYPE uxSavedInterruptStatus;

 

/* Similar to xQueueGenericSend, except we don't block if there is no room

in the queue. Also we don't directly wake a task that was blocked on a

queue read, instead we return a flag to say whether a context switch is

required or not (i.e. has a task with a higher priority than us been woken

by this post). */

uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();

{

if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )

{

traceQUEUE_SEND_FROM_ISR( pxQueue );

 

prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );

 

/* If the queue is locked we do not alter the event list. This will

be done when the queue is unlocked later. */

if( pxQueue->xTxLock == queueUNLOCKED )

{

if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )

{

if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )

{

/* The task waiting has a higher priority so record that a

context switch is required. */

*pxHigherPriorityTaskWoken = pdTRUE;

}

}

}

else

{

/* Increment the lock count so the task that unlocks the queue

knows that data was posted while it was locked. */

++( pxQueue->xTxLock );

}

 

xReturn = pdPASS;

}

else

{

traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue );

xReturn = errQUEUE_FULL;

}

}

portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

 

return xReturn;

}

 

if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )

 

 

uxMessagesWaiting больше uxLength и возвращается xReturn = errQUEUE_FULL;

 

что делать????

 

Из Курница написано:

- errQUEUE_FULL — означает, что дан­ные не записаны в очередь, так как очередь заполнена. Если определена продолжительность тайм-аута (пара­метр xTicksToWait не равен «О» или portMAX_DELAY), то возврат значения errQUEUE_FULL говорит о том, что тайм-аут завершен и свободное место в очереди так и не появилось.

 

в моем случае последнее, почему свободное место в очереди не появилось??

 

post-65449-1333703512_thumb.jpg

вот какие значения, откуда ? это же двоичный семафор, или я не так понимаю откуда такие значения

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не наблюдал подобных проблем у себя.

 

Какой порт FreeRTOS используется?

 

Проверьте:

1) Семафор создаётся перед его использованием?

2) Приоритет прерывания <= configMAX_SYSCALL_INTERRUPT_PRIORITY

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

семафор создан в мейне перед его использованием

 

порт под LM3S8962 eclipse code composer studio

 

#define configKERNEL_INTERRUPT_PRIORITY ( 7 << 5 ) /* Priority 7, or 255 as only the top three bits are implemented. This is the lowest priority. */

#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << 5 ) /* Priority 5, or 160 as only the top three bits are implemented. */

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В main создаю семафор, в прерываниях использую xSemaphoreGiveFromISR(), в задаче-обработчике использую xSemaphoreTake() и принудительное переключение контекста vPortYieldFromISR()

 

Какой приоритет прерывания, в котором Вы используете "xSemaphoreGiveFromISR()" ?

В прерывании вызываете portEND_SWITCHING_ISR(); ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) В прерываниях вызываю taskYIELD();

 

а в portmacro.h

такое:

 

/* Scheduler utilities. */

extern void vPortYieldFromISR( void );

 

#define portYIELD() vPortYieldFromISR()

 

#define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYieldFromISR()

/*-----------------------------------------------------------*/

 

т.е. посути taskYIELD(); равносильно portEND_SWITCHING_ISR( xSwitchRequired ) если xSwitchRequired

только не понял что за параметр - xSwitchRequired

 

2) Есть три канала АЦП их приоритеты прерываний 150, 149, 148

xSemaphoreGiveFromISR() вызывается в прерывании с приоритетом 148,

 

 

вываливается вот сюда где написано:

/* *** NOTE ***********************************************************

If you find your application is crashing here then likely causes are:

1) Stack overflow -

see http://www.freertos.org/Stacks-and-stack-o...w-checking.html

2) Incorrect interrupt priority assignment, especially on Cortex M3

parts where numerically high priority values denote low actual

interrupt priories, which can seem counter intuitive. See

configMAX_SYSCALL_INTERRUPT_PRIORITY on http://www.freertos.org/a00110.html

3) Calling an API function from within a critical section or when

the scheduler is suspended.

4) Using a queue or semaphore before it has been initialised or

before the scheduler has been started (are interrupts firing

before vTaskStartScheduler() has been called?).

See http://www.freertos.org/FAQHelp.html for more tips.

**********************************************************************/

кроме этих трех прерываний прерываний больше нет

 

не знаю на что и грешить ((

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...