Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Передача ядру указателя на пользовательскую функцию.  (Прочитано 1706 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
 Здравствуйте, коллеги.
 Помогите, пожалуйста, разобраться с проблемой. Я переписываю под Linux DOS-овскую программу, с внесением большого числа изменений. Самая главная проблема возникла при необходимости обработки прерываний от  com-порта. В DOS-овской программе меняется вектор прерываний и на соответствующий уровень прерываний устанавливается мой обработчик, путём передачи процессору указателя на функцию - часть моей программы.
 Соответственно, теперь мне нужно указатель на мой обработчик передать написанному мною модулю ядра. Помогите найти информацию, каким образом можно это осуществить. Модуль уже написан, ждёт указателя. Меня устроит man - знать бы, какую функцию смотреть. Спасибо большое за ответ!

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Ну передать ядру указатель легко. Только вот я не уверен что код будет исполняться нормально и не похоронит ОС или приолжение.

лучше закопай труппик и напиши по человечески

тебе нужны какие-то экзотические режимы работы с COM портом? или просто читать данные пришедшие на него?
ты уже тут задавал этот вопрос. тебе ответили. и послали читать именно ту документацию которую надо прочитать.

Давай так, ты наконец рассказываешь что там за хрень с портом, а мы тебе рассказываем как все организовать без залезания на уровень ядра.
Пока не докажешь всем доходчиво и аргументированно почему тебе кровь из носа надо именно прямой доступ к оборудованию считаем что ты пытаешься скомпилить досовское приложение не понимая
- ни основ работы компьютера
- ни основ работы современных ОС
- ни RS-232
- ни языка Си/С++

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
 Задача - обмениваться данными с АЦП, и, анализируя эти данные, выполнять различные операции - от записи их в память до выдачи команд исполняющим механизмам. Данные приходят примерно каждые 24 миллисекунды, и терять их нельзя.
 Я не вижу другого способа обработки сигнала, пришедшего от АЦП на ком-порт. Постоянное опрашивание ком-порта мне не подходит, потому что за время между двумя сигналами - около 20 миллисекунд - программа может не успеть выполнить все необходимые операции. К тому же, в старт-стопном режиме обмена данными я не могу рассчитывать на чёткие временные интервалы между двумя сигналами.
 Насколько я понимаю, обработка прерываний от ком-порта в этом случае - самый правильный способ. Программа реагирует на пришедший в порт байт именно по факту его получения, а не затрачивая постоянно ресурсы на непрерывный опрос. Если существуют какие-либо другие методы обработки информации в подобном режиме - поделитесь, пожалуйста, информацией. Я вам буду очень благодарен.

Оффлайн scsiman

  • Активист
  • *
  • Сообщений: 344
    • Просмотр профиля
Если не ошибаюсь, речь идёт о реалтайме, что в "обычном" линуксе недостижимо. На мой взгляд, имеет смысл смотреть в сторону realtime-OS типа QNX (если оно ещё живо).
Dell Studio XPS 16, Ubuntu 16.04 LTS (Home).
HP nx6110, Ubuntu 8.04 LTS => 10.04 LTS (Home).

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
 Да-да, я тоже читал про такой RT-Linux. А почему, по-вашему, нельзя просто реагировать на прерывания в обычном линуксе? Теоретически ведь в этом ничего сложного нет...

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Vil84, давай больше технической инфы
Таки АЦП гонит данные через стандартный UART? скорость обмена какая?
Тогда нехрен выпендриваться делай блокирующее чтение данных. Как только будет принят первый байт микросхема USART поместит его в приёмный буфер (4-8 байт всего) и выставит флаг прерывания. Он будет обработан практически мгновенно не незагруженой системе. Вызовится обработчик в который ты так отчаяно пытаешься залезть. Этот обработчик весьма быстро скопирует этот байт прямо в выделеный тобою буффер в user-space и отданный команде read. Дальше вызовится процедура планировщика которая из всех спящих процессов пнет именно твой птому что именно ему пришли в этот момент данные.

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

Цитировать
К тому же, в старт-стопном режиме обмена данными я не могу рассчитывать на чёткие временные интервалы между двумя сигналами.
А теперь по русски. Че сказать хотел? Чёткие временные интервалы тебе обеспечены будут если на системе больше ни чего другого крутиться не будет, что может притормозить обработку сигнала когда будет вызван другой процесс вместо твоего. Опять же только необходимые процессы в системе, система приоритетов и выбор правильного планировщика заданий позволят тебе сделать гарантированное время откликак по RS232'у порту из обычной пользовательской программы. Это на порядки проще чем писать свои обработчики прерываний не особо понимая что делаешь.
Цитировать
Насколько я понимаю, обработка прерываний от ком-порта в этом случае - самый правильный способ.
не правильно понимаешь. тоесть конечно это гарантирует что твой код первый кто узнает о том что пришли данные, но вот остальная часть слишком уж не тривиальна.
Цитировать
Программа реагирует на пришедший в порт байт именно по факту его получения
Таки отреагирует имеено на пришедшие байты. Именно по факту получения. Без лишнего гемороя.


Я тут конечно распинаюсь, но ты мне нифига не веришь и сидишь пальцем у виска крутишь. Тогда другой вопрос: а ты пробовал чтобы говорить что это не работает? код в студию! сдается мне там будет страшный копец который вообще не должен работать. мы все дружно поржём и скажем как на самом деле надо было написать.
Если реально сильно быстро и сильно критично повесь туда ARM на гигагерц, выкини вообще 232й интерфейс (довольно медленнная штука), прямо в арм вшей всю логику.

RT-Linux это кстати ядерные задачи которые именно обработчики прерываний и + обычный линукс который сам крутится рядом с ними как одна из задач. как то приблизительно так.


Пользователь решил продолжить мысль [time]Wed Feb  9 20:27:11 2011[/time]:

от куда 24 милисекунды? расчётное подлетное время? я умножил 24000 на 8 и получил сильно знакомую цифру в 192000 (bps надо полагать). Признавайся ты именно так получил эту цифру =)
Открою секрет. там не 8 бит на каждый байт. как минимум 10: старт бит, 8 бит данных, опциональный бит чётности и стоп бит. Бит данных может быть кстати меньше.
« Последнее редактирование: 09 Февраля 2011, 20:30:40 от Yurror »

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
Цитировать
Вызовится обработчик в который ты так отчаяно пытаешься залезть. Этот обработчик весьма быстро скопирует этот байт прямо в выделеный тобою буффер в user-space и отданный команде read. Дальше вызовится процедура планировщика которая из всех спящих процессов пнет именно твой птому что именно ему пришли в этот момент данные.
Ну так правильно! Именно это мне и нужно! Но как технически это осуществить - я не знаю.
Цитировать
Я тут конечно распинаюсь, но ты мне нифига не веришь и сидишь пальцем у виска крутишь. Тогда другой вопрос: а ты пробовал чтобы говорить что это не работает? код в студию! сдается мне там будет страшный копец который вообще не должен работать. мы все дружно поржём и скажем как на самом деле надо было написать.
Я потому и пишу на форум, что не могу это правильно сделать. И прошу у вас помощи. Мне не нужен готовый код, который я вставлю и у меня всё полетит. Но если вы дадите мне какие-либо учебные материалы или примеры - этого будет достаточно.

