Перейти к содержанию
    

Одновременное обращение 2 ядер к одной периферии, Ultrascale+

Всем доброго дня!

Заметил такую штуку на Ultrascale+. У меня 2 ядра CORTEX A используют для stdout один и тот же уарт - толкаю туда всякую отладочную информацию.  Когда получается так, что одно ядро выводит в уарт, и в это время туда же начинает другое ядро выводить - одно из ядер вылетает, видимо в исключение, SystemAbortHandler. Это я что-то криво сделал или так и должно быть?

PS уарт внешний, не из PS. Расположен в PL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 2/3/2023 at 3:45 PM, alexPec said:

Всем доброго дня!

Заметил такую штуку на Ultrascale+. У меня 2 ядра CORTEX A используют для stdout один и тот же уарт - толкаю туда всякую отладочную информацию.  Когда получается так, что одно ядро выводит в уарт, и в это время туда же начинает другое ядро выводить - одно из ядер вылетает, видимо в исключение, SystemAbortHandler. Это я что-то криво сделал или так и должно быть?

PS уарт внешний, не из PS. Расположен в PL.

По-идее, если ядра заходят в УАРТ через AXI interconnect, он должен буфферизировать или разрешать такие ситуации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уарт - ксайлинксовое ядро, axi uart lite. Подключен как axi slave к шине axi master у PS. Ничего самодельного нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

32 minutes ago, alexPec said:

Уарт - ксайлинксовое ядро, axi uart lite. Подключен как axi slave к шине axi master у PS. Ничего самодельного нет.

а внутри там ядра как обращаются к этому мастеру? По идее там же должно быть 2 мастера + арбитраж. А если там один мастер, то у вас тогда должны быть какие то семафоры что бы развести ядра, КМК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну а по отдельности ядра нормально отправляют в UART? Без вылета в исключение? И что значит "подключен к AXI Master у PS"? К какому PS?

По-хорошему, с двух процов нужно выводить шины на AXI Interconnect, а с него уже на ядро UART.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

36 минут назад, des00 сказал:

а внутри там ядра как обращаются к этому мастеру? По идее там же должно быть 2 мастера + арбитраж. А если там один мастер, то у вас тогда должны быть какие то семафоры что бы развести ядра, КМК.

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

1 час назад, Arlleex сказал:

Ну а по отдельности ядра нормально отправляют в UART? Без вылета в исключение? И что значит "подключен к AXI Master у PS"? К какому PS?

По-хорошему, с двух процов нужно выводить шины на AXI Interconnect, а с него уже на ядро UART.

По отдельности сколько хочешь, никаких проблем, ни одного вылета в исключение. PS - это Processor System у ксайлинкса внутри плисины. Это Hardware два ядра cortex A53 и два ядра Cortex R + периферия в виде SPI, ethernet, uart,sd, и т.д. Все это Processor system - PS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 минут назад, alexPec сказал:

PS - это Processor System у ксайлинкса внутри плисины...

Нет, это я знаю. Я имел в виду - к какому из PS подключен AXI-порт UART. Т.е. из описания не ясно, как же Вы все-таки подключили 1 AXI-slave (UART) к двум мастерам. Покажите блок-дизайн в виваде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

IMHO тут скорее не  аппаратная а софтовая проблема. Одновременный доступ  к одному ресурсу  нужно правильно  шарить,  через  мютекс например. 
Нельзя  просто так писать в один UART  из двух   независимых   процов -  тем более если непонятно как в софте сделана работа с этим UART. 
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, RobFPGA сказал:

IMHO тут скорее не  аппаратная а софтовая проблема. Одновременный доступ  к одному ресурсу  нужно правильно  шарить,  через  мютекс например.

Это понятно. Это другой вопрос. Тут же по крайней мере никаких исключений выкидываться не должно. Это как одновременная работа DMA и CPU с одной периферией - с точки зрения логики это глупо, но проц не уйдет в зависание.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, Arlleex said:

Тут же по крайней мере никаких исключений выкидываться не должно

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

26 минут назад, RobFPGA сказал:

Мало ли какая проблема в софте возникает при конфликте доступа двух процедур которые не рассчитаны для такого?

Что значит не рассчитаны? UART TC торчит наружу AXI-slave портом, при правильном подключении ему без разницы, кто из мастеров инициатор обмена. Или по-Вашему, если сейчас ТС вместо другого PS будет лезть к этому же UART-у уже через DMA, и первый PS будет уходить в исключение - это тоже должно разруливаться программно?:unknw: То, что ТС не разрулил программный захват одного ресурса - это его личное дело, однако это не говорит о том, что подобные действия должны положить ядро - ввалив его в исключение. Но статусные регистры для анализа исключения, конечно же, расшифровать стоит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 минут назад, Arlleex сказал:

