Easyelectronics.ru

Электроника для всех
Текущее время: 12 дек 2018, 15:06

Часовой пояс: UTC + 5 часов




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 11 ноя 2016, 13:51 
Старожил

Зарегистрирован: 26 янв 2010, 21:47
Сообщения: 325
Форумчане.
Кто нить делал такое?
В смысле есть необходимость вычитать из очереди последний записанный элемент без изменения самой очереди. Из имеющихся в самой фриртосе есть ф-ция xQueuePeek():
"Функция xQueuePeek() используется для приема элемента из очереди без удаления элемента из очереди. Функция xQueuePeek() читает элемент из головы очереди без модификации данных, которые сохранены в очереди или, другими словами, без модификации порядка сохраненных данных в очереди (состояние очереди остается неизменным)."

А вот бы тоже самое, но из конца.

буду оч благодарен за помощь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 11 ноя 2016, 14:18 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 798
Такой функции, насколько я знаю, нет, но вы можете залезть в код ОС и ее добавить. Там все сравнительно просто.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 11 ноя 2016, 14:32 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1813
Откуда: Харьков
Только тогда теряется смысл очереди...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 11 ноя 2016, 15:49 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2707
Если по простому - при добавлении в очередь, дублируйте в свою глобальную переменную. Соответственно в ней всегда будет последний добавленный элемент.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 14 ноя 2016, 03:52 
Только пришел

Зарегистрирован: 09 фев 2012, 21:29
Сообщения: 15
Добавляйте в очередь этим - xQueueSendToFront


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вычитка из очереди без изменения очереди
СообщениеДобавлено: 25 ноя 2016, 14:08 
Заглядывает иногда

Зарегистрирован: 15 мар 2010, 11:04
Сообщения: 30
Эту задачку можно решить подсмотрев исходники queue.c и разобравшись с тек, как очередь устроена. Штатными функциями такое не решить.

Код:
// Выдираем из queue.c структуру описания очереди. Жаль, что она не в queue.h описана.

typedef struct QueueDefinition
{
   int8_t *pcHead;               /*< Points to the beginning of the queue storage area. */
   int8_t *pcTail;               /*< Points to the byte at the end of the queue storage area.  Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
   int8_t *pcWriteTo;            /*< Points to the free next place in the storage area. */

   union                     /* Use of a union is an exception to the coding standard to ensure two mutually exclusive structure members don't appear simultaneously (wasting RAM). */
   {
      int8_t *pcReadFrom;         /*< Points to the last place that a queued item was read from when the structure is used as a queue. */
      UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */
   } u;

   List_t xTasksWaitingToSend;      /*< List of tasks that are blocked waiting to post onto this queue.  Stored in priority order. */
   List_t xTasksWaitingToReceive;   /*< List of tasks that are blocked waiting to read from this queue.  Stored in priority order. */

   volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */
   UBaseType_t uxLength;         /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
   UBaseType_t uxItemSize;         /*< The size of each items that the queue will hold. */

   volatile int8_t cRxLock;      /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */
   volatile int8_t cTxLock;      /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked.  Set to queueUNLOCKED when the queue is not locked. */

   #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
      uint8_t ucStaticallyAllocated;   /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */
   #endif

   #if ( configUSE_QUEUE_SETS == 1 )
      struct QueueDefinition *pxQueueSetContainer;
   #endif

   #if ( configUSE_TRACE_FACILITY == 1 )
      UBaseType_t uxQueueNumber;
      uint8_t ucQueueType;
   #endif

} xQUEUE;

typedef xQUEUE Queue_t;

// Стандартный хендлер очереди
QueueHandle_t queue;

void task_tmp(void * param) {
   
    uint32_t num1 = 0;
    uint32_t num2;
   
    uint32_t i;
    uint32_t item_size;
    uint32_t messages;
    int8_t * read;
    int8_t * head;
    int8_t * tail;
   
    // Создаем очередь с 8 элементами uint32_t - это стандартная процедура, может делаться где угодно
    queue = xQueueCreate(8, sizeof(uint32_t));
   
    while (1) {
       
        // Складываем в очередь два элемента - это здесь только для примера, в реальности в очередь данные кладутся скорее всего в другой задаче или в прерывании
        xQueueSend(queue, &num1, 0); num1++;
        xQueueSend(queue, &num1, 0); num1++;
       
        // Складываем в локальные переменные данные структуры. Обертывание в критическую секцию гарантирует, что данные не поменяются
        taskENTER_CRITICAL();
        item_size = ((Queue_t *)queue)->uxItemSize; // Оно же sizeof(uint32_t), который мы передавали при создании очереди
        messages  = ((Queue_t *)queue)->uxMessagesWaiting;
        read      = ((Queue_t *)queue)->u.pcReadFrom;
        head      = ((Queue_t *)queue)->pcHead;
        tail      = ((Queue_t *)queue)->pcTail;
        taskEXIT_CRITICAL();
       
        // Проходим по очереди
        for (i=0; i<messages; i++) {
           
            // Инкрементируем указатель как в функции prvCopyDataFromQueue()
            read += item_size;
            if( read >= tail) {
                read = head;
            }
           
            // Получаем данные (не забываем привести тип к исходному)
            num2 = *(uint32_t *)read;
           
            // Тут данные надо как-то обработать видимо
            // ...
           
        }
       
    }
   
}


PS: ой, перечитал первое сообщение и понял, что нужно только последнее сообщение прочитать. В общем-то несложно переделать пример, чтобы получить только последнее.

Код:
// Складываем в локальные переменные данные структуры. Обертывание в критическую секцию гарантирует, что данные не поменяются
        taskENTER_CRITICAL();
        item_size = ((Queue_t *)queue)->uxItemSize; // Оно же sizeof(uint32_t), который мы передавали при создании очереди
        messages  = ((Queue_t *)queue)->uxMessagesWaiting;
        write     = ((Queue_t *)queue)->pcWriteTo;
        head      = ((Queue_t *)queue)->pcHead;
        tail      = ((Queue_t *)queue)->pcTail;
        taskEXIT_CRITICAL();
       
        if (messages) { // Есть вообще сообщения?
           
            // Получаем указатель на последнее, (подсмотрено в функции prvCopyDataToQueue, метод queueSEND_TO_FRONT)
            write -= item_size;
            if (write<head) {
                write = tail - item_size;
            }
           
            // Получаем данные по указателю (не забываем привести тип к исходному)
            num2 = *(uint32_t *)read;
           
            // Тут данные надо как-то обработать видимо
            // ...
           
        }


PPS: Простите за много буков, подумал может кому еще понадобится.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB