Linux下GPIO驱动(五) ----misc_register();
//
struct miscdevice {
int minor;
const char *name;
const struct file_operations *fops;
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};
int misc_register(struct miscdevice * misc);//注册为杂项设备
int misc_deregister(struct miscdevice *misc);//注销
miscdevice的数据结构如下图所示:

int misc_register(struct miscdevice * misc)
{
struct miscdevice *c;
dev_t dev;
int err = ; INIT_LIST_HEAD(&misc->list);// // 初始化链表头,将misc->list的next和pre都指向自己 mutex_lock(&misc_mtx);// 获取互斥锁, or睡眠
list_for_each_entry(c, &misc_list, list) { // 遍历整个misc_list链表,所有的杂项驱动设备都有一个miscdevice数据结构,这些杂项驱动设备通过一个全局的misc_list链表连在一起, 相当一个记录
if (c->minor == misc->minor) {// 如果misc_list中已经有了这个设备(minor相同),则解锁返回,这里c是遍历时的tmp miscdevice,指向当前遍历节点
mutex_unlock(&misc_mtx);
return -EBUSY;
}
} if (misc->minor == MISC_DYNAMIC_MINOR) { // 如果misc_list中没有该设备,判断minor是否准备动态分配,实验中如此设置
int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS);// misc_minors是杂项设备位图,总共有64个位DYNAMIC_MINORS=64,表示可以注册64个杂项设备,这句代码找到位图中的空闲位置(表示还能加新设备)
if (i >= DYNAMIC_MINORS) {// 如果超过总设备数,则解锁返回
mutex_unlock(&misc_mtx);
return -EBUSY;
}
misc->minor = DYNAMIC_MINORS - i - ;// 计算子设备号,赋值到misc->minor set_bit(i, misc_minors);// 对应的位图也置位
} dev = MKDEV(MISC_MAJOR, misc->minor); // 生成设备号 misc->this_device = device_create(misc_class, misc->parent, dev,
misc, "%s", misc->name);// 在sysfs中创建并注册一个设备,可以在/dev下面看到misc->name
if (IS_ERR(misc->this_device)) {
int i = DYNAMIC_MINORS - misc->minor - ;
if (i < DYNAMIC_MINORS && i >= )
clear_bit(i, misc_minors);
err = PTR_ERR(misc->this_device);
goto out;
} /*
* Add it to the front, so that later devices can "override"
* earlier defaults
*/
list_add(&misc->list, &misc_list);// 以上操作都没有问题后,将新设备加入misc_list链表,解锁返回 out:
mutex_unlock(&misc_mtx);
return err;
}
/**
* misc_deregister - unregister a miscellaneous device
* @misc: device to unregister
*
* Unregister a miscellaneous device that was previously
* successfully registered with misc_register(). Success
* is indicated by a zero return, a negative errno code
* indicates an error.
*/ int misc_deregister(struct miscdevice *misc)
{
int i = DYNAMIC_MINORS - misc->minor - ; if (list_empty(&misc->list))
return -EINVAL; mutex_lock(&misc_mtx);
list_del(&misc->list);
device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
if (i < DYNAMIC_MINORS && i >= )
clear_bit(i, misc_minors);
mutex_unlock(&misc_mtx);
return ;
}
在Linux初始化期间会执行misc_init();
static int __init misc_init(void)
{
int err; #ifdef CONFIG_PROC_FS //在proc文件系统下创建一个"misc"目录。 misc_proc_fops是该文件系统下文件的操作函数集
proc_create("misc", , NULL, &misc_proc_fops);
#endif
misc_class = class_create(THIS_MODULE, "misc"); // 前面device_create()中的misc_class就是在这里初始化的 err = PTR_ERR(misc_class);
if (IS_ERR(misc_class))
goto fail_remove; err = -EIO;
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))//注册一个主设备号为MISC_MAJOR(10)的字符设备,设备操作函数集为misc_fops goto fail_printk;
misc_class->devnode = misc_devnode;
return ; fail_printk:
printk("unable to get major %d for misc devices\n", MISC_MAJOR);
class_destroy(misc_class);
fail_remove:
remove_proc_entry("misc", NULL);
return err;
}
Linux下GPIO驱动(五) ----misc_register();的更多相关文章
- 很好的linux下GPIO驱动详解文章
原文地址 http://blog.csdn.net/llxmedici/article/details/6282372 打算跟着友善之臂的<mini2440 linux移植开发指南>来做 ...
- Linux下GPIO驱动
编写驱动程序,首先要了解是什么类型的设备.linux下的设备分为三类,分别为:字符设备,块设备和网络设备.字符设备类型是根据是否以字符流为数据的交换方式,大部分设备都是字符设备,如键盘,串口等,块设备 ...
- Linux下GPIO驱动(三) ----gpio_desc()的分析
上篇最后提出的疑问是结构体gpio_chip中的成员函数set等是怎么实现的,在回答之前先介绍下gpio_desc这个结构体. 如上图所示,右上方部分为GPIO驱动对其它驱动提供的GPIO操作接口,其 ...
- Linux下GPIO驱动(一) ----一个简单的LED驱动
/******************************* * *杂项设备驱动:miscdevice *majior=10; * * *****************************/ ...
- Linux下GPIO驱动(四) ----gpio_request();gpio_free();
//gpio_request申请gpio口 int gpio_request(unsigned gpio, const char *label) { struct gpio_desc *desc; s ...
- Linux下GPIO驱动(二) ----s3c_gpio_cfgpin();gpio_set_value();
首先来看s3c_gpio_cfgpin(); int s3c_gpio_cfgpin(unsigned int pin, unsigned int config) { struct s3c_gpio_ ...
- 飞思卡尔imx6开发板Linux下GPIO驱动
控制GPIO_1_28的输出: #define MY_BOMB_GPIO IMX_GPIO_NR(1, 28) 配置为输出方式: gpio_direction_output (MY_BOM ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之二
/** ****************************************************************************** * @author 暴走的小 ...
- 调试exynos4412—ARM嵌入式Linux—LEDS/GPIO驱动之一
/** ****************************************************************************** * @author 暴走的小 ...
随机推荐
- android124 zhihuibeijing 新闻中心-组图
package com.itheima.zhbj52.base.menudetail; import java.util.ArrayList; import android.app.Activity; ...
- 迷你template
JavaScript Micro-Templatinghttp://ejohn.org/blog/javascript-micro-templating/ //Simple JavaScript ...
- 文件I/O之ioctl函数
ioctl函数是I/O操作的杂物箱.不能用其他函数表示的I/O操作通常都能用ioctl表示.终端I/O是ioctl的最大使用方面. ioctl函数通过对文件描述符发送特定的命令来控制文件描述符所代表的 ...
- 一些ecplise 快捷键
1 F5:下一步,可以进入下一个函数栈 2 F6:当前函数的下一步,不会进入其他的函数. 3 F8:下一个断点. 4 选中一个变量或者表达式,按ctrl+shift+i 来查看内容或者添加监视的方式. ...
- centos7下载安装谷歌浏览器
centos7安装完成结束后,发现自带的火狐浏览器不太习惯,自己还是习惯谷歌浏览器,因为是新手嘛,所以自己就各种找教程看如何下载安装谷歌浏览器,一个一个按照教程试验,终于最后试验成功了一个,亲测可用. ...
- 【itclx面向对象一】tcl基础语法:过程、作用域、以及itcl面向编程回顾
学习熟悉编程的最好方法就是动手,有点面向编程思维的话,直接练习就可以.直接看demo 1.过程.作用域 #全局变量:过程外定义的变量#局部变量: 过程内部定义的变量 set a 100proc tes ...
- 设置checkbox选中,设置radio选中,根据值设置checkbox选中,checkbox勾选
设置checkbox选中,设置radio选中,根据值设置checkbox选中,checkbox勾选 >>>>>>>>>>>>&g ...
- Thinkphp kindeditor 内容转义
参考了:[解决]ThinkPHP整合Html编辑器时出现自动转义的问题 遇到问题也是保存到数据库中的内容,会转义成“\"” 使用 $data['content'] = stripslashe ...
- 电脑小白学习软件开发-C#的选择语句、异常捕获,进攻程序员
写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用视频. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是不在话下. 不得不说,C#这门语言是小编以为最好的语言.其 ...
- (译文)12个简单(但强大)的JavaScript技巧(二)
原文链接: 12 Simple (Yet Powerful) JavaScript Tips 其他链接: (译文)12个简单(但强大)的JavaScript技巧(一) 强大的立即调用函数表达式 (什么 ...