- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/uaccess.h>
- #include <linux/io.h>
- #include "head.h"
-
- unsigned int major;//保存主设备号
- char kbuf[128] = {0};
- unsigned int *vir1_moder;
- unsigned int *vir1_odr;
- unsigned int *vir1_rcc;
- unsigned int *vir2_moder;
- unsigned int *vir2_odr;
- unsigned int *vir2_rcc;
- unsigned int *vir3_moder;
- unsigned int *vir3_odr;
- unsigned int *vir3_rcc;
- //封装操作方法
- 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)
- {
- int ret;
- ret = copy_to_user(ubuf,kbuf,size);
- if (ret)
- {
- printk("copy_to_user err\n");
- return -EIO;
- }
- return 0;
- }
- ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *lof)
- {
- int ret = 0;
- ret = copy_from_user(kbuf,ubuf,size);
- if (ret)
- {
- printk("copy_from_user err\n");
- return -EIO;
- }
- switch(kbuf[0])
- {
- case '1':
- (*vir1_odr) |= (0x1 << 10);
- break;
- case '2':
- (*vir1_odr) &= (~(0x1 << 10));
- break;
- case '3':
- (*vir2_odr) |= (0x1 << 10);
- break;
- case '4':
- (*vir2_odr) &= (~(0x1 << 10));
- break;
- case '5':
- (*vir3_odr) |= (0x1 << 8);
- break;
- case '6':
- (*vir3_odr) &= (~(0x1 << 8));
- break;
- default:
- printk("输入错误\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)
- {
- //字符设备驱动注册
- major = register_chrdev(0,"mychrdev",&fops);
- if(major < 0)
- {
- printk("字符串设备驱动注册失败\n");
- }
- printk("字符设备驱动注册成功 major = %d\n",major);
- //相关寄存器内存映射
- vir1_odr = ioremap(LED1_ODR,4);
- if (vir1_odr == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir1_rcc = ioremap(LED1_RCC,4);
- if (vir1_rcc == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir1_moder = ioremap(LED1_MODER,4);
- if (vir1_moder == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir2_odr = ioremap(LED2_ODR,4);
- if (vir2_odr == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir2_rcc = ioremap(LED2_RCC,4);
- if (vir2_rcc == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir2_moder = ioremap(LED2_MODER,4);
- if (vir2_moder == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir3_odr = ioremap(LED3_ODR,4);
- if (vir3_odr == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir3_rcc = ioremap(LED3_RCC,4);
- if (vir3_rcc == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- vir3_moder = ioremap(LED3_MODER,4);
- if (vir3_moder == NULL)
- {
- printk("物理内存映射失败%d\n",__LINE__);
- return -EFAULT;
- }
- printk("寄存器内存映射成功\n");
- //硬件寄存器的初始化
- //RCC使能
- (*vir1_rcc) |= (0x1 << 4);
- //设置PE10为输出
- (*vir1_moder) &= (~(0x3 << 20));
- (*vir1_moder) |= (0x1 << 20);
- //默认关灯
- (*vir1_odr) &= (~(0x1 << 10));
- //RCC使能
- (*vir2_rcc) |= (0x1 << 5);
- //设置PE10为输出
- (*vir2_moder) &= (~(0x3 << 20));
- (*vir2_moder) |= (0x1 << 20);
- //默认关灯
- (*vir1_odr) &= (~(0x1 << 10));
- //RCC使能
- (*vir1_rcc) |= (0x1 << 4);
- //设置PE10为输出
- (*vir1_moder) &= (~(0x3 << 16));
- (*vir1_moder) |= (0x1 << 16);
- //默认关灯
- (*vir1_odr) &= (~(0x1 << 8));
-
- return 0;
- }
- static void __exit mycdev_exit(void)
- {
- //取消物理内存映射
- iounmap(vir1_moder);
- iounmap(vir1_rcc);
- iounmap(vir1_odr);
- iounmap(vir2_moder);
- iounmap(vir2_rcc);
- iounmap(vir2_odr);
- iounmap(vir3_moder);
- iounmap(vir3_rcc);
- iounmap(vir3_odr);
- //字符设备驱动注销
- unregister_chrdev(major,"mychrdev");
-
- }
- module_init(mycdev_init);
- module_exit(mycdev_exit);
- MODULE_LICENSE("GPL");
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- int main(int argc,const char * argv[])
- {
- char buf[128] = {0};
- int fd = open("/dev/mychrdev",O_RDWR);
- if(fd < 0)
- {
- printf("设备文件打开失败\n");
- exit(-1);
- }
- while(1)
- {
- printf("请输入对LED的控制命令1(LED1开灯)2(LED1关灯)3(LED2开灯)4(LED2关灯)5(LED3开灯)6(LED3关灯)>");
- fgets(buf,sizeof(buf),stdin);//在终端输入数据到buf
- buf[strlen(buf)-1] = '\0';
- write(fd,buf,sizeof(buf));
- memset(buf,0,sizeof(buf));
- }
- close(fd);
- return 0;
- }