linux常用函数介绍(三)


gettimeofday

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

#include <sys/time.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

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

timeval 结构定义如下:

struct timeval {
    
    
    time_t tv_sec;  // 秒数
    suseconds_t tv_usec;  // 微秒数
};

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;
}

请注意,gettimeofday 返回 0 表示成功,-1 表示失败。在成功时,可以通过访问 tv.tv_sectv.tv_usec 字段来获取秒数和微秒数的值。

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

kmalloc

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

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

void* kmalloc(size_t size, gfp_t flags);
  • size参数指定要分配的内存块的大小,以字节为单位。
  • flags参数是用于控制内存分配行为的标志。它可以是以下标志之一或它们的组合:
    • GFP_KERNEL:表示分配常规内核内存。
    • GFP_ATOMIC:表示分配原子内存,适用于在中断上下文或自旋锁保护的临界区域中分配内存。
    • GFP_DMA:表示分配可用于DMA操作的内存。
    • 其他标志:还有其他标志可用于指定特定的内存分配行为,如GFP_NOWAITGFP_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);

然后,可以使用MAJORMINOR宏来提取设备号中的主设备号和次设备号。例如:

unsigned int major = MAJOR(device);
unsigned int minor = MINOR(device);

在内核开发中,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);
  • 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);

alloc_chrdev_regionunregister_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;

动态内存定义初始化:

struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &fops;
my_cdev->owner = THIS_MODULE;
int cdev_add(struct cdev *, dev_t, unsigned);  
 注册字符设备,传入 cdev 结构的指针,起始设备编号,
 以及设备编号范围。cdev_del() 函数来释放 cdev 占用的内存。

kstrtoul

kstrtoul是Linux内核中提供的一个函数,用于将字符串转换为无符号长整型数(unsigned long)。

函数原型如下:

int kstrtoul(const char *s, unsigned int base, unsigned long *res);
  • s是要转换的字符串。
  • base是进制数,指定字符串表示的数值的进制,可以是2到36之间的值,或者0表示自动根据字符串前缀判断进制(如0x表示十六进制)。
  • res是一个指向unsigned long类型变量的指针,用于接收转换后的结果。

函数将字符串s解析为无符号长整型数,并将结果存储在res指针指向的变量中。如果转换成功,函数返回0;如果转换失败,返回适当的错误代码。

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

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

猜你喜欢

转载自blog.csdn.net/qq_44710568/article/details/131953418
今日推荐