2012-11-30 1 views
1

Я запускаю встроенный linux 3.2.6 на ARM-процессоре. Я использую модифицированную версию последовательного драйвера atmel для управления четырьмя портами USART на моем устройстве. Когда я использую драйвер, скомпилированный с ядром, все работает нормально. Но вместо этого я хочу запустить драйвер как модуль ядра. Я делаю все необходимые изменения и отключает внутренний драйвер, и все кажется прекрасным. Устройства 4 tty успешно зарегистрированы, и я вижу, что все мои функции зондирования и инициализации работают правильно.request_irq преуспевает, но прерывание никогда не обнаруживается

Итак, вот в чем проблема: Когда я пытаюсь написать какое-либо из устройств, моя функция «начать передачу» вызывается, а затем ждет прерывания от usart, который никогда не возникает. Таким образом, запись просто зависает, и, используя логический анализатор, я вижу, что RTS получает подтверждение, но на строке tx не отображаются байты. Я знаю, что мой вызов request_irq преуспевает, но я никогда не вижу никаких записей irq в/proc/interrupts. В драйвере я также попытался использовать request_irq для регистрации отдельного обработчика прерываний для линии gpio, и это отлично работает.

Я знаю, что это проблема, которую, вероятно, трудно диагностировать, но я ищу ЛЮБЫЕ возможные предложения, которые могли бы привести меня в правильном направлении к поиску решения. Дайте мне знать, если вам нужны какие-либо разъяснения. Спасибо

+0

Другая мысль, когда используется встроенный драйвер/proc/interupts, показывает, что irq зарегистрирован как «AIC» irqs. Может ли быть что-то, что приведет к отключению между Advanced Interrupt Controller и загружаемым модулем? – user1415608

+0

Что делает * «Я делаю все необходимые изменения и отключает внутренний драйвер» * означает? Почему вы должны «отключить» «внутренний» драйвер? Означает ли это, что в памяти могут быть две версии драйвера? Связано ли это с тем, что серийный драйвер Atmel не может быть настроен на загрузку модуля через 'make menuconfig'? – sawdust

ответ

1

Так что я, наконец, исправил свою проблему. Спасибо за ответы, ни одна из них не решила мою проблему, но они снова предложили проверить мой код. После некоторых проб и ошибок я наконец получил его работу. Первоначально я переместил структуры platform_device для каждого usart из /mach-at91/xxx_devices.c в мой загружаемый модуль. По какой-то причине структуры не получили правильные данные для сопоставления с оборудованием, я полагаю, потому что он неправильно привязывал символы от ядра (никогда не получал сообщение об ошибке), и поэтому некоторые из функций регистрации weren ' t даже вызван. Я закончил перемещение структур, и platform_device_register обращается к файлу устройств. Я также решил сохранить драйвер для консоли, используя оригинальный драйвер atmel_serial.c. Мне пришлось изменить имя платформы для консоли как в файле устройств, так и во встроенном файле atmel_serial.c, чтобы он не конфликтует с моим драйвером портов usart. Я обнаружил, что изменение имени platform_device и platform_driver для usarts из ничего, кроме «atmel_usart», привело к сбою передачи usart. Я действительно не понимаю, почему, но я просто оставляю его как atmel_usart, чтобы он работал.

Еще раз спасибо всем, кто ответил на мою проблему.

1

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

Другая вещь, которую нужно проверить, - это условные директивы компиляции для конфигурационных структур HW в вашем файле arch/arm/mach-xxx/zzz_devices.c.
Убедитесь, что структуры последовательного порта имеют что-то вроде:

#if defined(CONFIG_SERIAL_ATMEL) || defined(CONFIG_SERIAL_ATMEL_MODULE) 

, а не только

#if defined(CONFIG_SERIAL_ATMEL) 

Дополнение

Я могу ошибаться, но часы не должны иметь никакого эффекта на выводе CTS, вызывающем прерывание, правильно?

Неправильно.
Эти цифровые схемы являются синхронными машинами состояния: без часов изменение состояния на входе не может быть обработано.
Кроме того, SoCs и современные uControllers используют периферийные часы в качестве переключателей включения/выключения для этих интегрированных периферийных устройств. Часто бывает больше функциональности, то есть периферийных устройств, на кремниевой микросхеме, чем можно фактически использовать, в основном из-за недостаточного количества контактов на плате. Поэтому для снижения энергопотребления используется отключение часов для неиспользуемых устройств.

Вы слишком сосредоточены на прерываниях.
У вас нет разрешимой проблемы с прерыванием; это вторичные отказы.
Отсутствие выхода при попытке передачи является гораздо более значительным и показательным.
Коренной причиной является, вероятно, некорректная конфигурация устройств USART, поскольку передающие биты представляют собой автоматическую операцию для настроенного операционного USART &.
Если разница между нерабочими и рабочими составляет загружаемый модуль по сравнению с статической привязкой, тогда основная причина будет чем-то фундаментальным (и тривиальным), как и мои два предложения.

Также ваше отсутствие подтверждения относительно #if defined(), например. вы не ответили «О да, мы уже знали это», поднимает гигантский красный флаг, который говорит «Исправьте меня первым!»

Добавление 2

Я соблазн удалить этот ответ после того, как обнаружил, что драйвер последовательного порта Atmel не может быть сконфигурирован/построен как загружаемый модуль, используя make menuconfig (который является предпосылкой для половины ответа). (Конечно, Kconfig файла может быть взломан, чтобы сделать переменный конфигурационный Tristate вместо булева преодолеть ограничение модуля.) Я оставил комментарий к ОП. Но я также хотел сохранить комментарий к г-ну Страттону, указав, как используются символы в файле .config.

+0

Большое спасибо за полезный ответ. Я не смогу пройти тест до понедельника. Одна вещь, о которой я забыл упомянуть, это то, что я попытался переключить вывод CTS, который должен также запустить прерывание, но он тоже не удался. Я мог ошибаться, но часы не должны влиять на вывод CTS, вызывающий прерывание, верно? – user1415608

+0

@ user1415608 Если периферийное устройство UART не получает синхронизацию, возможно, это предотвратит все связанные с uart функции, включая прерывания (RTS, CTS и т. Д., Скорее всего, GPIO, а не часть UART). Недопустимый бит разрешения прерывания UART может быть другим виновником. Также подумайте, почему процедура передачи будет ждать прерывания - возможно, от идеи, что регистр передачи еще не пуст. Но это может быть ошибочным предположением при запуске, и тот, который никогда не очистится. Вы можете опробовать и распечатать бит флагов UART во время запуска драйвера или даже принудительно отправить символ. –

+0

@sawdust - я не буду утверждать, что CONFIG_SOMETHING_MODULE - это идея, которая никогда не использовалась, но обычный случай заключается не в том, чтобы создать отдельный параметр конфигурации для модуля, а скорее для того, чтобы установить опцию конфигурации в «m», y 'при настройке для модуля. Либо пройдет тест #if. Однако верно, что не все, что будет работать как встроенный, будет работать как модуль; особенно для серийных, может существовать какой-то ключевой код в другом месте ядра, поскольку серийный номер часто является первым каналом отладки. Рекурсивный grep для всего дерева для идентификаторов может быть оправдан. –

Смежные вопросы