3.5【Linux驱动基础知识点之五】:驱动常用函数总结




一、地址映射、地址取消映射

ioremap():地址映射

释义:在驱动入口函数中进行地址映射,获取指定物理空间对应的虚拟空间的地址。
   即:将返回值赋值给定义好的地址指针,以后操作该指针指向的位置就是操作该地址。

ioremap();

iounmap():地址取消映射

释义:在驱动出口函数中进行地址取消映射,解除实际物理地址和指针变量的关系。

iounmap();

示例

/* 实际物理地址,芯片手册中查询 */
#define GPIO1_BASE_ADDR  0x4804c000
#define GPIO1_OE_ADDR    ((GPIO1_BASE_ADDR) + (0x134))

/*  虚拟地址指针变量 */
volatile unsigned long *gpio1_oe = NULL;

/* 驱动入口函数 */
static int __init led_init(void) {
    ...

    gpio1_oe = (volatile unsigned long *)ioremap(GPIO1_OE_ADDR, 32);    /* 添加地址映射 */

    ...
}

/* 驱动出口函数 */
static void __exit led_exit(void) {
    ...

    iounmap(gpio1_oe);    /* 取消地址映射 */
    
    ...
}

二、IO内存操作函数

当映射完地址以后,可以直接通过指针访问寄存器,如:

/* 将oe寄存器bit25、26、27置0 */
*gpio1_oe &= ((~(1<<25)) | (~(1<<26)) | (~(1<<27)));

也可以使用如下操作函数进行内存读写操作。

2.1 读操作函数

readb()

readw()

readl()

原型如下:

分别对应8/16/32位机器。

参数 addr 就是要读取写内存地址,返回值就是读取到的数据。

u8  readb(const volatile void __iomem *addr)
u16 readw(const volatile void __iomem *addr)
u32 readl(const volatile void __iomem *addr)

2.2 写操作函数

writeb()

writew()

writel()

原型如下:

分别对应8/16/32位机器。

参数 value 是要写入的数值, addr 是要写入的地址。

void writeb(u8 value, volatile void __iomem *addr)
void writew(u16 value, volatile void __iomem *addr)
void writel(u32 value, volatile void __iomem *addr)

三、设备号、主设备号、设备号操作宏

MKDEV(xxx.major, 0)

MAJOR(xxx.devid)

MINOR(xxx.devid)

设备号、主设备号、次设备号操作宏

MKDEV(ma,mi)     /* 已经知道主设备号ma和次设备号mi,使用该宏可以合成为完成的设备号 */
MAJOR(xxx.devid)
MINOR(xxx.devid)

上述3个设备号操作宏在内核源码的【】文件中定义。原型如下:

#define MINORBITS   20
#define MINORMASK   ((1U << MINORBITS) - 1)

#define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))                                                                            
#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))

四、【旧字符设备驱动框架】常用函数总结

4.1 注册、注销设备驱动

register_chrdev():注册设备驱动

注册设备驱动函数一般在【驱动入口函数】中调用。

register_chrdev(); 

unregister_chrdev():注销设备驱动

注销设备驱动函数一般在【驱动出口函数】中调用。

unregister_chrdev()

五、【新字符设备驱动框架】

5.1 申请、注册、注销设备号

alloc_chrdev_region(xxx.devid);
register_chrdev_region(&xxx.devid);
unregister_chrdev_region()

alloc_chrdev_region()

register_chrdev_region()

unregister_chrdev_region()

5.2 初始化/删除设备结构体

cdev_init(xxx.cdev,  &file_operation结构体);
cdev_add(xxx.cdev,  xxx.devid,  设备个数);

cdev_del()

cdev_init()

cdev_add()

cdev_del()

5.3 创建类、删除类

class_create();
class_destroy();

class_create():创建类

xxx.class = class_create();

自动创建设备节点代码一般在cdev_add()函数之后完成,创建之前首先要创建一个class类。

class结构在内核源码的【include/linux/device.h 】文件中定义。

和class相关的函数有:

struct class *class_create (struct module *owner, const char *name);
void class_destroy(struct class *cls);

class_destroy():删除类

5.4 创建设备、摧毁设备

device_create();
device_destroy();

device_create():创建设备

xxx.device = device_create(xxx.class…);

设备结构体,在内核中由函数:

struct device *device_create(struct class *class, struct device *parent,
                             dev_t devt, void *drvdata, const char *fmt, ...)

创建一个设备,返回值由device接收。

device_destroy():摧毁设备

六、短延时函数

6.1 休眠函数(应用层函数):

备注:sleep家族函数,不占用系统资源,休眠时间不是非常准确,比如一般延时1秒,实际延时时间通常大于1秒

sleep(unsigned int seconds)

  • 秒级休眠

usleep(useconds_t usec)

  • 含义:微妙级延时

6.2 延时函数(内核层函数):

备注:delay家族函数,时间比较准确,但是会占用系统资源,使用过多会导致系统相应变慢。

mdelay(unsigned long msecs)

  • 含义:毫秒级阻塞延时

udelay(unsigned long usecs)

  • 含义:微秒级阻塞延时

ndelay(unsigned long nsecs)

  • 含义:纳秒级延时

七、GPIO常用函数

备注:

  1. 一般来说,设置一个GPIO口为输出,先执行一次gpio_direction_output,然后接下来只需执行gpio_set_value就行了

  2. gpio口的通用函数接口定义在gpiolib.c文件中,声明则在gpio.h中

gpio_direction_output(unsigned gpio, int value)

  • 含义:设置gpio为输出功能,同时设置gpio输出的值

gpio_set_value(unsigned gpio, int value)

  • 含义:设置gpio寄存器的值

gpio_direction_input(unsigned gpio)

  • 含义:设置gpio为输入功能

gpio_get_value(unsigned gpio)

  • 含义:获取gpio口的输入的值

gpio_request(unsigned gpio, const char* label)

  • 含义:使用gpio口之前,使用该函数申请GPIO的 使用。若申请成功,则说明该gpio口未被使用

gpio_free(unsigned gpio)

  • 含义:使用完gpio口之后,用该函数释放gpio口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值