Как заставить многие задачи FreeRTOS ждать завершения друг друга? - PullRequest
0 голосов
/ 23 мая 2018

У меня есть одна init задача и несколько рабочих задач.В какой-то момент рабочие должны ждать, пока init завершит настройку.Я пытаюсь сделать это с двоичным семафором.

Когда запускается планировщик, все задачи готовы к запуску.Таким образом, чтобы гарантировать, что рабочие ждут, семафор должен быть «взят задачей init» до запуска планировщика.(В противном случае рабочий мог бы получить семафор до того, как init был даже запланирован.)

Как мне это сделать?Или как еще мне решить эту проблему?

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

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

Можно ли просто сделать задачу Init задачей с наивысшим приоритетом, пока она не завершит необходимую инициализацию.Другие задачи не будут выполняться до тех пор, пока инициализация не будет завершена из-за более низкого приоритета.Когда инициализация завершена, вы можете удалить задачу Init или, возможно, понизить ее приоритет.

Если приоритет не является параметром, то вам, вероятно, следует использовать бит события (флаг события).Для вашего случая использования бит события является лучшим механизмом, чем двоичный семафор, поскольку несколько ожидающих задач могут быть готовы к запуску, когда задача Init сообщает об этом событии.

0 голосов
/ 23 мая 2018

Двоичный семафор будет в порядке.Инициализируйте его до 0 единиц.

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

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

0 голосов
/ 23 мая 2018

Бинарный семафор сработал бы, если бы у вас была только одна рабочая задача.Вы должны создать семафор как «недоступный» / «взятый», а задача инициализации будет xSemaphoreGive семафором после завершения инициализации, уведомив одну рабочую задачу о завершении инициализации.Однако, когда у вас есть несколько задач, только одна из них сможет взять / приобрести семафор.

Будет работать счетный семафор.Семафор должен иметь емкость, равную количеству рабочих задач, и он должен начинаться как пустой.Как разработчик системы, вы знаете, что init-task предназначена для владения базовым ресурсом при запуске, поэтому init-task не нужно будет получать семафор при первой инициализации.После инициализации вы должны вызывать xSemaphoreGive один раз для каждого работника.Если / если вы хотите выполнить повторную инициализацию, вызовите xSemaphoreTake один раз для каждой рабочей задачи.Чтобы это работало, работники должны периодически «на короткое время» освобождать семафор, а затем повторно его получать.

Группа событий также может использоваться, если вы инициализируете только один раз.Ваша задача инициализации может использовать xEventGroupSetBits , чтобы указать, что инициализация завершена.Ваши рабочие задачи могут использовать xEventGroupWaitBits для ожидания выполнения задачи init.

...