LINUX.ORG.RU

Работа с прерываниями

 ,


1

1

Недавно занимаюсь разработкой софта под линуксом. Нужно написать протокол связи modbus, который будет общаться с железякой.
Организовать опрос драйвера удобнее, как мне показалось, с помощью системных прерываний. И вот тут я наткнулся на проблему. Дело в том, что в моем дистрибутиве (использую Ubuntu 12.10) в /usr/include/linux отсутствует interrupt.h
Нашёл инструкцию, как добавить заголовочные файлы из исходников:

$ make headers_check
$ make INSTALL_HDR_PATH=dest headers_install
$ find dest/include \( -name .install -o -name ..install.cmd \) -delete
# cp -rv dest/include/* /usr/include

Если я правильно понимаю, это просто копирование заголовочных файлов, сгенерированных из исходников в /usr/include.
Но как только в программе появлятся
#include <linux/interrupt.h>

у меня компилятор дико ругается на файлы linux/bitops.h, linux/thread_info.h и linux/list.h:
/usr/include/linux/bitops.h:175,37 - Error - unknown type name 'u64'
/usr/include/linux/bitops.h:181,2 - Error - BITS_PER_LONG not 32 or 64
/usr/include/linux/thread_info.h:24,4 - Error - unknown type name 'u32'
/usr/include/linux/thread_info.h:25,4 - Error - unknown type name 'u32'
/usr/include/linux/thread_info.h:26,4 - Error - unknown type name 'u32'
/usr/include/linux/thread_info.h:27,4 - Error - unknown type name 'u32'
/usr/include/linux/thread_info.h:28,4 - Error - unknown type name 'u64'
/usr/include/linux/thread_info.h:29,4 - Error - unknown type name 'u32'
/usr/include/linux/thread_info.h:33,4 - Error - unknown type name 'clockid_t'
/usr/include/linux/thread_info.h:38,4 - Error - unknown type name 'u64'
/usr/include/linux/list.h:26,6 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:27,6 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:41,6 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:42,5 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:43,5 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:44,6 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:62,28 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:76,22 - Error - incomplete definition of type 'struct list_head'
/usr/include/linux/list.h:88,6 - Error - incomplete definition of type 'struct list_head'
Как мне правильно добавить в систему нужные заголовочные файлы?



Последнее исправление: autrich (всего исправлений: 2)

1. ты модуль ядра пишешь, зачем тебе ядерные хидеры в /usr/include? Закинь всё дерево куда-нибудь в ~/dev/linux и там полностью всё делай.

2. http://libmodbus.org/documentation/

anonymous
()

Организовать опрос драйвера удобнее, как мне показалось, с помощью системных прерываний.

лолват

anonymous
()
Ответ на: комментарий от anonymous

Организовать опрос драйвера удобнее, как мне показалось, с помощью системных прерываний.

Драйвер последовательного порта генерирует 2 типа прерываний:

  • переполнение буфера FIFO
  • условно, конец посылки. зависит от типа протокола

Обработчик, соответственно, анализирует правильность приема данных и передает их дальше в обработку.

ты модуль ядра пишешь, зачем тебе ядерные хидеры в /usr/include? Закинь всё дерево куда-нибудь в ~/dev/linux и там полностью всё делай.

Если я закину все дерево в ~/dev/linux, то при подключении хидера interrupt.h он будет ссылаться на

#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/bitops.h>
#include <linux/preempt.h>
#include <linux/cpumask.h>
#include <linux/irqreturn.h>
#include <linux/irqnr.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
#include <linux/smp.h>
#include <linux/percpu.h>
#include <linux/hrtimer.h>
#include <linux/kref.h>
#include <linux/workqueue.h>

#include <linux/atomic.h>
#include <asm/ptrace.h>
и ошибка с заголовочными файлами не решится, если я правильно понял.
Вопрос, собственно, в том, как прицепить linux/interrupt.h таким образом, чтобы он корректно работал

