#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include "head.h"int major;
char kbuf[128] = {0};//定义指针接收映射成功的虚拟内存首地址
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;
gpio_t *vir1;
gpio_t *vir2;
gpio_t *vir3;
unsigned int *vir;
struct class *cls;
struct device *dev;
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);int ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user filad\n");return ret;}return 0;
}ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{int ret;ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user filed\n");return ret;}int c=(kbuf[0]-'0')*2+(kbuf[1]-'0');switch(c){case 2:(vir1->ODR)&=(~(0x1<<10));break;case 3:(vir1->ODR) |=(0x1<<10);break;case 4:(vir2->ODR)&=(~(0x1<<10));break;case 5:(vir2->ODR) |=(0x1<<10);break;case 6:(vir3->ODR)&=(~(0x1<<8));break;case 7:(vir3->ODR) |=(0x1<<8);break;default:printk("input error\n");break; }return 0;}int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
// 定义操作方法结构体遍历并且初始化
struct file_operations fops = {.open=mycdev_open,.read=mycdev_read,.write=mycdev_write,.release=mycdev_close,
};static int __init mycdev_init(void)
{int i;// 注册字符设备驱动major = register_chrdev(0, "mychrdev", &fops);if(major<0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功major=%d\n",major);//向上提交目录信息cls = class_create(THIS_MODULE,"mycdev");if (IS_ERR(cls)){printk("向上提交目录信息失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");//向上提交设备信息for(i = 0;i < 3; i++){dev = device_create(cls, NULL, MKDEV(major, i), NULL, "mycdev%d", i);if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(cls);}}printk("向上提交设备节点成功\n");//完成硬件寄存器物理内存的映射vir=ioremap(RCC_MP_AHB4_ENSETR,4);if(vir==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;} vir1=ioremap(GPIOE,sizeof(gpio_t));if(vir1==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir2=ioremap(GPIOF,sizeof(gpio_t));if(vir2==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir3=ioremap(GPIOE,sizeof(gpio_t));if(vir3==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("物理内存映射成功\n");(vir1->MODER) &= (~(0x3<<20));(vir1->MODER) |= (0x1<<20);(vir2->MODER) &= (~(0x3<<20));(vir2->MODER) |= (0x1<<20);(vir3->MODER) &= (~(0x3<<16));(vir3->MODER) |= (0x1<<16); (*vir) |= (0x3<<4);(vir1->ODR) &= (~(0x1<<10));(vir2->ODR) &= (~(0x1<<10));(vir3->ODR) &= (~(0x1<<8));return 0;
}
static void __exit mycdev_exit(void)
{iounmap(vir);iounmap(vir1);iounmap(vir2);iounmap(vir3);int i;for(i=0;i<3;i++)device_destroy(cls,MKDEV(major,i));class_destroy(cls);unregister_chrdev(major,"mycdev");}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");