Linux will automatically shut down the LCD after a certain period of time

Source: Internet
Author: User

From: http://blog.csdn.net/dongliqiang2006/archive/2009/06/12/4262950.aspx

[Excerpt ]:

After Linux is started, as long as the keyboard does not move for a period of time (the keyboard extended by I/O on the Development Board), the LCD will be automatically closed (black screen, display slowly disappears and so on), as long as you press the keyboard to restore. This problem took me more than a day. In fact, this is nothing if it is a handheld device. However, our company's products must always display things and solve this problem. I have read a lot of arguments, and many people have encountered this problem. However, when I was searching, I couldn't find the correct answer because of the incorrect keyword. If you have encountered the same problem and do not want to view my three-legged cat analysis, search Baidu for "blankinterval", "setterm-blank 0, now you can find a simple solution. This problem can easily lead to screen protection and power management. Indeed, this is a kind of power management. However, you cannot solve this problem from the power management of Linux kernel options. Let's step by step. First, I measured that the LCD pclk clock was gone, which meant that the kernel had shut down the LCD controller. Start with the LCD driver. I am using S3C2440, which is an upgraded version of 2410, but the LCD controller is the same. The development board manufacturer gave me the driver kernel, the driver is located in/Drivers/Video/s3c2410fb. c. Why is there an FB later? This is the abbreviation of framebuffer. You can find a lot of explanations about it in Baidu. Framebuffer is the device interface for all Linux GUI programs to operate on hardware. It is located in/Dev and is generally fb0. You can find
The name of the function, such as s3c2410_disable_controller (), is pxafb_disable_controller () in my driver. It can be seen that the driver was changed from the PXA processor. Of course, the names of different manufacturers are also different. There is a sentence like this: _ raw_writel (FBI-> Reg. lcdcon1 &~ S3c2410_lcdcon1_envid, s3c2410_lcdcon1); if you delete this sentence, the LCD will not be switched off. This is the first level. I also see someone doing this. However, there is a problem. After you press the keyboard to restore, what is originally displayed on the screen will disappear if you do not re-paint, even if you re-paint, some parts of the screen are black and restored. Of course, if you can accept it, that's it. Then, we can naturally think of who called the function and eliminated the problem from the source. But this is not the case. I searched for this function name and found a set_ctrlr_state () function. I called pxafb_disable_controller () and searched for set_ctrlr_state (). I found that a pxafb_task () called set_ctrlr_state (), however, when pxafb_task () is reached, there is no way to go up, because this is a task provided to the kernel, and the function entry is passed as a pointer. I didn't know enough about the kernel. I spent a lot of time reading articles on many forums. Coincidentally, I found/Drivers/Char/vt. C.
This file. Vt. c I think it should be a combination of console. C and vt. c In the 2.4 kernel. It should be because it integrates all the functions of the console, and IOCTL is in the vt_ioctl.c file. This file is mainly used to manage the console, such as the Console mode (graphics, characters) and output to the console. Some functions, such as do_blk_screen () and blank_screen_t (), can be found here. These functions disable the LCD controller and modify any one of them. One solution on the Internet is to convert "blank_screen_t ()" into an empty function, but I have never tried it like this. I think it is near the root of the problem and should be able to solve it fundamentally. Let's take a look at the real cause of the screen closure problem, and see the console initialization function static int _ init con_init (void)
{
Const char * display_desc = NULL;
Struct vc_data * VC;
Unsigned int currcons = 0; acquire_console_sem (); If (conswitchp)
Display_desc = conswitchp-> con_startup ();
If (! Display_desc ){
Fg_console = 0;
Release_console_sem ();
Return 0;
} Init_timer (& lele_timer );
Lele_timer.function = blank_screen_t;
If (blankinterval ){
Blank_state = blank_normal_wait;
Mod_timer (& lele_timer, jiffies + blankinterval );
} // This is the initialization of the timer on the console. The timer event function is connected to the blank_screen_t ()/*
* Kmalloc is not running yet-we use the bootmem allocator.
*/
For (currcons = 0; currcons <min_nr_les les; currcons ++ ){
Vc_cons [currcons]. d = VC = alloc_bootmem (sizeof (struct vc_data ));
Visual_init (VC, currcons, 1 );
VC-> vc_screenbuf = (unsigned short *) alloc_bootmem (VC-> vc_screenbuf_size );
VC-> vc_kmalloced = 0;
Vc_init (VC, VC-> vc_rows, VC-> vc_cols,
Currcons |! VC-> vc_sw-> con_save_screen );
}
Currcons = fg_console = 0;
Master_display_fg = VC = vc_cons [currcons]. D;
Set_origin (VC );
Save_screen (VC );
Gotoxy (VC, VC-> vc_x, VC-> vc_y );
Csi_j (VC, 0 );
Update_screen (VC );
Printk ("Console: % S % DX % d ",
VC-> vc_can_do_color? "Color": "Mono ",
Display_desc, VC-> vc_cols, VC-> vc_rows );
Printable = 1;
Printk ("/N"); release_console_sem (); # ifdef config_vt_console
Register_console (& vt_console_driver );
# Endif
Return 0;
}
Here, we reference a global variable named blankinterval and a console_time. I don't know how the kernel timer works, but this code is already obvious. This timer has nothing to do with the power management macro pm_config, which is part of the console. Let's take a look at blank_screen_t (): static void blank_screen_t (unsigned long dummy)
{
Blank_timer_expired = 1;
Schedule_work (& console_work );
} You can find the macro starting with vt. C, static declare_work (console_work, lele_callback, null);, and find the lele_callback () function: static void console_callback (void * ignored)
{
Acquire_console_sem (); If (want_console> = 0 ){
If (want_console! = Fg_console &&
Vc_cons_allocated (want_console )){
Hide_cursor (vc_cons [fg_console]. D );
Change_console (vc_cons [want_console]. D );
/* We only changed when the console had already
Been allocated-a new console is not created
In an Interrupt Routine */
}
Want_console =-1;
}
If (do_poke_blked_console) {/* Do not unblank for a led change */
Do_poke_blanked_console = 0;
Poke_blanked_console ();
}
If (scrollback_delta ){
Struct vc_data * Vc = vc_cons [fg_console]. D;
Clear_selection ();
If (VC-> vc_mode = kd_text)
VC-> vc_sw-> con_scrolldelta (VC, scrollback_delta );
Scrollback_delta = 0;
}
If (blank_timer_expired ){
Do_blank_screen (0 );
Blank_timer_expired = 0;
} Release_console_sem ();
} Then look at do_blk_screen (). With the similar pointer tracking in struct vc_data, you can find the corresponding code in the driver. Writing it out is too troublesome, so I am lazy. In summary, there is actually a timer in the console. It is responsible for displaying and disabling the timer after a certain period of time, regardless of whether the power management function is enabled. So what is the relationship between this and framebuffer? From a very weak point of view, when the kernel was just started, there was such an output: Console: Color dummy device 80x30 after initiating the LCD controller (framebuffer, there is an output like this: Console: switching to color frame buffer device 80x30: At this time, the kernel switches the console (or TTY) to framebuffer, let's hurry up and criticize me. Back to the question, we can find from the code that the fundamental solution is to make the value of blankinterval = 0, so that the state of blank_state will not be a value other than the value of blank_off, and the screen will not be closed. However, the problem is still not completely solved here. If the user program wants to change the balancer interval to implement screen saver (of course not needed on my system), in addition, some programs change the balancer interval. After the program exits, the screen will be closed after a period of time. How can we solve this problem at the end of the user program? It took me a lot of time. I took a detour while tracing the code. I thought that modifying the Console mode would not allow the black screen to appear. But later I found that this may make the console unable to draw pictures, and I don't know if it is correct. Ignore detours and directly resolve them. Isn't there many console functions in vt. C? Let's see who modified balancer interval. So I searched for blankinterval and found that setterm_command () modified it. Then I searched for setterm_command, found the do_con_trol () function, searched do_con_trol, found the do_con_write () function, and searched for do_con_write, finally, the boss appeared: The con_write () function. Why is it the final boss? Take a look at this section: static struct tty_operations con_ops = {
. Open = con_open,
. Close = con_close,
. Write = con_write,
. Write_room = con_write_room,
. Put_char = con_put_char,
. Flush_chars = con_flush_chars,
. Chars_in_buffer = con_chars_in_buffer,
. IOCTL = vt_ioctl,
. Stop = con_stop,
. Start = con_start,
. Throttle = con_throttle,
. Unthrottle = con_unthrottle,
}; If you are familiar with fops, you can see that this is a table of file operation functions for tty devices. That is to say, in the user program, open/dev/tty through the open function, and then use the write function to modify the balancer interval. The principle is found, and it is very difficult in practice. If you call multiple functions, check the switch statement in do_con_trol (). Normal people will be dizzy. Fortunately, the great Baidu provides us with a lot of information: In the command line, you can use the setterm-blank 0 command to set the blkinterval. Haha, the savior is coming. Check the source code of setterm. Setterm belongs to the util-linux package. It is easy to search.
Find. The sequence m_sequence () function contains the following section:/*-blank [0-60]. */
If (opt_blank & vcterm)
Printf ("/033 [9; % d]", opt_bl_min); it's amazing to use a printf program to solve this problem, originally, I only wanted to use printf to solve the problem. I thought it would be more comfortable to see the principle. Besides, I cannot use printf on my system. But! The problem is not complete yet. In our system, the LCD virtual console and the console tty are not the same device. That is to say, it is impossible to simply use printf in the program! In this way, you can only modify the TTY blankinterval that you are using, but you are using a text device. There is no black screen problem. Therefore, you need to carefully compare the device numbers of/dev/console,/dev/tty,/dev/ttyn, in my system, in the user program, both/dev/console and/dev/tty are 5, indicating that they are a thing and/dev/ttyn is 4. This is the virtual console on FB. However, the/dev/ttyn is not the TTY currently in use. How can this problem be solved? I had to use the write function to solve the problem. Write the following code: # include <fcntl. h> # include <stdio. h> # include <sys/IOCTL. h> void some_function () {int F; F = open ("/dev/tty0", o_rdwr); write (F, "/033 [9; 0]", 8); close (f);} the problem is finally solved. To sum up, there are many solutions to the second problem: 1. modify the LCD driver and change the function of the LCD controller to null (not recommended. modify vt. in C, use the blank_screen_t () function to leave it empty (recommended when the system does not need to disable the display function. modify vt. in C, set it to 0 (the system may need to disable the display function, and it is recommended that the display function be disabled normally after the system is powered on. modify the user program and add the code (recommended) for setting the blankinterval. I will write it here today and continue to work.
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.