linux常用函数介绍(三)

文章目录
gettimeofday
kmalloc
dev_t
alloc_chrdev_region
cdev
kstrtoul
gettimeofday
gettimeofday是一个函数,通常在UNIX和类UNIX系统上使用,用于获取当前时间和日期的精确值。它位于 <sys/time.h> 头文件中,可以通过以下方式进行调用:

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);
1
2
3
gettimeofday函数接受两个参数:struct timeval *tv 和 struct timezone *tz。tv 是一个指向 timeval 结构的指针,用于存储获取到的时间值。tz 是一个指向 timezone 结构的指针,用于获取时区信息(在较新的系统中,该参数已被废弃,可以传递 NULL)。

timeval 结构定义如下:

struct timeval {
    time_t tv_sec;  // 秒数
    suseconds_t tv_usec;  // 微秒数
};
1
2
3
4
gettimeofday 函数成功执行后,将当前的时间和日期信息存储在 tv 参数指向的 timeval 结构中。

以下是一个使用 gettimeofday 函数获取当前时间的简单示例:

#include <stdio.h>
#include <sys/time.h>

int main() {
    struct timeval tv;
    if (gettimeofday(&tv, NULL) == 0) {
        printf("Current time: %ld seconds, %ld microseconds\n", tv.tv_sec, tv.tv_usec);
    } else {
        printf("Failed to get the current time.\n");
    }
    return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
请注意,gettimeofday 返回 0 表示成功,-1 表示失败。在成功时,可以通过访问 tv.tv_sec 和 tv.tv_usec 字段来获取秒数和微秒数的值。

值得注意的是,gettimeofday 函数提供了微秒级别的时间精度,但在一些新的系统中,推荐使用更现代的函数,如 clock_gettime,它提供了更高精度的计时功能。

kmalloc
kmalloc是Linux内核中用于动态分配内核空间内存的函数。它是内核提供的一种内存分配机制,用于在运行时分配可用于内核代码和数据的内存块。

kmalloc函数的原型在<linux/slab.h>头文件中定义,其常见的使用方式如下:

void* kmalloc(size_t size, gfp_t flags);
1
size参数指定要分配的内存块的大小,以字节为单位。
flags参数是用于控制内存分配行为的标志。它可以是以下标志之一或它们的组合:
GFP_KERNEL:表示分配常规内核内存。
GFP_ATOMIC:表示分配原子内存,适用于在中断上下文或自旋锁保护的临界区域中分配内存。
GFP_DMA:表示分配可用于DMA操作的内存。
其他标志:还有其他标志可用于指定特定的内存分配行为,如GFP_NOWAIT、GFP_HIGHUSER等。
kmalloc函数返回一个指向分配的内存块的指针,如果分配失败,则返回NULL。

需要注意的是,使用完通过kmalloc分配的内存后,应使用对应的kfree函数释放内存,以避免内存泄漏。

总而言之,kmalloc是Linux内核中用于动态分配内核空间内存的函数,它提供了一种方便的方式来在运行时分配内存块,并根据需要选择不同的分配策略和标志。

dev_t
dev_t是一个数据类型,在Linux内核中用于表示设备号的类型。设备号是用于唯一标识系统中的设备的值。

在Linux系统中,设备可以是物理设备(如硬盘、串口等)或虚拟设备(如虚拟文件系统、伪终端等)。每个设备都被分配一个唯一的设备号,用于在内核中标识和访问该设备。

dev_t类型的变量通常由两部分组成:主设备号(major number)和次设备号(minor number)。主设备号用于标识设备的类型,而次设备号用于标识同一类型设备的不同实例或分区。

在用户空间,可以使用makedev宏将主设备号和次设备号组合成一个dev_t类型的设备号。例如:

dev_t device = makedev(major_number, minor_number);
1
然后,可以使用MAJOR和MINOR宏来提取设备号中的主设备号和次设备号。例如:

unsigned int major = MAJOR(device);
unsigned int minor = MINOR(device);
1
2
在内核开发中,dev_t类型的设备号常用于设备驱动程序中,用于唯一标识和操作设备。设备号在注册设备、打开设备文件、进行设备操作等过程中起着重要的作用。

unsigned int 类型,32位,用于在驱动程序中定义设备编号,高12位为主设备号,低20位为次设备号.

总结来说,dev_t是Linux内核中用于表示设备号的数据类型,由主设备号和次设备号组成,用于唯一标识系统中的设备。

alloc_chrdev_region
alloc_chrdev_region是Linux内核提供的一个函数,用于在内核中动态分配字符设备的主设备号范围。

在Linux系统中,字符设备是一类特殊的设备,通过字符设备文件(例如/dev/tty)提供对设备的访问。每个字符设备都有一个唯一的主设备号,用于标识设备的类型。

alloc_chrdev_region函数的原型如下:

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, const char *name);
1
dev是一个指向dev_t类型的变量的指针,用于接收分配的设备号范围。
firstminor是要分配的设备号范围中的第一个次设备号。
count是要分配的设备号范围内的设备数量。
name是一个可选的设备名称,用于在/proc/devices中显示设备信息。
调用alloc_chrdev_region函数后,内核会分配一个连续的设备号范围,并将其存储在dev指针指向的变量中。分配的设备号范围的主设备号从MAJOR(*dev)获取,次设备号从MINOR(*dev)获取。

