linux设备驱动之字符设备驱动模型(2)
在上一篇中我们已经了解了字符设备驱动的原理,也了解了应用层调用内核函数的机制,但是我们每次操作设备,都必须首先通过mknod命令创建一个设备文件名,比如说我们要打开u盘,硬盘等这些设备,难道我们还要自己创建,就如同刘老师常说的一句话,这也太山寨了吧,所以我们今天我们来点比较专业的,让函数帮我们自动创建;
在Linux 下,设备和驱动通常都需要挂接在一种总线上,总线有PCI、USB、I2C、SPI 等等,总线是处理器和设备之间的通道,在设备模型中,所有的设备都通过总线相连,一总线来管理设备和驱动函数;
因此我们先了解一下sys下的目录
block:用于管理块设备,系统中的每一个块设备会在该目录下对应一个子目录;
bus:用于管理总线,没注册一条总线,在该目录下有一个对应的子目录,其中,每个总线子目录下会有两个子目录:devices和drivers。
devices包含里系统中所有属于该总线的的设备。
drivers包含里系统中所有属于该总线的的驱动。
class:将系统中的设备按功能分类。
devices:该目录提供了系统中设备拓扑结构图。
dev:该目录已注册的设备节点的视图。
kernel:内核中的相关参数。
module:内核中的模块信息。
fireware:内核中的固件信息。
Fs:描述内核中的文件系统。
下面的代码是我们在sys/class中创建一个名为dog的类,然后在创建一个设备(wangcai);
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/err.h> MODULE_LICENSE("GPL");
MODULE_AUTHOR("bunfly"); struct class *dog;
struct device *wangcai; int bunfly_init()
{
dog = class_create(THIS_MODULE, "dog");//创建一个dog类
if(IS_ERR(dog)) {
PTR_ERR(dog);
return ;
} wangcai = device_create(dog, NULL, MKDEV(, ), NULL, "wangcai%d", );//创建一个名为旺财的设备
if(IS_ERR(wangcai)) {
PTR_ERR(wangcai);
return ;
} return ;
} int bunfly_exit()
{
printk("this is bunfly_exit\n"); return ;
} module_init(bunfly_init);
module_exit(bunfly_exit);
在实际的工作中我们一般都不需要创建类,设备等,linux系统都为常见的设备分好了类,而设备厂商都已经提供了,我们做的就是来驱动这些设备;在sys/class类中我们经常用的就是misc(杂项类)
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动,其定义如下:
struct device;
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;
};
extern int misc_register(struct miscdevice * misc); //混杂设备注册
extern int misc_deregister(struct miscdevice *misc); //混杂设备注销
#define MODULE_ALIAS_MISCDEV(minor) \
MODULE_ALIAS("char-major-" __stringify(MISC_MAJOR) \
"-" __stringify(minor))
#endif
下面代码是在misc下注册一个名为bunfly_led的设备;插入模块后,在/dev下生成一个名为bunfly_led的设备名
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/miscdevice.h> MODULE_LICENSE("GPL");
MODULE_AUTHOR("bunfly"); struct file_operations fops;//方法
struct miscdevice led; int bunfly_init()
{
led.name = "bunfly_led";//设备名
led.fops = &fops;//关联方法
misc_register(&led);//在杂项类中注册led return ;
} int bunfly_exit()
{
printk("this is bunfly_exit\n");
misc_deregister(&led);//注销 return ;
} module_init(bunfly_init);
module_exit(bunfly_exit);
下面代码的功能是用ioctl()函数控制led灯,格式:./ioctl /dev/bunfly_led 0 (灯亮) | 1(灯灭)
#include <stdio.h>
#include <string.h>
#include <fcntl.h> //输入 ./ioctl /dev/bunly_led 1(灯灭) : 0(灯亮)
int main(int argc, char *argv[])
{
if(argc != ) {
printf("using %s <devname> 1:0\n", argv[]);
return ;
} int fd = ;
fd = open(argv[], O_RDWR);
if(fd < ) {
perror("open");
return ;
} //argv【2】为字符,需要atoi转换为数字
ioctl(fd, atoi(argv[]));
close(fd);
return ;
}
内核中:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/gpio.h> MODULE_LICENSE("GPL");
MODULE_AUTHOR("bunfly"); int bunfly_open(struct inode *n, struct file *fp);
long bunfly_ioctl(struct file *fp, unsigned int num, unsigned long vlaue);
void led_on();
void led_off(); struct file_operations fops;//方法
struct miscdevice led; unsigned long gpio_virt;
unsigned long *gpm4con, *gpm4dat; int bunfly_init()
{
fops.open = bunfly_open;//调用系统函数
fops.unlocked_ioctl = bunfly_ioctl; gpio_virt = ioremap(0x11000000, SZ_4K);//led物理地址到虚拟地址的映射
gpm4con = gpio_virt + 0x02e0;
gpm4dat = gpio_virt + 0x02e4; led.name = "bunfly_led";
led.fops = &fops;
misc_register(&led);//注册杂项类设备led return ;
} int bunfly_exit()
{
printk("this is bunfly_exit\n");
misc_deregister(&led);//注销设备 return ;
} module_init(bunfly_init);
module_exit(bunfly_exit); int bunfly_open(struct inode *n, struct file *fp)
{
printk("this is bunfly_open\n");
return ;
} long bunfly_ioctl(struct file *fp, unsigned int num, unsigned long vlaue)
{
if(num == ) {
led_on();
}
else {
if(num == ) {
led_off();
}
else {
printk("unkonw command %d\n", num);
}
} return ;
} void led_on()
{
*gpm4con &= ~0xffff;
*gpm4con |= 0x1111;
*gpm4dat = 0x0;
} void led_off()
{
*gpm4con &= ~0xffff;
*gpm4con |= 0x1111;
*gpm4dat = 0xf; }
linux设备驱动之字符设备驱动模型(2)的更多相关文章
- 【转】深入浅出:Linux设备驱动之字符设备驱动
深入浅出:Linux设备驱动之字符设备驱动 一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据 ...
- 手把手教Linux驱动3-之字符设备架构详解,有这篇就够了
一.Linux设备分类 Linux系统为了管理方便,将设备分成三种基本类型: 字符设备 块设备 网络设备 字符设备: 字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程 ...
- Linux驱动设计——字符设备驱动(一)
Linux字符设别驱动结构 cdev结构体 struct cdev { struct kobject kobj; struct module *owner; const struct file_ope ...
- Linux 设备驱动之字符设备
参考转载博客:http://blog.chinaunix.net/uid-26833883-id-4369060.html https://www.cnblogs.com/xiaojiang1025/ ...
- linux中c表示字符设备文件符号
linux中c表示字符设备文件,b表示块设备文件,l表示符号链接文件,r表示可读权限,w表示可写权限.linux文件属性解读:文件类型:-:普通文件 (f)d:目录文件b:块设备文件 (block)c ...
- linux设备驱动之字符设备驱动模型(1)
一:字符设备驱动 在linux下面,应用层看到的一切皆为文件(名字)所有的设备都是文件,都可以调用open,read,write来操作,而在内核中每个中每个设备有唯一的对应一个设备号: APP ( ...
- 深入浅出:Linux设备驱动之字符设备驱
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...
- 【Linux驱动】字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 1.字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面 ...
- 蜕变成蝶~Linux设备驱动之字符设备驱动
一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...
随机推荐
- EM实现
以下是实验设计 设计一个一维的数据,14个数据,7个成一组,一个高斯分布,整体数据隐含了2个高斯分布. 系统最初给出第一个数属于z0的概率0.9,最后一个数属于在z1的概率0.9,其余数据不可判定. ...
- LeetCode之“链表”:Reorder List
题目链接 题目要求: Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You ...
- FFMPEG结构体分析:AVIOContext
注:写了一系列的结构体的分析的文章,在这里列一个列表: FFMPEG结构体分析:AVFrame FFMPEG结构体分析:AVFormatContext FFMPEG结构体分析:AVCodecConte ...
- java集合类中的迭代器模式
不说模式的问题,看一个<<设计模式之禅>>里面的例子. 老板要看到公司了各个项目的情况.(我知道我这个概述很让人头大,看代码吧) 示例程序 v1 package Iterato ...
- os x 下的strace命令
在linux下的strace跟踪命令在os x下找寻不见鸟,取而代之的是 dtruss命令,在os x下看一个程序的动态库依赖可以使用 otools -L xxx命令
- (python3爬虫实战-第一篇)利用requests+正则抓取猫眼电影热映口碑榜
今天是个值得纪念了日子,我终于在博客园上发表自己的第一篇博文了.作为一名刚刚开始学习python网络爬虫的爱好者,后期本人会定期发布自己学习过程中的经验与心得,希望各位技术大佬批评指正.以下是我自己做 ...
- 记录一下Maven整合spring,hibernate,strusts2我程序中出的bug
action类如下 package com.itheima.movenweb.action; import java.util.List; import org.apache.struts2.Serv ...
- H5页面转成图片并下载到本地
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- miniui几个常用知识点汇总
1.在表格中去除系统自带的序列号,请看代码: function allAndBrief(id) { if(id==1){ grid.set({ columns: [ { type: "ind ...
- sort list(给链表排序)
Sort a linked list in O(n log n) time using constant space complexity. 题目要求使用O(nlogn)时间复杂度,可以考虑使用归并排 ...