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");

相关推荐
你好,我叫C小白1 小时前
C语言 常量,数据类型
c语言·开发语言·数据类型·常量
多吃蔬菜!!!2 小时前
vscode 搭建C/C++开发环境搭建(linux)
linux·c语言·c++
爱和冰阔落7 小时前
从关机小游戏学 C 语言:分支循环 + 关键字(break/continue)实战
c语言·开发语言
Korloa8 小时前
表达式(CSP-J 2021-Expr)题目详解
c语言·开发语言·数据结构·c++·算法·蓝桥杯·个人开发
屁股割了还要学8 小时前
【数据结构入门】排序算法:插入排序
c语言·开发语言·数据结构·算法·青少年编程·排序算法
艾莉丝努力练剑9 小时前
【C语言16天强化训练】从基础入门到进阶:Day 5
c语言·c++·学习·算法
哈哈哼嘿12 小时前
C语言:函数指针,数组,结构体
c语言
Ustinian_31014 小时前
【C/C++】For 循环展开与性能优化【附代码讲解】
c语言·开发语言·c++
tt5555555555551 天前
C/C++嵌入式笔试核心考点精解
c语言·开发语言·c++
科大饭桶1 天前
C++入门自学Day14-- Stack和Queue的自实现(适配器)
c语言·开发语言·数据结构·c++·容器