autrich
() автор топика
Ответ на: комментарий от autrich

блин, тебе ж сказали — юзай готовую библиотеку. какие, на хер, прерывания, ты на голом железе пишешь, что ли?

anonymous
()

Организовать опрос драйвера удобнее, как мне показалось, с помощью системных прерываний.

Я что-то тоже, как и анонимус, не понял, почему тебе так показалось. Ты явно что-то делаешь не так.

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

по итогу это действительно будет работать на железе AM3517. Спасибо за совет, попробую разобраться с готовой библиотекой.

autrich
() автор топика

А этом модбасе случаем времена строго выдерживать не надо ? Делал бы ты железку, а то где-нибудь чего-нибудь рванет нечистое экологически.

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

вопрос временной задержки будет, но чуть позже. по стандарту modbus RTU считается концом посылки/сбоем задежка 3,5 символа.
задача стоит соорудить вот этот баян имеено на linux

autrich
() автор топика
Ответ на: комментарий от autrich

взять готовую реализацию протокола и не изобретать велосипед?

ymn ★★★★★
()
Ответ на: комментарий от autrich

Дело конечно хозяйское , линукс так линукс, но если планируешь работать в ASCII режиме , то в ядро лезть нафик не нужно. А если хочешь делать мастера с временной синхронизацией, большим количеством адресов, то от ОС больше вреда.

ilovewindows ★★★★★
()
Последнее исправление: ilovewindows (всего исправлений: 2)
Ответ на: комментарий от ilovewindows

если планируешь работать в ASCII режиме

Дело в том, что реализовать нужно оба типа протокола: и ASCII, и RTU.
Можно ли реализовать протокол с временной синхронизаией без использования прерываний? Информации по прерываниям не так много. Буду благодарен, если что-нибудь посоветуете почитать.

autrich
() автор топика
Ответ на: комментарий от autrich

Можно, если количество адресов не очень большое и период опроса не критичен. Мастеру чем-то надо задать интервал, под досом системный таймер можно на 1 миллисек. например сделать, винда и линукс (на десктопе) порядка десятков миллисекунд реально дают, меньше задать можно, но не выдерживается. Вторая проблема как передатчик выключать, если полный дуплекс то можно не выключать, а если два провода, то надо преобразователь с автоматическим выключением. Вообщем, можно обойтись без программирования в ядре, да даже если и для ядра, все рано логику работы отработать от пользователя. Если от железяки кроме протокола по модбасу ничего не нужно, то лучше ОС не использовать или недо ОС, типа ethernut , ТСР есть и таймер с последовательными портами можно забрать. А читать, общие сведения из интернета и исходники смотреть, никто не будет подробности расписывать.

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

винда и линукс (на десктопе) порядка десятков миллисекунд реально дают, меньше задать можно, но не выдерживается

Насчет Linux - вранье. И задать можно, и время выдерживается.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от ilovewindows

Вторая проблема как передатчик выключать

Тут все достаточно просто, т.к. плата будет делается под заказ, то реализация полудуплексного режима осуществляется битом RTS com порта, который управляет микрухой. Тут все работает, особых проблем нет. Сейчас проблема с RTU.

а нельзя ли обойтись работой на третьем кольце с файлом устройства из /dev?

Честно говоря, я не совсем понял, извините

autrich
() автор топика
Ответ на: комментарий от ilovewindows

Ну расскажи как, проверю и отпишусь.

Заводишь прерывания (если нет внешнего источника, то от RTC) и ждешь на poll нитью с любой RT-дисциплиной планирования. С high-res таймерами тоже можно, но несколько сложнее.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Насчет Linux - вранье. И задать можно, и время выдерживается.

Отлично, есть повод для оптимизма)
В таком случае вопрос в силе: если не использовать готовую реализацию протокола, стоит ли рассчитывать на работу с прерываниями или придется делать опрос порта только по времени?
Работа с прерываниями, как по мне, будет лучше, т.к. процессор будет свободен от обработки данных интерфейса.

