05 字符设备的API

一、字符设备API

1. cdev_init()

/**
* cdev_init() - initialize a cdev structure
* @cdev: the structure to initialize
* @fops: the file_operations for this device
*
* Initializes @cdev, remembering @fops, making it ready to add to the
* system with cdev_add().
*/
void cdev_init(struct cdev *cdev, const struct file_operations *fops)

头文件:#include <linux/cdev.h>

功能:初始化cdev结构体

参数:

@cdev  cdev结构体

@fops  操作函数的结构体

返回值:

2. register_chrdev_region()

/**
* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
* the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)

头文件:#include <linux/cdev.h>

功能:静态注册设备号,必须包含主设备号

参数:

@from  设备号(主设备号(12bit)+次设备号(20bit)),由MKDEV(MAJOR, MINOR)的返回值得到

@count   设备号的个数

@name   设备的名字 (在cat /proc/devices看到它)

返回值:

成功返回0,失败返回负的错误码。

3. unregister_chrdev_region()

/**
* unregister_chrdev_region() - return a range of device numbers
* @from: the first in the range of numbers to unregister
* @count: the number of device numbers to unregister
*
* This function will unregister a range of @count device numbers,
* starting with @from. The caller should normally be the one who
* allocated those numbers in the first place...
*/
void unregister_chrdev_region(dev_t from, unsigned count)

头文件:#include <linux/cdev.h>

功能:注销设备号

参数:

@from  设备号

@count   次设备的个数

返回值:

4. cdev_add()

/**
* cdev_add() - add a char device to the system
* @p: the cdev structure for the device
* @dev: the first device number for which this device is responsible
* @count: the number of consecutive minor numbers corresponding to this
* device
*
* cdev_add() adds the device represented by @p to the system, making it
* live immediately. A negative error code is returned on failure.
*/
int cdev_add(struct cdev *p, dev_t dev, unsigned count)

功能:添加字符设备

参数:

@p   cdev结构体

@dev  设备号(第一个设备号)

@count 次设备的个数

返回值:

成功返回0,失败返回负的错误码。

/**
* cdev_del() - remove a cdev from the system
* @p: the cdev structure to be removed
*
* cdev_del() removes @p from the system, possibly freeing the structure
* itself.
*/
void cdev_del(struct cdev *p)

功能:删除字符设备

参数:

@p  cdev结构体

一、动态注册设备号

/**
* alloc_chrdev_region() - register a range of char device numbers
* @dev: output parameter for first assigned number
* @baseminor: first of the requested range of minor numbers
* @count: the number of minor numbers required
* @name: the name of the associated device or driver
*
* Allocates a range of char device numbers. The major number will be
* chosen dynamically, and returned (along with the first minor number)
* in @dev. Returns zero or a negative error code.
*/
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

头文件:#include <linux/cdev.h>

功能:让系统自动分配一个设备号,并注册

参数:

@dev      用来获得系统分配的设备号

@baseminor     第一个次设备号

@count     次设备号个数

@name     设备的名字

返回值:

成功返回0,失败返回负的错误码。

二、自动创建设备节点

/* This is a #define to keep the compiler from merging different
* instances of the __key variable */
#define class_create(owner, name) \
({ \
static struct lock_class_key __key; \
__class_create(owner, name, &__key); \
})

头文件:#include <linux/device.h>

功能:创建设备类

参数:

@owner  THIS_MODULE

@name  设备类的名字

返回值:

返回一个struct class结构的指针,然后通过IS_ERR()判断是否出错,通过PTR_ERR()获取负的返回值。

/**
* class_destroy - destroys a struct class structure
* @cls: pointer to the struct class that is to be destroyed
*
* Note, the pointer to be destroyed must have been created with a call
* to class_create().
*/
void class_destroy(struct class *cls)

头文件:#include <linux/device.h>

功能:删除设备类

参数:

@cls  struct class 的指针变量

返回值:

/**
* device_create - creates a device and registers it with sysfs
* @class: pointer to the struct class that this device should be registered to
* @parent: pointer to the parent struct device of this new device, if any
* @devt: the dev_t for the char device to be added
* @drvdata: the data to be added to the device for callbacks
* @fmt: string for the device‘s name
*
* This function can be used by char device classes. A struct device
* will be created in sysfs, registered to the specified class.
*
* A "dev" file will be created, showing the dev_t for the device, if
* the dev_t is not 0,0.
* If a pointer to a parent struct device is passed in, the newly created
* struct device will be a child of that device in sysfs.
* The pointer to the struct device will be returned from the call.
* Any further sysfs files that might be required can be created using this
* pointer.
*
* Returns &struct device pointer on success, or ERR_PTR() on error.
*
* Note: the struct class passed to this function must have previously
* been created with a call to class_create().
*/
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)

头文件:#include <linux/device.h>

功能:创建一个设备,并注册到sys文件系统中

参数:

@class

@parent  NULL

@devt   设备号

@drvdata  NULL

@fmt    设备号的名字

返回值:

返回一个struct device的指针变量,通过IS_ERR()判断出错,通过PTR_ERR()获取负的错误码。

/**
* device_destroy - removes a device that was created with device_create()
* @class: pointer to the struct class that this device was registered with
* @devt: the dev_t of the device that was previously registered
*
* This call unregisters and cleans up a device that was created with a
* call to device_create().
*/
void device_destroy(struct class *class, dev_t devt)

头文件:#include <linux/device.h>

功能:销毁设备

参数:

@class  

@dev_t  设备号

返回值:

三、内核中错误码

头文件:#include <linux/err.h>

/*
* Kernel pointers have redundant information, so we can use a
* scheme where we can return either an error code or a normal
* pointer with the same return value.
*
* This should be a per-architecture thing, to allow different
* error and pointer decisions.
*/
#define MAX_ERRNO 4095