Пользователь решил продолжить мысль 10 Февраля 2011, 10:46:15:
Цитировать
Таки АЦП гонит данные через стандартный UART?
Да
Цитировать
скорость обмена какая?
4800
Цитировать
от куда 24 милисекунды? расчётное подлетное время? я умножил 24000 на 8 и получил сильно знакомую цифру в 192000 (bps надо полагать). Признавайся ты именно так получил эту цифру =)
Столько нужно для получения 9 битов - 8 значащих и один - чётности. Или нет?
« Последнее редактирование: 10 Февраля 2011, 10:46:15 от Vil84 »

Оффлайн alexander.pronin

  • Старожил
  • *
  • Сообщений: 2539
    • Просмотр профиля
Re: Передача ядру указателя на пользователь&#
« Ответ #7 : 10 Февраля 2011, 13:25:31 »
ТС, если мне память не изменяет, что-то уже было.
Еще раз скажу, что у всех микросхем USART есть FIFO. По памяти, на 16 байт.
Далее считаем время заполнения FIFO так.
Пусть скорость 19200 бит/c.
Примем 10 бит на байт, для простоты.
1/ 19200 * 10 *16 = 0,008333333 сек или 8.3 мс
Чтобы ничего не пропало даром берем интервал считывания в 2 раза ниже - 4 мс.
И считываем весь FIFO USART так
cat /dev/ttyS0 >> file_buffer
Точка.
ЗЫ. Можно организовать FIFO канал, чтобы не писать прямо в файл.
ЗЫ2. Чуть не забыл.
Используйте многопроцессность и таймер. Этого джентальментского набора хватит для решения любых Ваших задач.
« Последнее редактирование: 10 Февраля 2011, 13:53:14 от alexander.pronin »

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Тут прога вычитывающая байтики из порта и на каждый полученный байтик отсылающая ответ.
Минимальная обработка полученной информации ((unsigned char)buf[ i ] > 3 ? 0 : 1)

на скоростях 4800bps только ОЧЕНЬ МЕДЛЕННЫЙ ЛЕНИВЕЦ не успеет отреагировать.

(Нажмите, чтобы показать/скрыть)

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

P.S. написано жутко криво и топорно. не учтено что буфер на отправку может временно переполниться.
« Последнее редактирование: 10 Февраля 2011, 14:35:21 от Yurror »

Оффлайн alexander.pronin

  • Старожил
  • *
  • Сообщений: 2539
    • Просмотр профиля
Привычки использовать прерывания пошли от однопроцессного мышления (DOS). :idiot2:

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Алгоритм то обработки принимаемых значений сложный?
одно изменение АЦП сколько байт?

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
 
Алгоритм то обработки принимаемых значений сложный?
одно изменение АЦП сколько байт?
Нет, алгоритм несложен, а одно изменение АЦП - 9 байт.
 Спасибо за пример, сейчас буду разбираться

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
Прикрути буферизацию ввода/вывода и вперед.

Оффлайн Vil84

  • Автор темы
  • Новичок
  • *
  • Сообщений: 17
    • Просмотр профиля
 To Yurror:
 Спасибо, дядя Юра :), огромное за примерчик и, особенно, за вторую ссылку. Таки да, так значительно проще. Хотя переписываю чуть-чуть по-другому, но принцип тот же.

Оффлайн alexander.pronin

  • Старожил
  • *
  • Сообщений: 2539
    • Просмотр профиля
Re: Передача ядру указателя на пользователь&#
« Ответ #14 : 11 Февраля 2011, 12:20:36 »
Еще добавлю для полноты картины, на всякий случай.
Если Вы имеете непрерывный поток данных, а иногда его надо как-то обрабатывать (писать в БД, рисовать графики, считать среднепотолочное и т.д.).
Делается 2 переключающихся дескриптора файлов. В один пишется, другой используется. По окончании обработки (использования) происходит переключение.
ЗЫ. Рад, что Вы встали на верную дорогу.
« Последнее редактирование: 11 Февраля 2011, 12:22:13 от alexander.pronin »

 

Страница сгенерирована за 0.05 секунд. Запросов: 25.