ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
22 декабря
1013057 Топик полностью
LightElf (18.06.2020 22:49, просмотров: 1034) ответил fk0 на A остальные что, будут вечно спать? Я забыл уточнить, но записи в буфере не фиксированного размера (логгер -- текстовые строчки, вроде очевидно). Да и посылаются в компорт может быть не по одной. Вместо одной ушедшей можно 5 новых записать, и наоборот. Будить нужно всех ожидающих. И потом, между моментом проверки (нет места) и засыпанием на семафоре запросто могло появиться свободное место. И наоборот, после получения сигнала семафора другой поток мог занять всё своими
У тебя привычка обобщать все по самое некуда :) И в этом самом некуда - находить неразрешимые проблемы. Не бывает единого драйвера под разные OS и радикально разное железо. 

Вариант 1. Буфер заведомо больше, чем самая длинная строка лога. Достаточно частая ситуация. UART с DMA (типа того же STM32), буфер в килобайт. Разумная строка лога - в пределах 100 символов. Нужен один бинарный семафор.

Семафор взводится в обработчике прерываний DMA по условию "в буфере есть 100 свободных байт". Первый же поток хватает семафор, запихивает в буфер всю свою строку и отваливает. Остальные потоки обламываются. Когда в буфере освободится место - обработчик прерывания снова взведет семафор, самый приоритетный/первый/один из (в зависимости от того, как реализовано в OS) поток схватит семафор и отправит свою строку. И т.д.

Вариант 2. Буфер маленький, например UART с FIFO без DMA (типа LM3S, NUC970 и тыды). Нужен мутекс и примитив блокировки типа Block/Run. Поток захватывает мутекс, запихивает в FIFO сколько запихивается и блокируется. Обработчик прерывания по событию "в FIFO есть X свободных байт" будит этот поток, тот запихивает следующую порцию, снова блокируется и т.д. Когда отправит последний байт - отдаст мутекс. Мутекс схаватит следующий поток и айда вперед.

Оба варианта оборачиваются в некий единый интерфейс и получается "драйвер UART" для конкретной OS.

Не надо делать мне как лучше, оставьте мне как хорошо