该函数需要传递给它指定的第一个次设备号firstminor(一般为0)和要分配的设备数count,以及设备名,调用该函数后自动分配得到的设备号保存在dev中。
动态分配设备号可以避免手动指定设备号时带来的缺点,但是它却也有自己的缺点,那就是无法预知在/dev下创建设备节点

在使用完分配的设备号范围后,需要使用unregister_chrdev_region函数释放该范围。例如:

unregister_chrdev_region(*dev, count);
1
alloc_chrdev_region和unregister_chrdev_region函数通常在字符设备驱动程序的初始化和清理阶段使用,用于分配和释放设备号范围。

总结来说,alloc_chrdev_region是Linux内核中用于动态分配字符设备主设备号范围的函数,它提供了一种方便的方式来分配设备号范围,并将其用于字符设备的注册和使用。

分配设备号有静态和动态的两种方法。静态分配(register_chrdev_region()函数)是 指在事先知道设备主设备号的情况下,通过参数函数指定第一个设备号(它的次设备 号通常为 0)而向系统申请分配一定数目的设备号。动态分配(alloc_chrdev_region()) 是指通过参数仅设置第一个次设备号(通常为 0,事先不会知道主设备号)和要分配的设备数目而系统动态分配所需的设备号。通过 unregister_chrdev_region()函数释放已分配的(无论是静态的还是动态的)设备号。

cdev
静态内存定义初始化:

struct cdev my_cdev;
cdev_init(&my_cdev, &fops);
my_cdev.owner = THIS_MODULE;
1
2
3
动态内存定义初始化:

struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &fops;
my_cdev->owner = THIS_MODULE;
1
2
3
int cdev_add(struct cdev *, dev_t, unsigned);  
 注册字符设备,传入 cdev 结构的指针,起始设备编号,
 以及设备编号范围。cdev_del() 函数来释放 cdev 占用的内存。
1
2
3
kstrtoul
kstrtoul是Linux内核中提供的一个函数,用于将字符串转换为无符号长整型数(unsigned long)。

函数原型如下:

int kstrtoul(const char *s, unsigned int base, unsigned long *res);
1
s是要转换的字符串。
base是进制数,指定字符串表示的数值的进制,可以是2到36之间的值,或者0表示自动根据字符串前缀判断进制(如0x表示十六进制)。
res是一个指向unsigned long类型变量的指针,用于接收转换后的结果。
函数将字符串s解析为无符号长整型数,并将结果存储在res指针指向的变量中。如果转换成功,函数返回0;如果转换失败,返回适当的错误代码。

kstrtoul函数在内核中广泛用于解析用户空间传递的参数或配置项。它提供了一种安全、可靠的方式来将字符串转换为无符号长整型数,以便在内核中进行处理和使用。

总结来说,kstrtoul是Linux内核中用于将字符串转换为无符号长整型数的函数,常用于解析用户空间传递的参数或配置项。它提供了一种安全、可靠的方式来进行字符串到数值的转换。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_44710568/article/details/131953418

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值