03.04.2012.
Все получилось.
С отладочной платой поставляются примеры модулей, и среди них - модуль, регистрирующий прерывание от линии GPIO:
Код
#include <linux/module.h>
#include <linux/version.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <mach/cputype.h>
#include <mach/hardware.h>
#include <mach/mux.h>
#include <asm/gpio.h>
static int gpio_num;
static int gpio_pin;
DECLARE_COMPLETION(work);
static irqreturn_t handler (int irq, void * dev)
{
complete_all(&work);
return IRQ_HANDLED;
}
int init_module()
{
int status;
init_completion(&work);
gpio_num = 87; /* gpio_num = (bank_num * 16) + pin_num */
gpio_pin = DA830_GPIO5_7;
printk("\nTesting gpio %d (connected to boot pin S2-7)\n", gpio_num);
/* init/set pinmux */
status = davinci_cfg_reg(gpio_pin);
if (status < 0) {printk("pin could not be muxed for GPIO functionality %d\n", gpio_num);
return status;
}
status = gpio_request(gpio_num, "gpio_test\n");
if (status < 0) {printk("ERROR can not open GPIO %d\n", gpio_num);
return status;
}
gpio_direction_input(gpio_num);
printk("The current state of S2-7 pin is ");
if(gpio_get_value(gpio_num) == 0) printk("OFF. \n\tWaiting for the pin to be on..\n");
else printk("ON. \n\tWaiting for the pin to be off..\n");
status = request_irq(gpio_to_irq(gpio_num), handler, 0, "gpio_test", NULL);
if(status < 0) {printk(KERN_ERR "error %d requesting GPIO IRQ %d\n", status, gpio_num);
return status;
}
set_irq_type(gpio_to_irq(gpio_num), IRQ_TYPE_EDGE_RISING);
wait_for_completion_interruptible(&work);
printk(".. done\n");
return 0;
}
void cleanup_module(void)
{
gpio_free(gpio_num);
free_irq(gpio_to_irq(gpio_num), NULL);
}
MODULE_LICENSE("GPL");
Я его немного доработал, в частности, закомментировал функции "wait_for_completion_interruptible(&work);" и "complete_all(&work);" и вставил вызов изменения состояния светодиода в обработчик прерывания "handler". В результате теперь по каждому прерыванию от одной из линий GPIO светодиод на другой линии меняет свое состояние. Собрал, залил на плату, загрузил - все работает. Вопрос вот в чем. Как я понял, функции "wait_for_completion_interruptible()" и "complete_all()" - 'это специфические функции, реализованные чуть ли не только в Linux для ARM'ов от TI. Или я не прав ? Хоть они мне, похоже, не требуются, очень хотелось бы увидеть более-менее систематическое их описание. Кто подскажет, где его искать ? А также где искать описания на остальные функции, вроде той же "gpio_free" ? Сейчас приходится по частичкам вытаскивать его из заголовочных файлов и исходников. Описания в текстовом виде или в PDF я не нашел ...