#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#define GPC0_BASE 0xE0200060
int hello_major;
struct class *hello_cls;
struct device *hello_dev;
unsigned int *gpc0_conf;
unsigned int *gpc0_data;
int hello_open (struct inode *inode, struct file *filp)
{
printk("-----^_^-----%s-----\n",__FUNCTION__);
*gpc0_conf &=~(0xff<<12);
*gpc0_conf |=0x11<<12;
*gpc0_data &=~(0x03<<3);
return 0;
}
int hello_release(struct inode *inode, struct file *filp)
{
printk("-----^_^-----%s-----\n",__FUNCTION__);
*gpc0_data &=~(0x03<<3);
return 0;
}
ssize_t hello_write (struct file *filp, const char __user *buf, size_t size, loff_t *flags)
{
int value;
int ret;
printk("-----^_^-----%s-----\n",__FUNCTION__);
ret = copy_from_user(&value, buf, size);
if(ret>0){
printk("-----^_^-----copy_from_user error-----\n");
return -EINVAL;
}
switch(value){
case 1:
*gpc0_data |=0x01<<3;
break;
case 2:
*gpc0_data &=~(0x01<<3);
break;
case 3:
*gpc0_data |=0x01<<4;
break;
case 4:
*gpc0_data &=~(0x01<<4);
break;
case 5:
*gpc0_data |=0x03<<3;
break;
case 6:
*gpc0_data &=~(0x03<<3);
break;
}
return size;
}
struct file_operations fops={
.open =hello_open,
.release =hello_release,
.write =hello_write,
};
static int __init hello_drv_init(void)
{
int ret;
printk("-----^_^-----%s-----\n",__FUNCTION__);
#if 0
ret = register_chrdev(254,"hello_dev",&fops);
if(ret!=0){
printk("-----^_^-----register_chrdev error-----\n");
return -EINVAL;
}
#else
hello_major =register_chrdev(0,"hello_major",&fops);
if(hello_major<0){
printk("-----^_^-----register_chrdev error-----\n");
return -EINVAL;
}
#endif
hello_cls=class_create(THIS_MODULE, "hello_drv");
if(IS_ERR(hello_cls)){
printk("-----^_^-----class_create error-----\n");
ret=PTR_ERR(hello_cls);
goto err_unregister_dev;
}
hello_dev =device_create(hello_cls,NULL, MKDEV(hello_major, 4),NULL,"hello_drv");
if(IS_ERR(hello_dev)){
printk("-----^_^-----device_create error-----\n");
ret=PTR_ERR(hello_dev);
goto err_class_destory;
}
gpc0_conf = (unsigned int *)ioremap(GPC0_BASE, 8);
if(IS_ERR(gpc0_conf)){
printk("-----^_^-----ioremap error-----\n");
ret=PTR_ERR(gpc0_conf);
goto err_device_destory;
}
gpc0_data = gpc0_conf+1;
return 0;
err_device_destory:
device_destroy(hello_cls, MKDEV(hello_major, 4));
err_class_destory:
class_destroy(hello_cls);
err_unregister_dev:
unregister_chrdev(hello_major, "hello_major");
return ret;
}
static void __exit hello_drv_exit(void)
{
printk("-----^_^-----%s-----\n",__FUNCTION__);
iounmap(gpc0_conf);
device_destroy(hello_cls, MKDEV(hello_major, 4));
class_destroy(hello_cls);
#if 0
unregister_chrdev(254, "hello_dev");
#else
unregister_chrdev(hello_major, "hello_major");
#endif
}
module_init(hello_drv_init);
module_exit(hello_drv_exit);
MODULE_LICENSE("GPL");
KERNEL_DIR=/home/zzz/fs210/kerner_v1/linux-3.0.8
CUR_DIR=$(shell pwd)
OBJS=hello_drv
OBJS1=test
all:
make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
arm-none-linux-gnueabi-gcc $(OBJS1).c -o $(OBJS1)
clean:
make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
rm -rf $(OBJS1)
install:
cp *.ko /opt/rootfs/drv_module
cp $(OBJS1) /opt/rootfs/drv_module
obj-m +=$(OBJS).o
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int fd;
int temp;
fd = open("/dev/hello_drv",O_RDWR);
if(fd<0){
perror("open error");
exit
}
while(1){
printf("请输入开灯或者关灯:");
scanf("%d",&temp);
write(fd,&temp,sizeof(temp));
}
close(fd);
return 0;
}