первый драйвер пространства ядра в Linux

Я смог управлять GPIO с помощью системного вызова mmap для управления работой светодиодов непосредственно из пользовательского пространства. Теперь я хочу реализовать драйвер в пространстве ядра.

Я пытаюсь написать свой первый драйвер устройства пространства ядра для 16 * 2 строк ЖК-дисплея в Linux для контроллера ARM RPi. Теперь мне нужно получить доступ к GPIO для этой цели.

В AVR я использую для доступа к порту вот так.

#define PORTA  *(volatile unsigned char*)0x30

Я читал, что LLD говорит использовать функции inb() и outb() для доступа к порту ввода/вывода.
http://www.makelinux.net/ldd3/chp-9-sect-2

1> Можем ли мы не использовать #define адрес порта для доступа к GPIO?

2> Каковы преимущества использования функций inb() и outb() для управления GPIO?

Пожалуйста, предложите.


person Katoch    schedule 19.02.2013    source источник


Ответы (2)


1) использование определений часто упрощает вашу задачу. Вы можете, конечно, не использовать для своего порта define и использовать эту конструкцию буквально везде, где вам нужно получить доступ к порту. Но тогда вам придется везде заменять 0x30 на другой адрес, если вы измените дизайн своего устройства, например, если вы решите подключить свой светодиод к порту B. Также это сделает ваш код менее читаемым. В качестве альтернативы вы можете объявить функцию, которая будет обращаться к вашему порту. Если такая простая функция объявлена ​​inline (если ваш компилятор поддерживает встроенные строки), то разницы в производительности нет.

2) преимущество использования inb() и outb() заключается в переносимости вашей программы. Если это не проблема, то можно получить прямой доступ к вашему порту.

person Serge    schedule 19.02.2013
comment
я думаю, что inb() использует адресное пространство ввода-вывода для чтения порта вместо использования отображаемого в памяти пространства. - person Katoch; 20.02.2013
comment
что вы подразумеваете под переносимостью программы? - person Katoch; 20.02.2013
comment
Пожалуйста, прочитайте это en.wikipedia.org/wiki/Software_portability для определения. - person Serge; 20.02.2013
comment
Допустим, вы переходите на другую модель ЦП того же производителя или совместимую модель, которая не имеет отдельного адресного пространства ввода-вывода, но предоставляет порты с теми же адресами, что и исходный продукт. Затем вы просто используете параметры компилятора, чтобы сообщить ему архитектуру, для которой вы создаете свою программу, и он легко переключается между двумя различными методами доступа. - person Serge; 20.02.2013
comment
Конечно, когда мы говорим о встроенной разработке, такая гибкость редко имеет место, но все же использование встроенных функций компилятора может сэкономить ваши затраты на разработку. В любом случае, вы должны проверить документы для вашего случая. Вопрос был более или менее общим, поэтому я дал общий ответ. Вы всегда должны учитывать все особенности при выборе. - person Serge; 20.02.2013
comment
спасибо за вашу помощь.....› понял, что функция inb() будет скрывать детали для доступа к порту ввода/вывода внутри нее ---› и мы можем использовать ее на любом другом контроллере, который использует ARM с точки зрения переносимости зрения ---› потому что реализация доступа к порту скрыта за функциями inb() и outb(). - person Katoch; 20.02.2013
comment
@Katoch - я думаю, что inb() использует адресное пространство ввода-вывода... - Нет, RP использует SoC ARM, который имеет ввод-вывод с отображением памяти. Нет ни адресного пространства ввода-вывода, ни инструкций ввода-вывода, таких как x86. - person sawdust; 20.02.2013

В AVR я использую для доступа к порту вот так.

#define PORTA  *(volatile unsigned char*)0x30

Это неправильное определение, которое перегружает символ PORTA.
Помимо определения адреса порта как 0x30, вы также разыменовываете это местоположение.
Таким образом, на самом деле это операция чтения, но нет никаких указаний того в названии, т.е. вы действительно определили макрос для READ_PORTA.

1> Можем ли мы не использовать #define адрес порта для доступа к GPIO?

Конечно можно (и нужно).

 #define PORTA (unsigned char *)0x30

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

2> Каковы преимущества использования функций inb() и outb() для управления GPIO?

Таким образом, код представляет собой недвусмысленное утверждение о том, что ввод-вывод выполняется независимо от того, использует ли архитектура порты ввода-вывода или ввод-вывод с отображением памяти.
Любой, кто читает следующее, должен понять, что происходит:

x = inb(PORTA);

против путаницы при использовании вашего макроса:

x = PORTA;

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

Вам также следует ознакомиться и использовать стиль кодирования ядра Linux.

person sawdust    schedule 20.02.2013