arm 11 Tiny 6410 gpio駆動入力と出力を実現
この駆動は簡単だと言われていますが、必要なので、自分で書きました.
実は最后にもし初心者がこの駆动を书くならばやはり简単ではないことを発见して、多くの人に闻いて、多くの招待状を出して、会の人はごくわずかで、ネット上で贴ったのはすべていくつか入力buttonと出力のledだけを中断するdemoで、とても使いにくくて、私は私の书いたことを大家に分かち合って、みんなはどんな问题があって直接私に闻くことができます.
注意すべき点を列挙します
従来よく見られていたGPIOが割り込みとして使用されていた場合、*GPIO多重機能を一般的なGPIO機能に設定する、*GPIOをinput状態に設定する.*中断が発生する方法を設定する.上昇が延びるか、それとも下降が延びるか.*割り込みコントローラenable GPIO_の設定Xビット
以下は私の駆動コードです.本来は16ビット入力16ビット出力を実現すると言っていましたが、今はまず1ビット入力と1ビット出力を貼り付けます.
実は最后にもし初心者がこの駆动を书くならばやはり简単ではないことを発见して、多くの人に闻いて、多くの招待状を出して、会の人はごくわずかで、ネット上で贴ったのはすべていくつか入力buttonと出力のledだけを中断するdemoで、とても使いにくくて、私は私の书いたことを大家に分かち合って、みんなはどんな问题があって直接私に闻くことができます.
注意すべき点を列挙します
従来よく見られていたGPIOが割り込みとして使用されていた場合、*GPIO多重機能を一般的なGPIO機能に設定する、*GPIOをinput状態に設定する.*中断が発生する方法を設定する.上昇が延びるか、それとも下降が延びるか.*割り込みコントローラenable GPIO_の設定Xビット
以下は私の駆動コードです.本来は16ビット入力16ビット出力を実現すると言っていましたが、今はまず1ビット入力と1ビット出力を貼り付けます.
//gpio_drv.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "usr_gpio"
#define GPIO_INPUT_0 S3C64XX_GPN(0)// key1
#define GPIO_OUTPUT_0 S3C64XX_GPK(5)// led2
#define GPIO_INNUM 1
#define GPIO_OUTNUM 1
short temp;
int gpio_irq = IRQ_EINT(0);
struct workqueue_struct *gpio_queue;
struct work_struct gpio_wq;
void goio_do_work(unsigned long data);
static unsigned long input_table[] = {
GPIO_INPUT_0,
};
static unsigned long output_table[] = {
GPIO_OUTPUT_0
};
//
void gpio_do_work(unsigned long data)
{
int i, val;
for (i = 0; i < GPIO_INNUM; i++)
{
val = gpio_get_value(input_table[i]);
temp |= ((val&0x1) << i);
}
}
//
irqreturn_t read_interrupt(int irq, void *dev_id)
{
printk("int the read_interrupt
");
queue_work(gpio_queue, &gpio_wq);
return IRQ_HANDLED;
}
static int gpio_input_init(void)
{
int ret = 0, i = 0;
for (i = 0; i < GPIO_INNUM; i++)
{
if (gpio_is_valid(input_table[i]) == -EINVAL)
{
printk("ERROR, GPIO used for input port is using by other devices !");
break;
}
//
s3c_gpio_setpull(input_table[i], S3C_GPIO_PULL_DOWN);
//
s3c_gpio_cfgpin(input_table[i], S3C_GPIO_SFN(0));
}
return ret;
}
static int gpio_output_init(void)
{
int ret = 0, i = 0;
for (i = 0; i < GPIO_OUTNUM; i++)
{
if (gpio_is_valid(output_table[i]) == -EINVAL)
{
printk("ERROR, GPIO used for output port is using by other devices !");
break;
}
//
s3c_gpio_setpull(output_table[i], S3C_GPIO_PULL_UP);
//
s3c_gpio_cfgpin(output_table[i], S3C_GPIO_SFN(1));
//
gpio_set_value(output_table[i], 1);
}
return ret;
}
int gpio_open(struct inode *inode,struct file *filp)
{
int ret;
ret = request_irq(gpio_irq, read_interrupt, IRQF_TRIGGER_RISING, DEVICE_NAME, NULL);
if (ret < 0)
{
printk("ERROR, irq %d can not be requested !
", gpio_irq);
return -EBUSY;
}
else
printk("OK,ret=%d
",ret);
gpio_queue = create_workqueue("gpio_queue");
//
INIT_WORK(&gpio_wq, (void *)gpio_do_work);
return 0;
}
int gpio_release(struct inode *inode,struct file *filp)
{
//
disable_irq(gpio_irq);
destroy_workqueue(gpio_queue);
return 0;
}
ssize_t gpio_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
unsigned long err;
count = sizeof(temp);
printk("temp=%d
", temp);
err = copy_to_user(buf,&temp, count);
return err ? -EFAULT : count;
}
ssize_t gpio_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
int i = 0;
printk("%d
", buf[0]);
for (i = 0; i < GPIO_OUTNUM; i++)
{
if(((buf[0]>>i)&0x1)== 1)
gpio_set_value(output_table[i], 1);
if(((buf[0]>>i)&0x1) == 0)
gpio_set_value(output_table[i], 0);
}
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = gpio_open,
.release = gpio_release,
.read=gpio_read,
.write=gpio_write,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops
};
//
static int __init dev_init(void)
{
int ret;
//
gpio_input_init();
gpio_output_init();
//
ret = misc_register(&misc);
if (ret < 0)
{
printk("ERROR, misc_register error");
return ret;
}
printk(DEVICE_NAME"\t initialized
");
return ret;
}
//
static void __exit dev_exit(void)
{
disable_irq(gpio_irq);
free_irq(gpio_irq, read_interrupt);
//
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("CAIHUI.");
//gpio_test.c
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
int pin_state;
int pin_no;
int fd;
char n[4];
unsigned int bytes = 0;
fd = open("/dev/usr_gpio", O_RDWR);
if (fd < 0)
{
perror("open device /dev/usr_gpio");
exit(1);
}
sleep(10);
//while(1)
{
read(fd, n, 1);
printf("%d
", n[0]);
}
printf("out
");
close(fd);
return 0;
}
#Makefile
CC = arm-linux-gcc
obj-m := gpio_drv.o
PWD := $(shell pwd)
KDIR := /home/huicai/new-work/linux-2.6.38
default:
$(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
, , 。 ,