Linux裝置驅動程式學習(基於2440的GPIO字元裝置驅動)
阿新 • • 發佈:2018-12-30
GPIO驅動程式如下:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#define RING_MAJOR 224 //mknod /dev/ring c 224 0
#define rGPECON (*(volatile unsigned *)(vaddr+0x40))
#define rGPEDAT (*(volatile unsigned *)(vaddr+0x44))
#define rGPEUP (*(volatile unsigned *)(vaddr+0x48))
#define GPECON_MASK ~(3<<28)
#define GPECON_OUTPUT (1<<28)
#define GPEUP_MASK ~(1<<14)
#define GPEUP_OUTPUT (1<<14)
#define GPEDAT_MASK ~(1<<14)
#define GPEDAT_OUTPUT (1<<14)
#define ring_on() rGPEDAT = rGPEDAT & GPEDAT_MASK
char *vaddr;
static int ring_open(struct inode *,struct file *);
static int ring_release(struct inode *,struct file *);
static int ring_ioctl(struct inode *,struct file *,unsigned int ,unsigned long);
static struct file_operations ring_ctl_fops = {
owner : THIS_MODULE,
open : ring_open,
ioctl : ring_ioctl,
release : ring_release,
};
static int ring_open(struct inode *inode,struct file *file)
{
printk("open ring device...\n");
return 0;
}
static int ring_ioctl(struct inode *inode,struct file *fiel,unsigned int command,unsigned long arg)
{
printk("ring_ioctl called,with command=%d\n",command);
if(command ==0)
{
while(arg--)
{
printk("...");
ring_on();
}
printk("\n");
}
return 0;
}
static int ring_release(struct inode *inode,struct file *file)
{
rGPEDAT = (rGPEDAT & GPEDAT_MASK) | GPEDAT_OUTPUT;
printk("device close!!!\n");
return 0;
}
static int __init ring_init(void)
{
int err = 0;
vaddr = ioremap(0x56000000,0x100);
rGPECON = (rGPECON & GPECON_MASK) | GPECON_OUTPUT;
rGPEUP = (rGPEUP & GPEUP_MASK) | GPEUP_OUTPUT;
printk("ring_init\n");
err = register_chrdev(RING_MAJOR,"ring",&ring_ctl_fops);
if(err<0)
{
printk("fail to register\n");
return -1;
}
printk("success to register\n");
return 0;
}
static int __exit ring_exit(void)
{
printk("release this device!!!\n");
unregister_chrdev(RING_MAJOR,"ring");
return 0;
}
module_init(ring_init);
module_exit(ring_exit);
MODULE_LICENSE("GPL");
Makefile檔案:
#ring module example Makefile
ifneq ($(KERNELRELEASE),)
obj-m :=ring_driver.o
else
KERNELDIR ?= /home/czd/mike/linux-2.6.28.7
#KERNELDIR=/lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#define RING_MAJOR 224 //mknod /dev/ring c 224 0
#define rGPECON (*(volatile unsigned *)(vaddr+0x40))
#define rGPEDAT (*(volatile unsigned *)(vaddr+0x44))
#define rGPEUP (*(volatile unsigned *)(vaddr+0x48))
#define GPECON_MASK ~(3<<28)
#define GPECON_OUTPUT (1<<28)
#define GPEUP_MASK ~(1<<14)
#define GPEUP_OUTPUT (1<<14)
#define GPEDAT_MASK ~(1<<14)
#define GPEDAT_OUTPUT (1<<14)
#define ring_on() rGPEDAT = rGPEDAT & GPEDAT_MASK
char *vaddr;
static int ring_open(struct inode *,struct file *);
static int ring_release(struct inode *,struct file *);
static int ring_ioctl(struct inode *,struct file *,unsigned int ,unsigned long);
static struct file_operations ring_ctl_fops = {
owner : THIS_MODULE,
open : ring_open,
ioctl : ring_ioctl,
release : ring_release,
};
static int ring_open(struct inode *inode,struct file *file)
{
printk("open ring device...\n");
return 0;
}
static int ring_ioctl(struct inode *inode,struct file *fiel,unsigned int command,unsigned long arg)
{
printk("ring_ioctl called,with command=%d\n",command);
if(command ==0)
{
while(arg--)
{
printk("...");
ring_on();
}
printk("\n");
}
return 0;
}
static int ring_release(struct inode *inode,struct file *file)
{
rGPEDAT = (rGPEDAT & GPEDAT_MASK) | GPEDAT_OUTPUT;
printk("device close!!!\n");
return 0;
}
static int __init ring_init(void)
{
int err = 0;
vaddr = ioremap(0x56000000,0x100);
rGPECON = (rGPECON & GPECON_MASK) | GPECON_OUTPUT;
rGPEUP = (rGPEUP & GPEUP_MASK) | GPEUP_OUTPUT;
printk("ring_init\n");
err = register_chrdev(RING_MAJOR,"ring",&ring_ctl_fops);
if(err<0)
{
printk("fail to register\n");
return -1;
}
printk("success to register\n");
return 0;
}
static int __exit ring_exit(void)
{
printk("release this device!!!\n");
unregister_chrdev(RING_MAJOR,"ring");
return 0;
}
module_init(ring_init);
module_exit(ring_exit);
MODULE_LICENSE("GPL");
Makefile檔案:
#ring module example Makefile
ifneq ($(KERNELRELEASE),)
obj-m :=ring_driver.o
else
KERNELDIR ?= /home/czd/mike/linux-2.6.28.7
#KERNELDIR=/lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
endif