mycdev.c
#include
#include
#include
#include
#include
#include "led.h"
unsigned int major;
char kbuf[128]={0};
//LED1 PE10
unsigned int *vir1_moder;
unsigned int *vir1_odr;
unsigned int *vir1_rcc;
//LED2 PF10
unsigned int *vir2_moder;
unsigned int *vir2_odr;
unsigned int *vir2_rcc;
//LED3 PE8
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 *iof)
{
//向用户拷贝
int ret;
if(size> sizeof(kbuf))
size=sizeof(kbuf);
ret=copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("向用户拷贝失败\n");
return -EIO;
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mycdev_write(struct file *file,const char *ubuf,size_t size,loff_t *iof)
{
int ret;
//从用户拷贝
if(size>sizeof(kbuf))
size=sizeof(kbuf);
ret=copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("从用户拷贝失败\n");
return -EIO;
}
if(kbuf[0]=='1')
{
//LED1亮灯
(*vir1_odr) |=(0x1<<10);
}
else if(kbuf[0] == '0')
{
//LED1灭灯
(*vir1_odr) &=(~(0x1<<10));
}
else if(kbuf[0] == '2')
{
//LED2亮灯
(*vir2_odr) |=(0x1<<10);
}
else if(kbuf[0] == '3')
{
//LED2灭灯
(*vir2_odr) &=(~(0x1<<10));
}
else if(kbuf[0] == '4')
{
//LED3亮灯
(*vir3_odr) |=(0x1<<8);
}
else if(kbuf[0] == '5')
{
//LED3灭灯
(*vir3_odr) &=(~(0x1<<8));
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
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,"mycdev",&fops);
if(major<0)
{
printk("字符设备驱动注册失败\n");
return major;
}
printk("字符设备驱动注册成功major=%d\n",major);
//LED1相关寄存器映射
vir1_moder=ioremap(PHY_GPIOE_MODER,4);
if(vir1_moder==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir1_odr=ioremap(PHY_GPIOE_ODR,4);
if(vir1_odr==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir1_rcc=ioremap(PHY_RCC,4);
if(vir1_rcc==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
printk("LED1物理内存映射为虚拟内存成功\n");
//LED1相关寄存器初始化
//GPIOE使能
(*vir1_rcc) |= (0x1<<4);
//设置为输出
(*vir1_moder) &=(~(0x3<<20));
(*vir1_moder) |=(0x1<<20);
//灭灯
(*vir1_odr) &=(~(0x1<<10));
printk("LED1相关寄存器初始化成功");
//LED2相关寄存器映射
vir2_moder=ioremap(PHY_GPIOF_MODER,4);
if(vir2_moder==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir2_odr=ioremap(PHY_GPIOF_ODR,4);
if(vir2_odr==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir2_rcc=ioremap(PHY_RCC,4);
if(vir2_rcc==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
printk("LED2物理内存映射为虚拟内存成功\n");
//LED2相关寄存器初始化
//GPIOF使能
(*vir2_rcc) |= (0x1<<5);
//设置为输出
(*vir2_moder) &=(~(0x3<<20));
(*vir2_moder) |=(0x1<<20);
//灭灯
(*vir2_odr) &=(~(0x1<<10));
printk("LED2相关寄存器初始化成功");
//LED3相关寄存器映射
vir3_moder=ioremap(PHY_GPIOE_MODER,4);
if(vir3_moder==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir3_odr=ioremap(PHY_GPIOE_ODR,4);
if(vir3_odr==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
vir3_rcc=ioremap(PHY_RCC,4);
if(vir3_rcc==NULL)
{
printk("物理内存映射失败\n");
return -EFAULT;
}
printk("LED3物理内存映射为虚拟内存成功\n");
//LED3相关寄存器初始化
//GPIOE使能
(*vir3_rcc) |= (0x1<<4);
//设置为输出
(*vir3_moder) &=(~(0x3<<16));
(*vir3_moder) |=(0x1<<16);
//灭灯
(*vir3_odr) &=(~(0x1<<8));
printk("LED3相关寄存器初始化成功");
return 0;
}
static void __exit mycdev_exit(void)
{
//内存取消映射
iounmap(vir1_rcc);
iounmap(vir1_odr);
iounmap(vir1_moder);
iounmap(vir2_rcc);
iounmap(vir2_odr);
iounmap(vir2_moder);
iounmap(vir3_rcc);
iounmap(vir3_odr);
iounmap(vir3_moder);
//字符设备驱动的注销
unregister_chrdev(major,"mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
led.h
#ifndef __LED_H__
#define __LED_H__
//LED1 PE10
//LED2 PF10
//LED3 PE8
#define PHY_GPIOE_MODER 0x50006000
#define PHY_GPIOF_MODER 0x50007000
#define PHY_GPIOE_ODR 0x50006014
#define PHY_GPIOF_ODR 0x50007014
#define PHY_RCC 0x50000A28
#endif
test.c
#include
#include
#include
#include
#include
#include
#include "led.h"
int main(int argc,const char * argv[])
{
char buf[128]={0};
int fd=open("/dev/mycdev",O_RDWR);
if(fd < 0)
{
printf("打开设备文件失败\n");
return -1;
}
while(1)
{
printf("请输入控制码:0(LED1灭灯),1(LED1亮灯),2(LED2亮灯),3(LED2灭灯),4(LED3亮灯),5(LED3灭灯)\n");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]='\0';
write(fd,buf,sizeof(buf));
memset(buf,0,sizeof(buf));//清空buf
}
close(fd);
return 0;
}