Asynchronous notification concept: The concept of asynchronous notification is that once the device is ready, it will actively notify the application, so that the application does not need to query the device status at all. This is very similar to the concept of "interrupt" in hardware. The more accurate name is "signal-driven asynchronous IO". The signal is a simulation of the interrupt mechanism at the software level. In principle, a process receiving a signal is the same as the processor receiving an interrupt request. The signal is asynchronous, and a process does not have to wait for the arrival of the signal through any operation. In fact, the process does not know when the signal will arrive.
Asynchronous notification and device access: Blocking IO means waiting for the device to be accessible before accessing it; non-blocking IO using poll means querying whether the device is accessible; and asynchronous notification means that the device notifies itself that it is accessible, thus realizing asynchronous I/O.
Use the kill -l command to view the available signals in Linux
Signal reception
signal() function to set the processing function of the corresponding signal.
void (*signal(int signum,void(*handler))(int)))(int);
//The first parameter specifies the value of the signal; the second parameter specifies the processing function for the previous signal value. If it is SIN_IGN, it means ignoring the signal; if it is SIG_DFL, it means using the system default method to process the signal; if it is user-defined
function, the signal is captured and the function will be executed
//The prototype of this function is hard to understand, and can be broken down into: typedef void(*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler));
If the signal call succeeds, it returns the handler value of the last signal signum binding, and returns SIG_ERR if it fails.
The sigaction() function can be used to change the behavior of a process after receiving a specific signal.
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
//The first parameter of this function is the value of the signal, which can be any specific valid signal except SIGKILL and SIGSTOP; the second parameter is a pointer to an instance of the structure sigaction.
Specifies the processing function for a specific signal. If it is empty, the process will process the signal in the default way. The object pointed to by the third parameter oldact is used to save the original processing function for the corresponding signal. You can specify oldact as NULL.
If the second and third parameters are set to NULL, the function is used to detect the validity of the signal.
An example application using signals for asynchronous notifications:
#include
#include
#include
#include
#include
#include
#define MAX_LEN 100
void input handler(int num)
{
char data[MAX_LEN];
int len;
len=read(STDIN_FILENO,&data,MAX_LEN); //Read and output input on STDIN_FILENO.
data[len]=0;
printf("input available:%sn",data);
}
main()
{
int oflags;
//Start the signal drive mechanism
signal(SIGIO,input_handler); //Install input_handler() as the processing function for SIGIO signal
fcntl(STDIN_FILENO,F_SETOWN,getpid()); //The getpid() here is to obtain the current process. Note that without this step, the kernel does not know which process to send the signal to.
In Linux, the functions for implementing file locking are lock and fcntl. flock is used to apply advisory locks to files, while fcntl can not only apply advisory locks, but also mandatory locks. At the same time, fcntl can also lock a record of a file, that is, record lock.
Record locks can be divided into read locks and write locks. Read locks are also called shared locks, which enable multiple processes to establish read locks on the same part of a file. Write locks are also called exclusive locks, and only one process can establish a write lock on a certain part of a file at any time. Of course, read locks and write locks cannot be established on the same part of a file at the same time.
Notice:
fcntl is a very general function that can also change various attributes of file processes. In this section, we mainly introduce how to establish record locks. Readers who are interested in other users can refer to the fcntl manual.
oflags=fcntl(STDIN_FILENO,F_GETFL); //In order to start the one-step notification mechanism, you also need to set the FASYNC flag on the device
fcntl(STDIN_FILENO,F_SETFL,oflags|FASYNC);
//Finally enter an infinite loop, just to keep the process from terminating. If there is no infinite loop in the program, the execution will be completed immediately.
while(1);
}
Signal release:
In the asynchronous notification interaction between the device driver and the application, the application captures the signal and the driver releases the signal.
In order for a device to support asynchronous notification mechanism, three tasks are involved in the driver.
(1) Supports the F_SETOWN command, which can set filp->f_owner to the corresponding process ID in this control command processing. However, this work has been completed by the kernel and the device driver does not need to handle it.
(2) Support the processing of F_SETFL command. Whenever the FASYNC flag changes, the fasync() function in the driver will be executed. Therefore, the fasync() function should be implemented in the driver.
(3) When device resources are available, call the kill_fasync() function to trigger the corresponding signal.
Interaction between user space and device drivers during asynchronous notification processing.
Asynchronous notification mainly uses a data structure and two functions. The data structure is the fasync_struct structure, and the two functions are fasync_helper and kill_fasync.
int fasync_helper(int fd,struct file *filp,int mode,struct fasync_struct **fa); //Handle FASYNC flag change
void kill_fasync(struct fasync_struct **fa,int sig,int band); //Release signal
Device structure template that supports asynchronous notification
struct xxx_dev{
struct cdev cdev; //cdev structure
...
struct fasync_struct *async_queue; //Asynchronous structure pointer
};
Device driver fasync() function template that supports asynchronous notification
static int xxx_fasync(int fd,struct file *filp,int mode)
{
struct xxx_dev *dev=filp->private_data;
return fasync_helper(fd,filp,mode,&dev->async_queue);
}
When the device resources are available, kill_fasync() should be called to release the SIGIO signal. The third parameter is set to POLL_IN when readable and POLL_OUT when writable.
An example of a device driver signal release that supports asynchronous notification:
static ssize_t xxx_write(struct file *filp,const char_user *buf,size_t count,loff_t *f_pos)
{
struct xx_dev *dev=filp->private_data;
...
//Generate asynchronous read signal
if(dev->async_queue)
kill_fasync(&dev->async_queue,SIGIO,POLL_IN);
...
}
Finally, when closing the file, that is, in the release function, the file should be deleted from the list of asynchronous notifications.
static int xxx_release(struct inode *inode,struct file *filp)
{
//Delete the file from the asynchronous notification list
xxx_fasync(-1,filp,0);
...
return 0;
}
Previous article:ARM Linux character device driver
Next article:14. s3c2440 bare metal - interrupt controller
Recommended ReadingLatest update time:2024-11-16 09:37
- Popular Resources
- Popular amplifiers
- Network Operating System (Edited by Li Zhixi)
- Siemens PLC from Beginner to Mastery with Color Illustrations (Yang Rui)
- Siemens S7-1200-PLC Programming and Application Tutorial (3rd Edition) (Edited by Shi Shouyong)
- Siemens Motion Control Technology and Engineering Applications (Tongxue, edited by Wu Xiaojun)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- How to assign initial values to a continuous RAM range in C2000 chip
- What is 4G DTU and what are its specific functions?
- CadenceLIVE China 2022 China Online User Conference invites you to attend
- Super detailed summary of receiver sensitivity and equivalent noise bandwidth
- Difference between junction temperature and case top temperature of power device
- The problem of grounding the output signal of the half-bridge inverter circuit
- Xianyu not only hired someone to do their graduation project, but also tried to "extort" money from the seller. It's a pity for these two students from Xidian University...
- 3-wire spi (cs clk sda), LCD driver for HX8369
- 8 DDR3 surface-to-bottom mounting solution
- Where are the options for PCB material/PCB copper thickness/PCB spray color/milling edge in the Gerber file of Altium Designer?