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

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

есть программисты, а есть инженеры. программист решает все аппаратные проблемы программой, а инженер программные паяльником. результат плачевный... велик и могуч русский язык - но "нужных" слов не хватает. и практически бесполезно объяснять что тем что этим в чём они не правы. это как фанатики религиозные...🙁

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


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

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

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

Либо такая же ситуация как выше описал, но скажем при чтении пустого 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, исключающий конфликты доступа от разных ядер.

Спасибо за Ваш ответ! Очень похоже на правду - скорее всего действительно драйвер не рассчитан на одновременный доступ 2х ядер. Проблема вроде как и программная, а в результате можем получить аппаратную (рассогласование счетчиков, вылет за допустимый диапазон памяти и т.д.), что и приводит к вылету в исключение.

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


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

если смотреть (на сколь смог залезть) во "внутрь" дров для uart от вивадо (zynq) до 2021 (примерно) - то там только "одно поточный драйвер" (за линукс не скажу). врядли что то принципиально сделано по другому для других soc.

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


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

Делал такое, два ядра Zunq в один UART посылали, сделал флаг занятости в BRAM(семафор), доступный обеим. 

Изменено пользователем ovn

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


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

В 04.02.2023 в 18:01, RobFPGA сказал:

IMHO тут скорее не  аппаратная а софтовая проблема.

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

Изменено пользователем mantech

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


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

1 hour ago, mantech said:

Странно, я не знаю, как там сделан вывод в уарт, но если по простому, смотрим флаг окончания передачи

А если знать?  И если не по простому?   А если правильно - с буферизацией, DMA, FIFO на запись и чтение, ...     Что бы "по простому" не тратить проц на тупое ожидание  бита готовности для UART работающего на 1200 бит/с.  

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


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

Quote

смотрим флаг окончания передачи - посылаем байт,

Нет. Все равно есть шанс одновременной проверки флага и начала передачи. Всегда есть пауза между проверкой флага и запуском передачи (и поднятием флага). И в эту паузу второй процесс с удовольствием вклинивается. Делать светофор. 

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


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

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

Нет. Все равно есть шанс одновременной проверки флага и начала передачи. Всегда есть пауза между проверкой флага и запуском передачи (и поднятием флага).

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

Например на x86-системах, описанная вами операция, успешно решается при помощи одной из семейства функций InterlockedCompareExchange...(). На многих многоядерных системах есть её аналог. Даже ядра Cortex-M имеют подобный механизм синхронизации.

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


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

10 часов назад, mantech сказал:

Странно, я не знаю, как там сделан вывод в уарт

Вы, когда пишете какой-то драйвер работы с периферией, как работаете с регистрами этой периферии? Если что-то записываете в регистр управления такой периферии, то потом проверяете записанное или нет? И если проверяете, то насколько часто проверяете? А если нет, то почему нет? Вы не задумывались, что ваш драйвер, написанный в расчёте на монопольное использование периферийного блока, вдруг кто-то решит запустить на двух ядрах многоядерного SoC?

А флаги в регистрах статуса как проверяете? Проверяете на все возможные значения?

Вот простой пример (раз уж до сих пор не понятно): Предположим в регистре статуса есть флаг переполнения записи (взводится, если в уже заполненное FIFO или регистр данных передатчика была попытка записи нового значения). Ваш драйвер рассчитывает, что этот флаг будет всегда сброшен (ведь он же знает, что никогда лишнее не запишет, так как сперва читает статус FIFO и только затем пишет в него). Но вдруг другое ядро сделало лишнюю запись в TX.FIFO и флаг взвёлся! А анализ содержимого регистра статуса у вас сделан в рассчёте на максимально быструю работу - чтением всего регистра статуса и табличным переходом по индексу из таблицы, выбранному по содержимому регистра статуса. И в результате - при установке лишнего флага получаете чтение адреса перехода за пределами таблицы и улёт процессора по произвольному адресу. С последующим закономреным fault-ом.  :unknw:

 

А ещё драйвер UART может быть энергоэффектиным. И отключать тактирование регистров UART, когда он не используется. Сами догадаетесь, что будет в другом ядре, когда оно полезет к регистрам в отключенной периферии?  :punish:

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


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

20 часов назад, RobFPGA сказал:

А если знать?  И если не по простому?

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

11 часов назад, jcxz сказал:

Вы, когда пишете какой-то драйвер работы с периферией, как работаете с регистрами этой периферии?

Когда пишу драйвер для реального применения, то делаю по прерываниям, чтобы не ждать освобождения уарта, но еще раз - тут вопрос, что виновато программа или железо, а чтобы это проверить, нужно сделать программу как можно проще, а иначе будете вечность рассуждать что виновно, ИМХО.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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