Article directory
gettimeofday
gettimeofday
is 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);
gettimeofday
The function accepts two parameters: struct timeval *tv
and struct timezone *tz
. tv
Is a timeval
pointer to a structure used to store the obtained time value. tz
is a timezone
pointer to a structure used to obtain time zone information (in newer systems, this parameter has been deprecated and can be passed NULL
).
timeval
The structure is defined as follows:
struct timeval {
time_t tv_sec; // 秒数
suseconds_t tv_usec; // 微秒数
};
gettimeofday
After the function is successfully executed, the current time and date information is stored in the structure tv
pointed to by the parameter timeval
.
Here is a gettimeofday
simple 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 gettimeofday
0 is returned for success and -1 for failure. On success, the seconds and microseconds values can be obtained by accessing the tv.tv_sec
and fields.tv.tv_usec
It is worth noting that gettimeofday
the 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
kmalloc
It 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.
kmalloc
The 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);
size
The parameter specifies the size, in bytes, of the memory block to be allocated.flags
Parameters 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_HIGHUSER
etc.
kmalloc
The function returns a pointer to the allocated memory block, or returns if the allocation failed NULL
.
It should be noted that kmalloc
after using the allocated memory, you should use the corresponding kfree
function to release the memory to avoid memory leaks.
All in all, kmalloc
it 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_t
Is 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_t
Type 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, makedev
macros can be used to combine major and minor device numbers into a single dev_t
type of device number. For example:
dev_t device = makedev(major_number, minor_number);
You can then use MAJOR
the and MINOR
macros 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_t
type 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_t
it 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_region
It 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/tty
provides 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_region
The prototype of the function is as follows:
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, const char *name);
dev
Is adev_t
pointer to a variable of type that receives the assigned device number range.firstminor
Is the first minor device number in the range of device numbers to be assigned.count
Is the number of devices within the device number range to be allocated.name
is an optional device name used to/proc/devices
display device information in .
After calling alloc_chrdev_region
the function, the kernel allocates a contiguous range of device numbers and stores them in dev
the 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 /dev
how to create device nodes.
After you have finished using the allocated device number range, you need to use unregister_chrdev_region
a function to release the range. For example:
unregister_chrdev_region(*dev, count);
alloc_chrdev_region
The and unregister_chrdev_region
functions are typically used during the initialization and cleanup phases of character device drivers to allocate and free device number ranges.
In summary, alloc_chrdev_region
it 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
kstrtoul
is 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);
s
is the string to be converted.base
It 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 as0x
hexadecimal).res
Is aunsigned long
pointer to a type variable that receives the converted result.
The function parses the string s
into an unsigned long integer and stores the result in res
the 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.
kstrtoul
Functions 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, kstrtoul
it 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.