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

Чтение из устройства по прерыванию

Здравствуйте.

Ситуация следующая.

Есть система на SOC, 2 ядра + FPGA, частота ядра 1 ГГц. На ПЛИС реализован модуль, который принимает из UART пакеты, частота пакетов 1 КГц, размер 50 байт.

После приема пакета модуль формирует прерывание. 

В драйвере реализован девайс, который при открытии засыпает и ждет соответствующего прерывания. После возникновения прерывания системный вызов open возвращает дескриптор.

Код в пространстве пользователя открывает устройство, потом читает необходимое кол-во байт и закрывает устройство.

Проблема в том, что периодически пакеты теряются. Реально принимается с секунду около 900 пакетов из 1000 ожидаемых.

Оказалось, что время от времени открытие девайса занимает более 2, а то и 4 мсек, соответственно за это время драйвер успевает принять несколько пакетов.

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

Пытался вставлять wait_event_interruptible в функцию read, чтобы не один раз получить дескриптор, но это ничего не изменило.

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

Что еще можно предпринять ?

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


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

16 minutes ago, карамболь said:

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

Чем не устраивает вариант добавлять таймштамп в каждый пакет в драйвере?

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


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

3 minutes ago, BaN said:

Чем не устраивает вариант добавлять таймштамп в каждый пакет в драйвере?

да устраивает в принципе. Лень все переписывать ) И хочется понять, неужели 1 КГц это слишком быстро для гигигерцового двухядерного проца ?

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


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

2 minutes ago, карамболь said:

да устраивает в принципе. Лень все переписывать ) И хочется понять, неужели 1 КГц это слишком быстро для гигигерцового двухядерного проца ?

Обычный линукс без rt-ядра может иметь и бОльшие задержки:

http://shukra.cedt.iisc.ernet.in/edwiki/Real-time_response_of_the_Embedded_Linux_system_on_BeagleBone_Black_Wireless

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


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

14 minutes ago, BaN said:

Обычный линукс без rt-ядра может иметь и бОльшие задержки:

http://shukra.cedt.iisc.ernet.in/edwiki/Real-time_response_of_the_Embedded_Linux_system_on_BeagleBone_Black_Wireless

Ясно

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


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

On 11/18/2021 at 11:27 AM, карамболь said:

да устраивает в принципе. Лень все переписывать ) И хочется понять, неужели 1 КГц это слишком быстро для гигигерцового двухядерного проца ?

Каков шаг планировщика Linux ?

Linux нет приоритетов для приложений и процессов, что приложение с высшим приоритетом перебивает   приложение с низким приоритетом.

Если лень, ну тогда буферизация в ПЛИС.

 

 

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


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

7 minutes ago, gosha said:

Каков шаг планировщика Linux ?

Linux нет приоритетов для приложений и процессов, что приложение с высшим приоритетом перебивает   приложение с низким приоритетом.

Если лень, ну тогда буферизация в ПЛИС.

 

 

Уже реализовал все в ПЛИС. Получилось быстрее и надежнее 

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


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

18.11.2021 в 11:06, карамболь сказал:

Что еще можно предпринять ?

без ПЛИС поможет только realtime ядро (preempt_rt) и запуск realtime thread(s) в программе, делаю так на raspbian для CM3+

Хотя нет, ещё может помочь (но не пробовал) изолирование одного ядра проц. от системы

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

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


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

В таких случаях лучше использовать Userspace I/O (uio). Описываете устройство в дереве устройств:

my_dev0: @43C40000 {  
                        compatible = "generic-uio","uio";
                        reg = <0x43C40000 0x1000>;
                };

Оно отображается в sysfs:

> ls /sys/class/uio
uio0  uio1  uio2  uio3  uio4  uio5

Найти его можно по имени:

> cat /sys/class/uio/uio4/name
my_dev

Открываете /dev/uio4 один раз,  ожидание прерывания в read().

Подробнее в https://www.kernel.org/doc/html/v4.12/driver-api/uio-howto.html#waiting-for-interrupts

Надо включить в bootargs строку uio_pdrv_genirq.of_id=generic-uio

 

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


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

В 03.12.2021 в 03:06, gridinp сказал:

без ПЛИС поможет только realtime ядро (preempt_rt) и запуск realtime thread(s) в программе

 

А что есть "realtime thread" для PREEMPT_RT ядра? Достаточно настроить планировщик в режим SCHED_FIFO с максимальным приоритетом?

const int shed_type = SCHED_FIFO;
int max_priority = sched_get_priority_max(shed_type);
struct sched_param shd_param = { .sched_priority = max_priority };
sched_setscheduler(0, shed_type, &shd_param);

 

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


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

В 24.10.2022 в 08:11, arhiv6 сказал:

А что есть "realtime thread" для PREEMPT_RT ядра? Достаточно настроить планировщик в режим SCHED_FIFO с максимальным приоритетом?

Одна программа может содержать pthread_t и rt и не-rt.

О, хотел уже описывать процесс, но нашёл ссылку:

HOWTO build a simple RT application

 

добавлю только, что такая программа для ядра без PREEMPT_RT будет нормально выполнятся, но RT threads станут просто с 

повышенным приоритетом, но не RT

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

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


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

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

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

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

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

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

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

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

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

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