То, что ТС не разрулил программный захват одного ресурса - это его личное дело, однако это не говорит о том, что подобные действия должны положить ядро - ввалив его в исключение.

Мне кажется ув. RobFPGA имел в виду следующее:

Предположим - UART содержит TX.FIFO на N элементов. В регистре статуса UART содержится состояние этого TX.FIFO. Скажем в статусе указано, что оно пусто. Драйвер UART, желающий записать данные на передачу, читает статус занятости TX.FIFO, видит там 0 и понимает, что может записать в него максимальный объём данных, равный его размеру (размер TX.FIFO ему известен, например ==16). Далее он записывает туда эти 16 байт. Так как драйвер монопольно работает с UART - всё ок.

А теперь предположим, что между чтением статуса и записью TX.FIFO драйвера в одном CPU, успел вклиниться такой-же драйвер в другом CPU, прочитал тоже статус и успел впихнуть туда свои 16 байт. Тогда 1-й CPU при записи получит переполнение при записи TX.FIFO. Аналогичная ситуация может быть и с приёмным FIFO, только underflow в результате.

А вот по событиям overflow или underflow FIFO UART данная реализация периферии запросто может генерить exception.

 

ЗЫ: Реализации UART в данном SoC не знаю, просто предположение. Я не говорю, что там именно это происходит, но вот например в семействе XMC4xxx, если включен ECC-контроль памяти периферии, то чтение неинициализированной памяти FIFO (или за пределами его заполненной части) как раз и вызывает exception.

ЗЫЫ: Также в некоторых МК встречал такие периферийные регистры, обращение к которым приостанавливает работу CPU на сколько-то тактов (по инфе из мануала). Что будет, в многоядерном SoC, если, пока одно ядро приостановлено, к этому регистру обратилось другое ядро? Может тут такая ситуация.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, jcxz сказал:

А вот по событиям overflow или underflow FIFO UART данная реализация периферии запросто может генерить exception.

Exception ядра или обычное прерывание периферии?

Просто исключение ядра - это обычно по каким-то критичным ошибкам системного уровня - отказ шины, например.

А FIFO в UART-е, по-хорошему, должно ставить локальный флажок в регистре + возбуждать периферийное прерывание.

ИМХО, у ТС как раз первая ситуация.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

21 минуту назад, Arlleex сказал:

Exception ядра или обычное прерывание периферии?

Просто исключение ядра - это обычно по каким-то критичным ошибкам системного уровня - отказ шины, например.

Exception. В XMC4xxx генерится именно exception.

Ещё одна возможная ситуация:

Либо такая же ситуация как выше описал, но скажем при чтении пустого RX.FIFO (underflow) возвращается значение за пределами диапазона 0...255 (например == 0xFFFFFFFF), дальше это значение кладётся в массив входящих данных, элементы которого 16-и или 32-и разрядные. При этом указатель количества данных сдвигается по результату первого чтения регистра статуса. В результате - процедура обработки читает количество данных и читает данные, в которых вдруг оказываются значения 0...255 и у неё от этого сносит крышу. Так как не ожидает значений за пределами 0...255. А дальше она может куда-то улететь и там уже произвойдёт вторичный exception.

Либо любая другая ситуация, где не очень корректно написанный драйвер, в котором например есть указатель на данные и счётчик количества байт. Счётчик количества модифицируется при чтении статуса FIFO, а дальше код пишет/читает FIFO, контролируя после каждой записи/чтения статус заполненности/пустоты FIFO и двигая указатель в памяти. И если кто-то посторонний вклинился, записал/считал FIFO, цикл выполнит меньшее количество проходов. И получится рассогласование счётчика байт и указателя данных в памяти. Что опять-же в последующем может привести к сбою в любом месте программы. А при монопольной работе драйвера с UART такого в принципе не может случиться.

 

Ещё вариант:

Драйвер UART может быть написан таким образом, чтобы отключать тактирование UART когда тот не нужен (энергосбережение). Вот драйвер в одном из ядер передал данные в TX.UART, дождался завершения их передачи и отключил тактирование UART (предварительно переведя ножку UART.TX в режим GPIO). А в эту пору другое ядро решило обратиться к этому UART. И получило исключение, так как периферия уже отключена.

 

PS: Причин может быть 100500. Смысла нет их все разбирать, кто знает как там драйвера UART написаны? Лучше написать корректный арбитраж UART, исключающий конфликты доступа от разных ядер.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...