Introduction to commonly used functions in Linux (3)


gettimeofday

gettimeofdayis a function, commonly used on UNIX and UNIX-like systems, to obtain the precise value of the current time and date. It is located <sys/time.h>in the header file and can be called with:

#include <sys/time.h>

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

gettimeofdayThe function accepts two parameters: struct timeval *tvand struct timezone *tz. tvIs a timevalpointer to a structure used to store the obtained time value. tzis a timezonepointer to a structure used to obtain time zone information (in newer systems, this parameter has been deprecated and can be passed NULL).

timevalThe structure is defined as follows:

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

gettimeofdayAfter the function is successfully executed, the current time and date information is stored in the structure tvpointed to by the parameter timeval.

Here is a gettimeofdaysimple example of using the function to get the current time:

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

Note that gettimeofday0 is returned for success and -1 for failure. On success, the seconds and microseconds values ​​can be obtained by accessing the tv.tv_secand fields.tv.tv_usec

It is worth noting that gettimeofdaythe function provides microsecond-level time accuracy, but in some new systems, it is recommended to use more modern functions, such as clock_gettime, which provide higher-precision timing functions.

kmalloc

kmallocIt is a function in the Linux kernel used to dynamically allocate kernel space memory. It is a memory allocation mechanism provided by the kernel to allocate blocks of memory at runtime that can be used for kernel code and data.

kmallocThe prototype of the function <linux/slab.h>is defined in the header file, and its common usage is as follows:

void* kmalloc(size_t size, gfp_t flags);
  • sizeThe parameter specifies the size, in bytes, of the memory block to be allocated.
  • flagsParameters are flags used to control memory allocation behavior. It can be one of the following flags or a combination of them:
    • GFP_KERNEL: Indicates allocating regular kernel memory.
    • GFP_ATOMIC: Represents the allocation of atomic memory, suitable for allocating memory in interrupt context or critical areas protected by spin locks.
    • GFP_DMA: Indicates allocating memory that can be used for DMA operations.
    • Other flags: There are other flags that can be used to specify specific memory allocation behavior, such as GFP_NOWAIT, GFP_HIGHUSERetc.

kmallocThe function returns a pointer to the allocated memory block, or returns if the allocation failed NULL.

It should be noted that kmallocafter using the allocated memory, you should use the corresponding kfreefunction to release the memory to avoid memory leaks.

All in all, kmallocit is a function in the Linux kernel used to dynamically allocate kernel space memory. It provides a convenient way to allocate memory blocks at runtime and choose different allocation strategies and flags as needed.


dev_t

dev_tIs a data type used to represent device numbers in the Linux kernel. A device number is a value that uniquely identifies a device in the system.

In Linux systems, devices can be physical devices (such as hard disks, serial ports, etc.) or virtual devices (such as virtual file systems, pseudo terminals, etc.). Each device is assigned a unique device number, which is used to identify and access the device within the kernel.

dev_tType variables usually consist of two parts: major number and minor number. Major device numbers identify the type of device, while minor device numbers identify different instances or partitions of the same type of device.

In user space, makedevmacros can be used to combine major and minor device numbers into a single dev_ttype of device number. For example:

dev_t device = makedev(major_number, minor_number);

You can then use MAJORthe and MINORmacros to extract the major and minor device numbers from the device number. For example:

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

In kernel development, dev_ttype device numbers are often used in device drivers to uniquely identify and operate devices. The device number plays an important role in registering the device, opening device files, and performing device operations.

Unsigned int type, 32 bits, used to define the device number in the driver, the high 12 bits are the primary device number, and the low 20 bits are the minor device number.

In summary, dev_tit is a data type used to represent device numbers in the Linux kernel. It consists of a major device number and a minor device number, and is used to uniquely identify devices in the system.


alloc_chrdev_region

alloc_chrdev_regionIt is a function provided by the Linux kernel and is used to dynamically allocate the major device number range of character devices in the kernel.

In Linux systems, a character device is a special class of device that /dev/ttyprovides access to the device through a character device file (for example). Each character device has a unique major number that identifies the type of device.

alloc_chrdev_regionThe prototype of the function is as follows:

int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, const char *name);
  • devIs a dev_tpointer to a variable of type that receives the assigned device number range.
  • firstminorIs the first minor device number in the range of device numbers to be assigned.
  • countIs the number of devices within the device number range to be allocated.
  • nameis an optional device name used to /proc/devicesdisplay device information in .

After calling alloc_chrdev_regionthe function, the kernel allocates a contiguous range of device numbers and stores them in devthe variable pointed to by the pointer. The major device number of the assigned device number range is MAJOR(*dev)obtained from , and the minor device number MINOR(*dev)is obtained from .

This function needs to pass the first minor device number firstminor (usually 0) specified by it, the number of devices to be allocated, count, and the device name. The device number automatically assigned after calling this function is saved in dev.
Dynamic allocation of device numbers can avoid the shortcomings caused by manually specifying device numbers, but it also has its own shortcomings, that is, it is impossible to predict /devhow to create device nodes.

After you have finished using the allocated device number range, you need to use unregister_chrdev_regiona function to release the range. For example:

unregister_chrdev_region(*dev, count);

alloc_chrdev_regionThe and unregister_chrdev_regionfunctions are typically used during the initialization and cleanup phases of character device drivers to allocate and free device number ranges.

In summary, alloc_chrdev_regionit is a function in the Linux kernel used to dynamically allocate the major device number range of character devices. It provides a convenient way to allocate the device number range and use it for the registration and use of character devices.

There are two methods of assigning device numbers, static and dynamic. Static allocation ( register_chrdev_region()function) means that when the major device number of the device is known in advance, the first device number (its minor device number is usually 0) is specified through the parameter function and the system is applied to allocate a certain number of device numbers. Dynamic allocation ( alloc_chrdev_region()) means that the system dynamically allocates the required device number by setting only the first minor device number (usually 0, the major device number is not known in advance) and the number of devices to be allocated through parameters. unregister_chrdev_region()Frees an allocated (whether static or dynamic) device number via a function.

cdev

Static memory definition initialization:

struct cdev my_cdev;
cdev_init(&my_cdev, &fops);
my_cdev.owner = THIS_MODULE;

Dynamic memory definition initialization:

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

kstrtoulis a function provided in the Linux kernel to convert a string to an unsigned long integer ( unsigned long).

The function prototype is as follows:

int kstrtoul(const char *s, unsigned int base, unsigned long *res);
  • sis the string to be converted.
  • baseIt is a base number, which specifies the base of the value represented by the string. It can be a value between 2 and 36, or 0 means that the base is automatically determined based on the string prefix (such as 0xhexadecimal).
  • resIs a unsigned longpointer to a type variable that receives the converted result.

The function parses the string sinto an unsigned long integer and stores the result in resthe variable pointed to by the pointer. If the conversion is successful, the function returns 0; if the conversion fails, an appropriate error code is returned.

kstrtoulFunctions are widely used in the kernel to parse parameters or configuration items passed by user space. It provides a safe and reliable way to convert strings to unsigned long integers for processing and use in the kernel.

In summary, kstrtoulit is a function in the Linux kernel used to convert strings into unsigned long integers. It is often used to parse parameters or configuration items passed by user space. It provides a safe and reliable way to perform string to numeric conversion.

Guess you like

Origin blog.csdn.net/qq_44710568/article/details/131953418