Блокировка FreeRTOS для нескольких событий/объектов

В примере решения стека UDP/IP, здесь, есть предлагаемое решение для блокировки в одной очереди событий.

Каким будет решение для защиты данных, на которые указывает указатель, до тех пор, пока они не будут обработаны задачей, ожидающей очереди.

Скажем, например, что очередь заполняется из ISR. ISR не должен писать в *pvData, если он не был обработан соответствующей задачей. Но поскольку источников событий может быть несколько, очередь, вероятно, должна быть длиннее одного элемента. Должна ли быть создана структура:

typedef struct IP_TASK_COMMANDS
{
    eIPEvent_t eEventType;
    SemaphoreHandle_t data_read;
    void *pvData;
} xIPStackEvent_t;

С семафором, взятым в ISR и заданным в задаче, которая обрабатывает данные, когда с ними покончено.


person evading    schedule 25.02.2016    source источник
comment
Название этого вопроса предполагает нечто совершенно иное, чем сам вопрос. Название предполагает блокировку в нескольких очередях. Вы могли бы сделать так, чтобы устранить эту двусмысленность.   -  person Clifford    schedule 26.02.2016
comment
@Clifford Я просто украл название страницы FreeRTOS на эту тему, но я понял вашу точку зрения. Предложения приветствуются.   -  person evading    schedule 26.02.2016


Ответы (2)


Если вы возьмете пример UDP - обычно у вас будет пул буферов (или динамически выделенный буфер), из которого будет получен буфер и передан в DMA. Когда DMA заполняет буфер полученными данными, указатель на буфер попадает в стек UDP, после чего только стек UDP знает, где находится буфер, и отвечает за него. В какой-то момент данные в буфере могут быть переданы из стека UDP в приложение, где они могут быть использованы. Затем приложение возвращает буфер в пул (или освобождает выделенный буфер), чтобы он снова был доступен для прямого доступа к памяти. Верно и обратное — приложение может выделить буфер, заполненный данными для отправки, через стек UDP, для функции Tx, где он фактически помещается в провод — и в этом случае возвращается прерывание окончания Tx. буфер в пул.

Короче говоря, есть только одна вещь, которая имеет ссылку на буфер в каждый момент времени, так что проблем нет.

[обратите внимание выше, где говорится, что приложение выделяет или освобождает буфер, который будет находиться внутри API-интерфейса стека UDP/IP, вызываемого приложением, а не приложением напрямую — на самом деле это частично, по крайней мере, как наш собственный TCP/IP.]

person Richard    schedule 26.02.2016

Вы не хотите, чтобы ваш ISR блокировался и ждал, пока буфер данных станет доступным. Если ваш ISR может просто пропустить обновление и двигаться дальше, когда буфер недоступен, тогда, возможно, имеет смысл использовать семафор. Но ISR не должен блокировать семафор.

Вот альтернатива для рассмотрения. Создайте пул памяти, содержащий несколько буферов данных соответствующего размера. ISR выделяет из пула следующий доступный буфер, записывает в него данные и ставит указатель на него в очередь. Задача считывает указатель из очереди, использует данные, а затем освобождает буфер обратно в пул. Если ISR запускается снова до того, как задача использует данные, ISR будет выделять новый буфер, чтобы не перезаписывать предыдущие данные.

Вот еще одно соображение. Очередь FreeRTOS передает элементы по копиям. Если буфер данных относительно мал, то, возможно, имеет смысл просто передать структуру данных, а не указатель на структуру данных. Если вы передадите структуру данных, служба очереди сделает копию для предоставления задаче, и ISR сможет обновить свой исходный буфер.

Теперь, когда я думаю об этом, использование функции копирования службы очередей может быть проще, чем создание собственного отдельного пула памяти. Когда вы создаете очередь и указываете длину очереди и размер элемента, я полагаю, что служба очереди создает пул памяти, который будет использоваться очередью.

person kkrambo    schedule 25.02.2016
comment
Я рассмотрел этот подход, но, поскольку некоторые события не связаны с какими-либо данными, а другие имеют данные, я ищу подход, при котором мне не нужно копировать данные, если их нет. - person evading; 25.02.2016