-
- Так и есть в данном случае, один принтер на всю систему, называется
printf() и, что может быть логичней, чем брать и печатать на него
из любого места. - petrd(14.08.2025 07:49)
- откройте из двух терминалов один порт - Vit(14.08.2025 08:49)
- Такое нельзя сделать. Но это не аналогия для данной ситуации. - petrd(14.08.2025 09:13)
- А я думаю - аналогия! Я бы сделал одну задачу-драйвер, для UART,
как для принтера. В нашем случае, последовательного. Внутри этой
задачи прерывания, DMA, монопольный (!) доступ к телу (железу) и
пр.. А все остальне задачи обращаются не к UART'у, а к
обслуживающей его задаче, вернего уровня приложений: "Не будет ли
так любезен Джинн вот это вот передать?". И ждать, когда
UART'овский Джин твой флажок сбросит, т.е. запрос будет обработан. - vpv.vpv(Вчера, 10:54)
- Следите! Уже сделано так. Все имеют доступ к printf(), внутри него,
когда сообщение готово, вызывается _write() в котором сообщение
отправляется в завернутый в критическую обертку StreamBufferSend().
В задаче из завернутого в критическую обертку StreamBufferRecieve()
это сообщение копируется, его длина и адрес передается в DMA, пуск
DMA, начинается транзакция в UART, задача ставится на ожидание,
пока от прерывания DMA не придет уведомление о завершении
транзакции. C приходом petrd(503 знак., Вчера, 11:47)
- Начало новой транзакции никак не мешает завершению передачи
предыдущего символа. Вы же, по опустошению буфера DMA, UART не
выключаете? Nikolay_Po(213 знак., Вчера, 12:59)
- Нет, конечно, ничего не выключаю. Похоже на воду дую ....
размышляю, пришло уведомление о завершении транзакции ДМА, а UART
еще передает, задача успела вытащить следующее сообщение, засунула
адрес и длину в ДМА, стартует, а от UART запроса к ДМА еще не
поступало, ну и, значит, стоп, ДМА ждет когда придет запрос от
него. - petrd(Вчера, 13:21)
- Поясню: DMA можно запускать при неготовности периферии. Всего делов-то - DMA будет стоять на первой транзакции, не выполняя её, сохраняя исходное значение счётчика транзакций. Как только ранее положенный в буфер самого UARTа символ протолкнётся в освободившийся сдвиговый регистр, сразу же, по флагу transmit empty, DMA положит первый символ следующей транзакции. Nikolay_Po(372 знак., Вчера, 13:34)
- Стоп DMA никак не влияет на передачу уже поступившего и переданного в свдиговый регистр символа. Так что не переживайте. - Nikolay_Po(Вчера, 13:26)
- Нет, конечно, ничего не выключаю. Похоже на воду дую ....
размышляю, пришло уведомление о завершении транзакции ДМА, а UART
еще передает, задача успела вытащить следующее сообщение, засунула
адрес и длину в ДМА, стартует, а от UART запроса к ДМА еще не
поступало, ну и, значит, стоп, ДМА ждет когда придет запрос от
него. - petrd(Вчера, 13:21)
- Начало новой транзакции никак не мешает завершению передачи
предыдущего символа. Вы же, по опустошению буфера DMA, UART не
выключаете? Nikolay_Po(213 знак., Вчера, 12:59)
- Изобретаем journald вместе. Люблю такое :) - Cкpипaч(Вчера, 10:55)
- Следите! Уже сделано так. Все имеют доступ к printf(), внутри него,
когда сообщение готово, вызывается _write() в котором сообщение
отправляется в завернутый в критическую обертку StreamBufferSend().
В задаче из завернутого в критическую обертку StreamBufferRecieve()
это сообщение копируется, его длина и адрес передается в DMA, пуск
DMA, начинается транзакция в UART, задача ставится на ожидание,
пока от прерывания DMA не придет уведомление о завершении
транзакции. C приходом petrd(503 знак., Вчера, 11:47)
- не нужно передёргивать с ситуациями. компорт компа это USART с
дополнительными сигналами. здесь же аж голый USART. можете
семафорить, можете ещё как лочить, но обеспечьте отсутствие одновременного доступа Vit(1 знак., 14.08.2025 09:57, ссылка)
- Обычно при попытке открыть во втором терминале порта, открытого в
первом терминале второй терминал будет ругаться. Что не так?
Отсутствие "одновременного" доступа к чему? К UART? Так он только с
каналом ДМА взаимодействует, больше ни с кем. А данные в ДМА
поставляет единственный приемник
xStreamBufferReceive(uart_tx_stream....) завернутый в критическую
секцию, в который данные шлет единственный передатчик
xStreamBufferSend( uart_tx_stream, .....) тоже завернутый в petrd(126 знак., 14.08.2025 10:38)
- не хотите понимать. во время передачи (пока речь о) в USART из
буфера, как с FIFO, так и с DMA, весь этот ресурс должен быть
заблокирован. дальше можно не развивать. кто-то блокирует
заворачиванием в критическую секцию. ТС пишет о дебаг-выхлопе из
тучи задач. хорошо хоть не из обработчиков прерываний. если ресурс
захвачен одной задачей, то в другой можно либо отказаться, либо
ждать освобождения ресурса, либо отправить в программное устройство
отложенной отправки в. когда Vit(62 знак., 14.08.2025 11:34)
- Хочу понимать! Но не все понятно. Вы говорите "во время передачи
(пока речь о) в USART из буфера, как с FIFO, так и с DMA, весь этот
ресурс должен быть заблокирован" о каком ресурсе? О ДМА? Он
заблокирован. Я не теоретически, а практический разговор веду в
железе, независимо от топикстартера. - petrd(14.08.2025 11:49)
- ваша аналогия насчёт принтера не учитывает наличие службы спулера
печати (в винде Print Spooler). да были prn и lptx, а с ними как-то
употреблялись copy/type/print, но уже давно перешли на
использование именно службы печати - Vit(14.08.2025 12:33)
- Хорошо, без аналогий. Цель, изо всех мест программы, где требуется
вывод, без оглядки на FreeRTOS, писать printf() и получать вывод в
терминале. Говорю исключительно про МК. - petrd(14.08.2025 15:26)
- никто не мешает так писать:). но есть нюансы. при использовании без вытеснения (в т.ч. всяких вызовов в обработчиках прерываний) нужно, чтобы уход последнего байта контроллировался по TXC (если RS485 - аналогично снятию DE). при использовании DMA это не всегда решаемо без дополнительных сложностей, потому как событие окончания отправки по DMA возникает чуть раньше факического ухода байта. потому возникают варианты с расчетными таймаутами и т.п.. при вытеснении же всё то же, Vit(503 знак., Вчера, 08:38)
- Хорошо, без аналогий. Цель, изо всех мест программы, где требуется
вывод, без оглядки на FreeRTOS, писать printf() и получать вывод в
терминале. Говорю исключительно про МК. - petrd(14.08.2025 15:26)
- ваша аналогия насчёт принтера не учитывает наличие службы спулера
печати (в винде Print Spooler). да были prn и lptx, а с ними как-то
употреблялись copy/type/print, но уже давно перешли на
использование именно службы печати - Vit(14.08.2025 12:33)
- Хочу понимать! Но не все понятно. Вы говорите "во время передачи
(пока речь о) в USART из буфера, как с FIFO, так и с DMA, весь этот
ресурс должен быть заблокирован" о каком ресурсе? О ДМА? Он
заблокирован. Я не теоретически, а практический разговор веду в
железе, независимо от топикстартера. - petrd(14.08.2025 11:49)
- не хотите понимать. во время передачи (пока речь о) в USART из
буфера, как с FIFO, так и с DMA, весь этот ресурс должен быть
заблокирован. дальше можно не развивать. кто-то блокирует
заворачиванием в критическую секцию. ТС пишет о дебаг-выхлопе из
тучи задач. хорошо хоть не из обработчиков прерываний. если ресурс
захвачен одной задачей, то в другой можно либо отказаться, либо
ждать освобождения ресурса, либо отправить в программное устройство
отложенной отправки в. когда Vit(62 знак., 14.08.2025 11:34)
- Обычно при попытке открыть во втором терминале порта, открытого в
первом терминале второй терминал будет ругаться. Что не так?
Отсутствие "одновременного" доступа к чему? К UART? Так он только с
каналом ДМА взаимодействует, больше ни с кем. А данные в ДМА
поставляет единственный приемник
xStreamBufferReceive(uart_tx_stream....) завернутый в критическую
секцию, в который данные шлет единственный передатчик
xStreamBufferSend( uart_tx_stream, .....) тоже завернутый в petrd(126 знак., 14.08.2025 10:38)
- А я думаю - аналогия! Я бы сделал одну задачу-драйвер, для UART,
как для принтера. В нашем случае, последовательного. Внутри этой
задачи прерывания, DMA, монопольный (!) доступ к телу (железу) и
пр.. А все остальне задачи обращаются не к UART'у, а к
обслуживающей его задаче, вернего уровня приложений: "Не будет ли
так любезен Джинн вот это вот передать?". И ждать, когда
UART'овский Джин твой флажок сбросит, т.е. запрос будет обработан. - vpv.vpv(Вчера, 10:54)
- Такое нельзя сделать. Но это не аналогия для данной ситуации. - petrd(14.08.2025 09:13)
- откройте из двух терминалов один порт - Vit(14.08.2025 08:49)
- Так и есть в данном случае, один принтер на всю систему, называется
printf() и, что может быть логичней, чем брать и печатать на него
из любого места. - petrd(14.08.2025 07:49)