104
КОМПОНЕНТЫ И ТЕХНОЛОГИИ • № 6 '2011
компоненты
микроконтроллеры
образом место в очереди. Как только в оче-
реди появилось свободное место, планиров-
щик выведет из состояния блокировки ту за-
дачу из числа «ожидавших», которая дольше
остальных пребывала блокированной. В на-
шем случае это задача-передатчик 2 (момент
времени (7)). Так как приоритет у нее выше,
она вытеснит задачу-приемник и запишет
следующий элемент в очередь. После чего
она вызовет планировщик API-функцией
taskYIELD(). Однако готовых к выполнению
задач с более высоким или равным приори-
тетом на этот момент нет, поэтому пере-
ключения контекста не произойдет, и задача-
передатчик 2 продолжит выполняться. Она
попытается записать в очередь еще один
элемент, но очередь заполнена, и задача-
передатчик 2 перейдет в блокированное со-
стояние (момент времени (8)).
Снова сложилась ситуация, когда все вы-
сокоприоритетные задачи-передатчики бло-
кированы, поэтому управление получит
низкоприоритетная задача-приемник (8).
Однако на этот раз после появления свобод-
ного места в очереди разблокируется задача-
передатчик 1, так как теперь ее время пребы-
вания в блокированном состоянии превыша-
ет время задачи-передатчика 2, и т. д.
Следует отметить, что в ранее приведен-
ном примере, когда задачи-передатчики
имеют более высокий приоритет, чем задача-
приемник, в очереди в любой момент вре-
мени не может быть более одного свободного
места.
Использование очередей
для передачи больших объемов данных
Если размер одного элемента очереди
достаточно велик, то предпочтительно ис-
пользовать очередь для хранения не самих
элементов, а для хранения указателей на эле-
менты (например, на массивы или на струк-
туры).
Преимущества такого подхода:
Экономия памяти. Память при созда-
•
нии очереди выделяется под все элемен-
ты очереди, даже если очередь пуста.
Использование небольших по объему за-
нимаемой памяти указателей вместо объ-
емных структур или массивов позволяет
достичь существенной экономии памяти.
Меньшее время записи элемента в очередь
•
и чтения его из очереди. При записи/чте-
нии элемента из очереди происходит его
побайтовое копирование. Копирование
указателя выполняется быстрее копирова-
ния объемных структур данных.
Тем не менее использование указателей
в качестве элементов очереди сопряжено
с некоторыми трудностями, преодоление
которых ложится на плечи программиста.
Для достижения корректной работы про-
граммы должны быть выполнены следую-
щие условия:
У памяти, адресуемой указателем, в каж-
•
дый момент времени должна быть одна
четко определенная задача-хозяин, ко-
торая может обращаться к этой памя-
ти. То есть необходимо гарантировать,
что несколько задач не будут одновре-
менно обращаться к памяти, на которую
ссылается указатель. В идеальном случае
только задача-передатчик должна иметь
доступ к памяти, пока указатель на эту
память находится в очереди. Когда же
указатель прочитан из очереди, только
задача-приемник должна иметь возмож-
ность доступа к памяти.
Память, на которую ссылается указатель,
•
должна существовать. Это требование ак-
туально, если указатель ссылается на дина-
мически выделенную память. Только одна
задача должна быть ответственна за осво-
бождение динамически выделенной памя-
ти. Задачи не должны обращаться к памя-
ти, если та уже была освобождена.
Нельзя использовать указатель на пере-
•
менные, расположенные в стеке задачи,
то есть указатель на локальные перемен-
ные задачи. Данные, на которые ссылается
указатель, будут неверными после очеред-
ного переключения контекста.
Выводы
В этой части статьи был подробно описан
механизм очередей как средства межзадач-
ного взаимодействия. Показаны основные
способы организации такого взаимодей-
ствия. Однако существуют еще несколько
API-функций для работы с очередями, кото-
рые используются только для отладки ядра
FreeRTOS. О них будет рассказано в дальней-
ших публикациях, посвященных возможно-
стям отладки и трассировки. В следующей же
публикации внимание будет сконцентриро-
вано на особенностях обработки прерываний
микроконтроллера в среде FreeRTOS.
■
Достарыңызбен бөлісу: |