Я постараюсь дать вам ответ на основании ограниченной информации, при условии, что:
- простой, доморощенный планировщик используется для invoke task1 и task2 на основе простого критерия
- task1 и task2 выполняются до завершения (т. не вытеснять друг друг)
- данных представляют собой поток байт на основе (немного другая реализация требуется, если вам нужны пакеты)
То, что я обычно стараюсь при проектировании встраиваемых систем является минимизацией использования семафоров, и не зависящие от модели потоки данных. Я проиллюстрирую это ниже:
asynchronous (lock free) communication queues http://www.freeimagehosting.net/uploads/477741db06.gif ISR можно отделить от задач с помощью потоковой FIFO-очереди. Пример можно найти в: http://msmvps.com/blogs/vandooren/archive/2007/01/05/creating-a-thread-safe-producer-consumer-queue-in-c-without-using-locks.aspx
Такая реализация (без блокировок) не имеет зависимостей между ОС и должна быть тривиально проста в поддержке. Это также дает четкий дизайн производителя-потребителя, который свободен от тупиков.
Предполагая, что задачи запускаются планировщиком на дому, вы можете выбрать для проверки события (непустые fifo). т. Е. Если (TRUE == fifo_filled (my_read_queue)) {invoke task 1}
Теперь о синхронизации задач1 и task2. Если task1 просто создает данные, может использоваться один и тот же механизм: если у вас есть очередь (fifo), в которой task1 может записывать данные, которые могут быть прочитаны задачей 2, тогда задачи отключаются. Опять же, это можно проверить в вашем планировщике (если (TRUE == fifo_filled (task1_to_2_queue()) {invoke task2)}
Если вам нужно больше (т.е. если задачи не выполняются до завершения, но вытесняются) Мне нужен какой-то механизм для синхронизации.Варианты включают в себя: - использовать (бесплатно) операционную систему или простой планировщик в любом случае - заваривать свой собственный (мой опыт: должен быть выполнен, если он такой же простой, как цикл for и несколько операторов if) - используйте простой планировщик (гораздо более легкий вес, чем полный RTOS) - код рефакторинга для интеграции task1 и task2 в один. В этом случае вы будете эффективно составлять часть планировщика вашего кода приложения.
Примечание: примерная функция, которую я использовал в этом объяснении (fifo_filled()), не является частью кода примера. Он должен возвращать true if (read! = Write) Кроме того, в примере кода используются глобальные переменные, которые читаются и записываются; вы можете либо запустить функцию, способную обрабатывать несколько очередей, либо переместить переменные чтения/записи и буфера в структуру и обратиться к структуре параметров.
Альтернативный способ - создать критический раздел посредством отключения прерывания. Тем не менее, я пытаюсь ограничить это, поскольку он часто создает сильную связь системы, и код становится сложнее повторного использования.
На какой платформе вы работаете? – Amber
Учитывая, что оба ISR имеют одинаковый приоритет, могут ли они прерывать друг друга? Если нет, вам может не понадобиться дополнительная синхронизация. –
@Matthem - обычно ISR отключает прерывания при вводе. Но это было бы хорошо проверить. – Robert