Transferred from: http://blog.csdn.net/yikai2009/article/details/8653697
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Directory (?) [-]
- Blocking
- Blocking operations
- Non-blocking operation
- Blocking mode-read-implementation
- Blocking mode-write-implementation
- Non-blocking read and write operations
- Implementation of instance---read blocking
- Instance---key driver blocking implementation
- 1 in the Open function to see if it is blocking or non-blocking mode
- 2 See also in the Read function
- 3 in the application
- 1 running in blocking mode
- 2 run in a non-blocking manner
Blocking:
When designing a simple character driver, you should be aware of an important issue.
What should a device do when it cannot immediately satisfy a user's read and write requests?
For example: No data is readable when calling read, but may be later;
Or a process tries to write data to the device, but the device is temporarily not ready to receive data.
Applications typically do not care about this problem, and the application simply calls read or write and gets the return value.
The driver should (by default) block the process and put it to sleep until the request can be satisfied .
Blocking actions:
When performing a device operation, if a resource is not available, the process is suspended until the operational conditions are met.
The suspended process goes to sleep and is moved from the scheduler's run queue until the waiting condition is met.
Non-blocking operation:
The process cannot perform device operations without suspending, he either abandons, or keeps querying until it can be manipulated.
Blocking mode-read-implementation:
In a blocking driver, read is implemented as follows:
If the process calls read but the device has no data or insufficient data, the process is blocked.
When the new data arrives, the wake-up process is blocked.
Blocking mode-write-implementation: In a blocking driver, the write implementation is as follows: If the process calls write, but the device does not have enough space for it to write data, the process is blocked. The process is awakened when the data in the device is read away and the buffer is partially empty. Non-blocking read and write operations:
blocking Modeis a file read and write operation
default mode, but application programmers can use the O_NONBLOCK flag to artificially
SetRead and write operations as
non-blocking mode. (This flag is defined in < linux/fcntl.h >, specified when the file is opened.) If
set the O_NONBLOCK flag, read and write behave differently if the process does not have data ready when the read is called, or if the buffer does not have space when the write is called, the system just
simple return to-eagain, while
does not block processes. The implementation of the instance---read blocking:
using while is because there may be other signals waking up to sleep, and we want to re-detect if there is data through the while ....
Example---key driver blocking implementation: 1, in the open function to see whether the blocking mode or non-blocking mode: The file structure contains the F_FLAGS flag bit, to see whether the blocking mode or non-blocking mode:
O_nonblock is non-blocking mode;
[CPP]View PlainCopy
- if (File->f_flags & o_nonblock)/ * Non-blocking operation * /
- {
- if (Down_trylock (&button_lock))/ * Cannot get the semaphore, Down_trylock returns a non-0 value immediately * /
- Return-ebusy;
- }
- else/ * Blocking operation * /
- {
- / * Get the semaphore * /
- Down (&button_lock); / * Get no sleep * /
- }
2, see the same in the Read function:
[CPP]View PlainCopy
- if (File->f_flags & o_nonblock)/ * Non-blocking operation * /
- {
- if (!ev_press)/// ev_press is 1 for press, 0 if set, no button pressed, * /
- Return-eagain; / * Return-eagain Let's do it again * /
- }
- else/ * Blocking operation * /
- {
- / * If there is no key action, hibernate * /
- Wait_event_interruptible (BUTTON_WAITQ, ev_press);
- }
3, in the application: 1, to run in a blocking manner: the background to execute the application, the process is asleep, press the key, immediately print the key number;
[CPP]View PlainCopy
- int main (int argc, char **argv)
- {
- unsigned char key_val;
- int oflags;
- FD = open ("/dev/buttons", O_RDWR);
- if (FD < 0)
- {
- printf ("can ' t open!\n");
- return-1;
- }
- While (1)
- {
- Read (FD, &key_val, 1);
- printf ("key_val:0x%x\n", key_val);
- }
- return 0;
- }
2, run in a non-blocking manner:
when the open driver, the incoming flag o_nonblock non-blocking;Background execution Application:
[CPP]View PlainCopy
- int main (int argc, char **argv)
- {
- unsigned char key_val;
- int ret;
- int oflags;
- FD = open ("/dev/buttons", O_RDWR | O_nonblock);
- if (FD < 0)
- {
- printf ("can ' t open!\n");
- return-1;
- }
- While (1)
- {
- ret = Read (FD, &key_val, 1);
- printf ("key_val:0x%x, ret =%d\n", Key_val, ret);
- Sleep (5);
- }
- return 0;
- }
non-blocking mode, no keystroke value pressed, the program immediately return;
The read return value is-1;
Linux device Driver---Blocking character device driver---o_nonblock---non-blocking flag "turn"