In most BSP of the 2440 Development Board wince 5.0, The smdk2440, drivers, and backlite directories generally have backlights. You can print "!!!!!!!!!!!! Backlight on !!!!!!!!!!!!, If no operation is performed, print it in about 1 minute !!!!!!!!!!!! Backlight off !!!!!!!!!!!!. After printing off, even if there is a trigger event (click on the touch screen), it will not print "!!!!!!!!!!!! Backlight on !!!!!!!!!!!!.
When you analyze the following three events in the driver:
G_evtsignal [0] = createevent (null, false, false, szevtbacklightchange );
G_evtsignal [1] = createevent (null, false, false, szevtuserinput );
G_evtsignal [bl_powerevt] = createevent (null, false, false, szevtpowerchanged );
Especially the second one. It seems that there is no problem. In fact, this driver is basically correct. The modified source code (incomplete and strict, for example, the thread statement is not created) is as follows:
// Globals
Const tchar szevtbacklightchange [] = text ("backlightchangeevent ");
Const tchar szevtpowerchanged [] = text ("powerchangedevent ");
Const tchar szevtuserinput [] = text ("powermanager/activitytimer/useractivity ");
Const tchar szregrootkey [] = text ("controlpanel // backlight ");
Const tchar szregbatterytimeout [] = text ("batterytimeout ");
Const tchar szregactimeout [] = text ("actimeout ");
Const tchar szregbatteryauto [] = text ("backlightontap ");
Const tchar szregacauto [] = text ("acbacklightontap ");
Handle g_evtsignal [num_events]; // The value of num_events is 3.
Volatile iopreg * v_piopregs = (iopreg *) iop_base;/* virtual address corresponding to the gpio register */
Blstruct g_blinfo; // global structure
Void bl_on (bool bon) // turn on/off the backlight
{
If (bon)
{
If (g_blinfo.m_dwstatus! = Bl_on)
{
G_blinfo.m_dwstatus = bl_on;
V_piopregs-> rgpbdat & = 0x6ff; // turn on the LED
Retailmsg (1, (text ("!!!!!!!!!!!! Backlight on !!!!!!!!!!!! /R/N ")));
}
}
Else
{
If (g_blinfo.m_dwstatus! = Bl_off)
{
G_blinfo.m_dwstatus = bl_off;
V_piopregs-> rgpbdat | = 0x100; // turn off the LED
Retailmsg (1, (text ("!!!!!!!!!!!! Backlight off !!!!!!!!!!!! /R/N ")));
}
}
}
Void bl_poweron (bool binit) // restore power to the backlight
{
Bl_on (true );
}
Bool backlightinitialize () // perform all one-time initialization of the backlight
{
Bool Bret = true;
Retailmsg (1, (text ("backlightinitialize/R/N ")));
Bl_poweron (true );
V_piopregs-> rgpbcon & = 0x3c03ff;
V_piopregs-> rgpbcon | = 0x15400;
V_piopregs-> rgpbup & = 0x61f; // enable Backlight
Return Bret;
}
Void bl_readregistry (blstruct * pblinfo) // utility function to read from registry for the parameters
{
Hkey;
Long lresult;
DWORD dwtype;
DWORD dwval;
DWORD dwlen;
Lresult = regopenkeyex (HKEY_CURRENT_USER, szregrootkey, 0, key_all_access, & hkey );
If (error_success = lresult)
{
Dwtype = REG_DWORD;
Dwlen = sizeof (DWORD );
Lresult = regqueryvalueex (hkey, szregbatterytimeout, null, & dwtype, (lpbyte) & dwval, & dwlen );
If (error_success = lresult)
{
Pblinfo-> m_dwbatterytimeout = dwval;
}
Lresult = regqueryvalueex (hkey, szregactimeout, null, & dwtype, (lpbyte) & dwval, & dwlen );
If (error_success = lresult)
{
Pblinfo-> m_dwactimeout = dwval;
}
Lresult = regqueryvalueex (hkey, szregbatteryauto, null, & dwtype, (lpbyte) & dwval, & dwlen );
If (error_success = lresult)
{
Pblinfo-> m_bbatteryauto = (bool) dwval;
}
Lresult = regqueryvalueex (hkey, szregacauto, null, & dwtype, (lpbyte) & dwval, & dwlen );
If (error_success = lresult)
{
Pblinfo-> m_bacauto = (bool) dwval;
}
Regclosekey (hkey );
}
Else
{
Retailmsg (1, (text ("Bak: HKEY_CURRENT_USER // % s key doesn't exist! /R/N "), szregrootkey ));
}
}
Bool bl_init () // initialize the backlight
{
// Set up all the events we need.
G_evtsignal [0] = createevent (null, false, false, szevtbacklightchange );
G_evtsignal [1] = createevent (null, false, false, szevtuserinput );
G_evtsignal [bl_powerevt] = createevent (null, false, false, szevtpowerchanged );
If (! G_evtsignal [0] |! G_evtsignal [1] |! G_evtsignal [2])
{
Bl_deinit ();
Return false;
}
Debugmsg (1, (text ("bl_init () and setgpio/n/R ")));
Return true;
}
Void bl_deinit () // uninitialize the backlight
{
Int I;
Retailmsg (1, (text ("Bak: bl_deinit! /R/N ")));
For (I = 0; I <num_events; I ++) // clean up
{
If (g_evtsignal [I])
{
Closehandle (g_evtsignal [I]);
}
}
}
/* The backlight handling is done by a thread, which monitors those three event and performs some actions based on the parameters specified */
DWORD bl_monitorthread (pvoid pparms) // backlight service thread
{
DWORD dwresult;
DWORD dwtimeout;
G_blinfo.m_bacauto = true;
G_blinfo.m_bbatteryauto = true;
G_blinfo.m_dwbatterytimeout = 20; // 20 seconds
G_blinfo.m_dwactimeout = 60; // 1 minutes
Bl_readregistry (& g_blinfo); // now read from the Registry to see what they say
If (! Bl_init () // initialize BL
{
Retailmsg (1, (text ("bl_init () failed! Exit from bl_monitorthread! /R/N ")));
Return 0;
}
While (1)
{
_ Try
{
// If we are using AC now, use m_dwactimeout as the timeout, otherwise use m_dwbatterytimeout
If (isacon ())
{
Dwtimeout = g_blinfo.m_dwactimeout * 1000;
}
Else
{
Dwtimeout = g_blinfo.m_dwbatterytimeout * 1000;
}
// However, if user wants BL on all the time, we have to let him
// Do that. Or if we come back here, and BL is off, we want
// Put this thread to sleep until other event happens.
If (dwtimeout = 0 | g_blinfo.m_dwstatus = bl_off)
{
Dwtimeout = infinite;
}
// Now let's wait for either there is an update on registry, or
// There is user action on the device, or there is activity on
// AC power supply.
Dwresult = waitformultipleobjects (num_events, & g_evtsignal [0], false, dwtimeout );
If (wait_object_0 = dwresult) // The backlight latency is changed.
{
// All we need to do is to read from registry and update the tick count
Bl_readregistry (& g_blinfo );
// Always turn on the backlight after a change to registry
Bl_on (true );
}
Else if (dwresult = wait_object_0 + 1)
{
// User activity, depending on the situation, we may/may not update the tick count
If (isacon ())
{
If (g_blinfo.m_bacauto)
{
Bl_on (true );
}
}
Else
{
If (g_blinfo.m_bbatteryauto)
{
Bl_on (true );
}
}
}
Else if (dwresult = wait_object_0 + 2)
{
// When AC is plugged or un-plugged, we don't really need to do anything
// We continue the loop. The correct timeout value will be assigned
// The Top Of The while loop.
Retailmsg (1, (text ("backlight thread: power changed! /R/N ")));
}
Else if (dwresult = wait_timeout)
{
// Time out, let's turn the device off
Retailmsg (1, (text ("timeout, turn off the backlight! /R/N ")));
Bl_on (false );
}
}
_ Handler T (exception_execute_handler)
{
Retailmsg (1, (text ("an exception is raised in bl_monitorthread.../R/N ")));
}
} // While
}
Add the corresponding IOCTL processing function:
Bool bkl_iocontrol (DWORD dwopencontext, DWORD dwiocontrolcode, lpbyte lpinbuf, DWORD ninbufsize, lpbyte lpoutbuf, DWORD noutbufsize, lpdword lpbytesreturned)
{
DWORD dwerr = error_invalid_parameter;
// Verify Context
If (! Dwopencontext)
{
Retailmsg (zone_error, (L "error: bkl_deinit:" l "incorrect context paramer/R/N "));
Return false;
}
Switch (dwiocontrolcode)
{
Case ioctl_power_capabilities:
Retailmsg (zone_backlight, (text ("BKL: ioctl_power_capabilities/R/N ")));
................;
Break;
Case ioctl_power_query: // determines whether changing power state is feasible
Retailmsg (zone_backlight, (text ("BKL: received ioctl_power_query/R/N ")));
...............;
Break;
Case ioctl_power_set: // requests a change from one device power state to another
Retailmsg (zone_backlight, (text ("BKL: received ioctl_power_set/R/N ")));
..............;
Break;
Case ioctl_power_get: // gets the current device power state
Retailmsg (zone_backlight, (text ("BKL: received ioctl_power_get/R/N ")));
..............;
Break;
Default:
Dwerr = backlightiocontrol (pbklinfo-> dwpddcontext, dwiocontrolcode, lpinbuf, ninbufsize, lpoutbuf, noutbufsize, lpbytesreturned );
Retailmsg (zone_backlight, (text ("backlightiocontrol IOCTL code % u/R/N"), dwiocontrolcode ));
Break;
}
}
// Process the supplemented IOCTL code
DWORD backlightiocontrol (DWORD dwopencontext, DWORD dwiocontrolcode, lpbyte lpinbuf, DWORD ninbufsize, lpbyte lpoutbuf, DWORD noutbufsize, lpdword lpbytesreturned)
{
DWORD ret = error_success;
Switch (dwiocontrolcode)
{
Case blk_ioctl_set_brightness:
..........................;
Break;
Case blk_ioctl_get_brightness:
..........................;
Break;
Case blk_ioctl_get_minfreq:
..........................;
Break;
Case blk_ioctl_set_minfreq:
..........................;
Break;
Default:
Ret =! Error_success;
Break;
}
Return ret;
}
Http://blog.csdn.net/cy757/archive/2008/08/07/2783730.aspx ()