#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include "head.h"
#include <sys/ioctl.h>
int main(int argc, char const *argv[])
{
int a,b;
int fd=open("/dev/mycdev0",O_RDWR);
if(fd<0)
{
printf("打开设备文件1失败\n");
exit(-1);
}
printf("打开设备文件1成功\n");
while(1)
{
printf("请输入1/0\n");
scanf("%d",&a);
switch (a)
{
case 1:
printf("请输入1/2/3\n");
scanf("%d",&b);
ioctl(fd,LED_ON,&b);
break;
case 0:
printf("请输入1/2/3\n");
scanf("%d",&b);
ioctl(fd,LED_OFF,&b);
break;
default:
close(fd);
return 0;
break;
}
}
close(fd);
return 0;
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/slab.h>
#include "head.h"
struct cdev* cdev;
unsigned int major=0;
unsigned int minor=0;
dev_t devno;
struct class* cls;
struct device* dev;
unsigned int *vir_led13_moder;
unsigned int *vir_led13_odr;
unsigned int *vir_led123_rcc;
unsigned int *vir_led2_moder;
unsigned int *vir_led2_odr;
int mycdev_open(struct inode* inode,struct file* file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)
{
unsigned int which;
int ret=copy_from_user(&which,(unsigned int*)arg,4);
switch (cmd)
{
case LED_ON:
switch (which)
{
case 1:(*vir_led13_odr) |= (0x1<<10);
break;
case 2:(*vir_led2_odr) |= (0x1<<10);
break;
case 3:(*vir_led13_odr) |= (0x1<<8);
break;
default:
break;
}
break;
case LED_OFF:
switch (which)
{
case 1:(*vir_led13_odr) &= (~(0x1<<10));
break;
case 2:(*vir_led2_odr) &= (~(0x1<<10));
break;
case 3:(*vir_led13_odr) &= (~(0x1<<8));
break;
default:
break;
}
break;
default:
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,
.unlocked_ioctl=mycdev_ioctl,
.release=mycdev_close,
};
static int __init mycdev_init(void)
{
int ret;
cdev=cdev_alloc();
if(cdev==NULL)
{
printk("申请字符设备驱动对象空间失败\n");
ret=-EFAULT;
goto OUT1;
}
printk("申请字符设备驱动对象空间成功\n");
cdev_init(cdev,&fops);
if(major>0)
{
ret=register_chrdev_region(MKDEV(major,minor),3,"mycdev");
if(ret)
{
printk("静态指定设备号失败\n");
goto OUT2;
}
}
else
{
ret=alloc_chrdev_region(&devno,minor,3,"mycdev");
if(ret)
{
printk("静态指定设备号失败\n");
goto OUT2;
}
minor=MINOR(devno);
major=MAJOR(devno);
}
printk("申请设备号成功\n");
ret=cdev_add(cdev,MKDEV(major,minor),3);
if(ret)
{
printk("注册字符设备驱动对象失败\n");
goto OUT3;
}
printk("注册字符设备驱动对象成功\n");
cls = class_create(THIS_MODULE,"mycdev");
if(IS_ERR(cls))
{
printk("提交目录信息失败\n");
goto OUT4;
}
printk("目录提交成功\n");
int i;
for(i=0;i<3;i++)
{
dev=device_create(cls,NULL,MKDEV(major,i),NULL,"mycdev%d",i);
if(IS_ERR(dev))
{
printk("提交设备节点失败\n");
goto OUT5;
}
}
printk("提交设备节点成功\n");
vir_led123_rcc=ioremap(PHY_LED123_RCC,4);
vir_led13_moder=ioremap(PHY_LED13_MODER,4);
vir_led13_odr=ioremap(PHY_LED13_ODR,4);
vir_led2_moder=ioremap(PHY_LED2_MODER,4);
vir_led2_odr=ioremap(PHY_LED2_ODR,4);
(*vir_led123_rcc) |= (0x3<<4);
(*vir_led13_moder) &= (~(0x33<<16));
(*vir_led13_moder) |= (0x11<<16);
(*vir_led13_odr) &= (~(0x5<<8));
(*vir_led2_moder) &= (~(0x3<<20));
(*vir_led2_moder) |= (0x1<<20);
(*vir_led2_odr) &= (~(0x1<<10));
return 0;
OUT5:
int i;
for(--i;i>=3;i--)
{
device_destroy(cls,MKDEV(major,i));
}
class_destroy(cls);
OUT4:
cdev_del(cdev);
OUT3:
unregister_chrdev_region(MKDEV(major,minor),3);
OUT2:
kfree(cdev);
OUT1:
return ret;
}
static void __exit mycdev_exit(void)
{
int i;
for(i=0;i<3;i++)
{
device_destroy(cls,MKDEV(major,i));
}
class_destroy(cls);
cdev_del(cdev);
unregister_chrdev_region(MKDEV(major,minor),3);
kfree(cdev);
iounmap(vir_led123_rcc);
iounmap(vir_led13_moder);
iounmap(vir_led13_odr);
iounmap(vir_led2_moder);
iounmap(vir_led2_odr);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
#ifndef __HEAD_H__
#define __HEAD_H__
#define PHY_LED13_MODER 0x50006000
#define PHY_LED13_ODR 0x50006014
#define PHY_LED123_RCC 0x50000A28
#define PHY_LED2_MODER 0x50007000
#define PHY_LED2_ODR 0x50007014
#define LED_ON _IOW('l',1,int*)
#define LED_OFF _IOW('l',0,int*)
#endif