autrich
() автор топика
Ответ на: комментарий от autrich

стоит ли рассчитывать на работу с прерываниями

Если под «прерыаниями» понимается работа через poll - да.

Работа с прерываниями, как по мне, будет лучше, т.к. процессор будет свободен от обработки данных интерфейса.

Работа по таймеру тоже подразумевает использование прерываний. Какие у тебя ограничения по времени?

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Какие у тебя ограничения по времени?

Ограничения порядка единиц, максимум несколько десятков миллисекунд

autrich
() автор топика
Ответ на: комментарий от ilovewindows

винда и линукс (на десктопе) порядка десятков миллисекунд реально дают, меньше задать можно, но не выдерживается.

http://www.osadl.org/QA-Farm-Continuous-real-time-monitorin.qa-farm-monitorin...

десятки/сотни микросекунд, в зависимости от системы. С PREEMPT_RT патчем.

AptGet ★★★
()
Ответ на: комментарий от autrich

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

ilovewindows ★★★★★
()
Ответ на: комментарий от AptGet

Я про обычный комп говорил, для обычной ОС, для пользовательской программы, с целью избавится от программирования в ядре.

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

Порт поддерживается стандартным драйвером. Но при работе с временной синхронизацией, нужно следить за паузой между пачками данных. Пауза в 3,5 символа - это либо сбой посылки, либо конец. Тоесть, нужно увидеть эти 3,5 символа, и затем обрабатывать посылку. Время на ответ строго не регламентируется, может достигать секунды, если не больше.

autrich
() автор топика
Ответ на: комментарий от autrich

Ограничения порядка единиц, максимум несколько десятков миллисекунд

Всё должно получиться на ядре с включенным kernel preemption и пользовательской нитью с планировщиком реального времени. Для пущей крутизны можно взять ядро с патчем -rt, но для таких времен это оверкилл.

tailgunner ★★★★★
()
Ответ на: комментарий от ilovewindows

Я про обычный комп говорил, для обычной ОС, для пользовательской программы, с целью избавится от программирования в ядре.

Патч -rt дает всё это.

tailgunner ★★★★★
()
Ответ на: комментарий от autrich

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

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

Я про обычный комп говорил,

по ссылке для обычных компов данные есть

для обычной ОС

rt-kernel доступно в убунте и дебиане «изкаробки»

для пользовательской программы

latency измеряется для пользовательского процесса, с SCHED_FIFO/SCHED_RR и высоким приоритетом, разумеется

AptGet ★★★
()
Ответ на: комментарий от ilovewindows

не пробовал. Вряд ли, т.к. этот патч не влияет напрямую на дисковый I/O.

AptGet ★★★
()
Ответ на: комментарий от FFh

на третьем кольце

Где ты у арма кольца нашёл, бедняша?

anonymous
()
Ответ на: комментарий от ilovewindows

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

Отличное решение. При этом для отслеживания времени 3,5 символа мне нужно использовать специальный драйвер последовательного порта?

autrich
() автор топика
Ответ на: комментарий от autrich

А не нужно это отслеживать. Допустим слейв передаёт и возникает пауза 4 байта. Мастер считает, что передача закончилась, и начинает новую передачу. А там что-то непонятое с линией (обрыв,помеха,неисправное устройство) просто байты не дошли до мастера и новая передача наложится на остаток ответа. В результате как неисправные два устройства будут выглядеть. Имхо, правильно подождать от конца посылки мастера максимальную длину передачи слейва. Это уже будет больше десятка миллисекунд. Так алгоритм работы мастера надежнее будет и в разы проще.

ilovewindows ★★★★★
()
Ответ на: комментарий от ilovewindows

Спасибо всем за советы. Буду рыть дальше

autrich
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.