9.13作业

#include <linux/init.h>

#include <linux/module.h>

#include <linux/cdev.h>

#include <linux/fs.h>

#include <linux/device.h>

#include <linux/uaccess.h>

#include <linux/slab.h>

struct cdev *cdev

char kbuf[128]=0;

unsigned int major=0;

unsigned int minor=0;

dev_t devno;

module-param(major,unit,0664); //方便在命令行传递major的值

struct class*cls;

struct device *dev;

struct mutex mutex; //定义互斥体

int mycdev_open(struct inode *inode,struct file*file)

{

mutex_lock(&mutex);//上锁

printk("%s:%s:%d\n",FILE,func,LINE);

return 0;

}

long mycdev_ioctl(struct file *file,unsigned int cmd,unsigned long arg)

{

int which;

//获取arg对应的用户空间中的值

int ret=copy_from_user(&which,(void *)arg,4);

if(ret)

{

printk("从用户空间获取数据失败\n");

return -EIO;

}

switch (cmd)

{

case LED_ON:

switch(which)

{

case 1: //LED1

vir_led1->ODR |= 1 << 10;

break;

case 2:

vir_led2->ODR |= 1 << 10;

break;

case 3:

vir_led3->ODR |= 1 << 8;

break;

}

break;

case LED_OFF:

switch(which)

{

case 1: //LED1

vir_led1->ODR &= (~(1 << 10));

break;

case 2:

vir_led2->ODR &= (~(1 << 10));

break;

case 3:

vir_led3->ODR &= (~(1 << 8));

break;

}

break;

}

return 0;

}

nt mycdev_close(struct inode *inode,struct file *file)

{

mutex_unlock(mutex);//解锁

printk("%s:%s:%d\n",FILE,func,LINE);

return 0;

}

//定义操作方法结构体变量并赋值

struct file_operation fops={

.open=mycdev_open,

.read=mycdev_read,

.write=mycdev_write,

.realease=mycdev_close,

};

int all_led_init(void)

{

vir_led1=ioremap(PHY_LED1_ADDR,sizeof(gpio_t));

if(vir_led1==NULL)

{

printk("ioremap filed: %d\n",LINE);

return -ENOMEM;

}

vir_led2=ioremap(PHY_LED2_ADDR,sizeof(gpio_t));

if(vir_led2==NULL)

{

printk("ioremap filed: %d\n",LINE);

return -ENOMEM;

}

vir_led3=vir_led1;

vir_rcc=ioremap(PHY_RCC_ADDR,4);

if(vir_rcc==NULL)

{

printk("ioremap filed: %d\n",LINE);

return -ENOMEM;

}

printk("物理地址映射成功\n");

//寄存器的初始化

//rcc

(*vir_rcc) |= (0x3<<4);

//LED1

vir_led1->MODER &= (~(3<<20));

vir_led1->MODER |= (1<<20);

vir_led1->ODR &= (~(1<<10));

//LED2

vir_led2->MODER &= (~(3<<20));

vir_led2->MODER |= (1<<20);

vir_led2->ODR &= (~(1<<10));

//LED3

vir_led3->MODER &= (~(3<<16));

vir_led3->MODER |= (1<<16;

vir_led3->ODR &= (~(1<<8));

printk("寄存器初始化成功\n");

return 0;

}

static int __init mycdev_init(void)

{

int ret;

//为字符设备驱动对象申请空间

cdev=cdev_alloc();

if(cdev==NULL)

{

printk(" 字符设备驱动对象申请空间失败\n");

ret=-EFAULT;

goto out1;

}

printk("申请对象空间成功");

//初始化字符设备驱动对象

cdev------init(cdev,&fops);

//申请设备号

if(major>0)//静态指定设备号

{

ret=register_chrdev_region(MKDEV(major,minor),3,"myled");

if(ret)

{

printk("静态申请设备号失败\n");

goto out2;

}

}

else if(major==0)//动态申请设备号

{

ret=register_chrdev_region(MKDEV(major,minor),3,"myled");

if(ret)

{

printk("动态申请设备号失败\n");

goto out2;

}

major=MAJOR(devno);//获取主设备号

major=MINOR(devno);//获取次设备号

}

printk("申请设备号成功\n");

mutex_init(&mutex);//初始化互斥体

//字符设备驱动对象注册

ret=cdev_add(cdev,MKDEV(major,minor),3);

if(ret)

{

printk("字符设备驱动对象注册失败\n");

goto out3;

}

printk("字符设备驱动对象注册成功\n");

//寄存器映射以及初始化

all_led_init();

//向上提交目录

cls=class_create(THIS_MODULE,"myled");

if(IS_ERR(cls))

{

printk("向上提交目录失败\n");

return -PTR_ERR(cls);

goto out4;

}

printk("向上提交目录成功\n");

//向上提交设备节点信息

int i;

for(i=0;i<3;i++)

{

dev=device_create(cls,NULL,MKDEV(major,i)NULL,"mychrdevv%d",i);

if(IS_ERR(dev))

{

printk("向上提交设备节点信息失败\n");

return -PTR_ERR(dev);

}

}

printk("向上提交设备节点信息成功\n");

return 0;

}

out5:

//释放前一次提交成功的设备信息

for(--i;i>=0;i--)

{

device_destory(cls,MKDEV(major,i));

}

class_destory(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_destory(cls,MKDEV(major,i));

}

//销毁目录信息

class_destory(cls);

//取消地址映射

iounmap(vir_led1);

iounmap(vir_led2);

iounmap(vir_rcc);

//注销字符设备驱动对象

cdev_del(cdev);

//释放设备号

unregister_chrdev_region(MKDEV(major,minor),3);

//释放对象空间

kfree(cdev);

}

module_init(mycdev_init);

module_exit(mycdev_exit);

MODULE_LICENSE("GPL");

相关推荐
zyq99101_15 分钟前
PTA刷题笔记3(微难,有详解)
c语言·笔记·学习·算法
0xCC说逆向25 分钟前
Windows逆向工程提升之IMAGE_IMPORT_DESCRIPTOR
c语言·汇编·windows·安全·逆向·pe结构
在右ZR3 小时前
嵌入式(C语言篇)Day10
c语言
Cherl.10 小时前
探索数据结构的时间与空间复杂度:编程世界的效率密码
c语言·数据结构·算法·时间复杂度·空间复杂度
ElvInR11 小时前
冒泡排序详解
c语言·c++·排序算法·冒泡排序
范纹杉想快点毕业12 小时前
Google C++ Style Guide 谷歌 C++编码风格指南,深入理解华为与谷歌的编程规范——C和C++实践指南
c语言·数据结构·c++·qt·算法
旺仔老馒头.13 小时前
【数据结构】线性表--队列
c语言·数据结构·visual studio·队列
代码程序猿RIP13 小时前
【C语言】(10)—指针4
c语言·开发语言
眸生14 小时前
自制操作系统day7(获取按键编码、FIFO缓冲区、鼠标、键盘控制器(Keyboard Controller, KBC)、PS/2协议)
c语言·汇编·计算机外设·操作系统·计算机组成原理·寄存器