#ifndef __ASSEMBLY__

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)

static inline void * __must_check ERR_PTR(long error)
{
return (void *) error;
}

static inline long __must_check PTR_ERR(__force const void *ptr)
{
return (long) ptr;
}

static inline bool __must_check IS_ERR(__force const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}

static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
{
return !ptr || IS_ERR_VALUE((unsigned long)ptr);
}

时间: 2024-07-30 13:50:45

05 字符设备的API的相关文章

05 字符设备驱动

一.字符设备驱动函数接口 1.初始化cdev结构体void cdev_init(struct cdev * cdev, const struct file_operations * fops)功能:初始化cdev结构体参数:@cdev cdev结构体 @fops 操作函数的结构体 2.申请设备号int register_chrdev_region(dev_t from, unsigned count, const char * name);参数:@from 包含主设备号的数字 @count 设备

Linux实现字符设备驱动的基础步骤

Linux应用层想要操作kernel层的API,比方想操作相关GPIO或寄存器,能够通过写一个字符设备驱动来实现. 1.先在rootfs中的 /dev/ 下生成一个字符设备.注意主设备号 和 从设备号.可用例如以下shell脚本生成: if [ ! -e audioIN ];then sudo mknod audioIN c 240 0 fi 生成的设备为 /dev/audioIN ,主设备号240,从设备号0. 2.写audioINdriver.ko ,audioINdriver.c 基本代码

Linux字符设备驱动框架

字符设备是Linux三大设备之一(另外两种是块设备,网络设备),字符设备就是字节流形式通讯的I/O设备,绝大部分设备都是字符设备,常见的字符设备包括鼠标.键盘.显示器.串口等等,当我们执行ls -l /dev的时候,就能看到大量的设备文件,c就是字符设备,b就是块设备,网络设备没有对应的设备文件.编写一个外部模块的字符设备驱动,除了要实现编写一个模块所需要的代码之外,还需要编写作为一个字符设备的代码. 驱动模型 Linux一切皆文件,那么作为一个设备文件,它的操作方法接口封装在struct fi

Linux设备驱动之字符设备驱动

一.linux系统将设备分为3类:字符设备.块设备.网络设备. 应用程序调用的流程框图: 三种设备的定义分别如下, 字符设备:只能一个字节一个字节的读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后顺序进行.字符设备是面向流的设备,常见的字符设备如鼠标.键盘.串口.控制台.LED等. 块设备:是指可以从设备的任意位置读取一定长度的数据设备.块设备如硬盘.磁盘.U盘和SD卡等存储设备. 网络设备:网络设备比较特殊,不在是对文件进行操作,而是由专门的网络接口来实现.应用程序不能直接访

简单字符设备驱动程序

linux驱动程序开发步骤 1)查看原理图.数据手册,了解设备的操作方法. 2)在内核中找到相近的驱动程序,以它为模板进行开发,有时候需要从零开始. 3)实现驱动程序的初始化:比如向内核注册驱动程序,这样应用程序传入文件名时,内核才能找到相应的驱动程序. 4)设计所要实现的操作,比如open,read,write,close. 5)实现中断服务(不是必需的) 6)编译该驱动程序到中,或者用insmod命令加载. 7)测试驱动程序.  驱动框架 应用程序API接口read,open,write 是

字符设备之异步通信

基于字符设备驱动之中断按键来进行分析字符设备驱动的另一种技巧:异步通知--一种可以让驱动程序变的很主动的方法 一.目标: 按键按下时,驱动层序主动通知应用程序有数据可读,这样就不用应用程序老是自己主动去读数据,专心做自己的事,该来的不用去请都会自己送上门来,瞬间就高大上起来啦 要思考的问题: ①注册信号处理函数 ②谁发信号?内核驱动 ③发给谁?APP.前提是App要告诉驱动它的PID ④怎么发?kell_fasync()函数 二.首先在ubuntu上感受一下这种服务: (1)man signal

SylixOS字符设备驱动框架

1.概述 本文档主要介绍SylixOS中字符设备驱动框架,适用于在SylixOS集成开发环境下进行字符设备驱动开发的学习. 注:文中xxx是指具体设备名,编写对应驱动时,自行命名(如RTC.COMPASS等). 2.SylixOS字符设备驱动简介 字符设备是指只能以字节为单位进行读写的设备,读取数据需按照先后顺序,不能随机读取设备内存中某一数据.常见的字符设备如:鼠标.键盘.串口等. 在SylixOS中,每个字符设备都会在/dev目录下对应一个设备文件,用户程序可通过设备文件(或设备节点)来使用

(57)Linux驱动开发之三Linux字符设备驱动

1.一般情况下,对每一种设备驱动都会定义一个软件模块,这个工程模块包含.h和.c文件,前者定义该设备驱动的数据结构并声明外部函数,后者进行设备驱动的具体实现. 2.典型的无操作系统下的逻辑开发程序是:这种三层的裸机驱动模型是足够满足低耦合.高内聚的特点的. 3.当有操作系统存在时,设备驱动成为了连接硬件和内核的桥梁,这时候的设备驱动对外表现为操作系统的API,与直接裸机开发不同,裸机开发时的设备驱动是应用工程师的API.如果设备驱动都按照操作系统给出的独立于设备的接口而设计,应用程序将可以使用统

字符设备集中编程模型

1.重要数据结构 - struct file_operaions - struct inode - struct file 2.杂设备驱动模板:struct miscdevice - 注册:int misc_register(struct miscdevice *misc) - 注销:int misc_deregister(struct miscdevice *misc) 3.早期标准字符设备驱动模板: - 注册:int register_chrdev(unsigned int major, c