用户空间函数:
int main(int argc,char** argv)
{
int fd;
int val;
fd=open("/dev/led",O_RDWR);
if(fd<0)
printf("can not open!\n");
while(1)
{
printf("please input contro bit,1:led light ,0:led close\n\r");
scanf("%d",&val);
write(fd,val,sizeof(val));
}
return 0;
}
内核空间:
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/delay.h>
#include<linux/uaccess.h>
#include<asm/irq.h>
#include<asm/io.h>
#include<asm/arch/regs-gpio.h>
#include<asm/hardware.h>
#include<linux/device.h>
static struct class* led_class;
static struct class_device* led_dev_class;
volatile unsigned long* gpfcon=NULL;
volatile unsigned long* gpfdat=NULL;
int major;
static int led_open(struct inode* inode,struct file* file)
{
printk("led_open ");
*gpfcon &=~((0x3<<8)|(0x3<<10)|(0x3<<12));
*gpfcon |=((0x1<<8)|(0x1<<10)|(0x1<<12));
return 0;
}
static ssize_t led_write(struct file* file,const char __user* buf ,size_t count,loff_t* ppos)
{
int val;
printk("first_drv_write\n");
copy_from_user(&val,buf,count);
if(val==1)
{
*gpfdat &=~((1<<4)|(1<<5)|(1<<6));
}
else
{
*gpfdat |=((1<<4) | (1<<5) |(1<<6));
}
return 0;
}
static struct file_operations first_drv_fops=
{
.owner=THIS_MODULE,
.open=led_open,
.write=led_write,
};
static int led_enter(void)
{
printk("enter driver....\n\r");
major=register_chrdev(0,"led_register",&first_drv_fops);
led_class=class_create(THIS_MODULE,"led_class");
led_dev_class=class_device_create(led_class,NULL,MKDEV(major,0),NULL,"led");
gpfcon=(volatile unsigned long*)ioremap(0x56000050,16);
gpfdat=gpfcon+1;
return 0;
}
static void led_leave(void)
{
printk("ledave driver....\n\r");
unregister_chrdev(major,"led_register");
class_device_unregister(led_dev_class);
class_destroy(led_class);
iounmap(gpfcon);
}
module_init(led_enter);
module_exit(led_leave);
MODULE_LICENSE("GPL");