timeout for power manager reset

We reset the power on our Colibri T30 as a hack to deal with certain communications bugs. Currently we use

uint IOCTL_HAL_REBOOT = CTL_CODE(FILE_DEVICE_HAL, 15, METHOD_BUFFERED, FILE_ANY_ACCESS);

            unsafe
            {
                uint zeroInt = 0;
                var ptrToNull = new IntPtr(&zeroInt);
                KernelIoControl(IOCTL_HAL_REBOOT, ptrToNull, 4, IntPtr.Zero, 0, ref bytesReturned);
            }

to restart the system. This is causing us all kinds of problems now because we find our systems rebooting in the field and doing things like losing the registry entries for the CF and also possibly corrupting our flash storage.

We want to move a more “gentle” approach to rebooting the systems to try and reduce the hardware failures. We have included the full PowerManager in our OS Image and are trying to use that.

  1. Is there a way to try and inform applications when the system before NativeMethods.SetSystemPowerState(IntPtr.Zero, PowerStateFlags.Reset, NativeMethods.POWER_FORCE); restarts the system? Will RequestPowerNotifications let us know about an impending Reset? I can’t seem to capture the notification.
  2. is there a way to try and give the applications time before the reset is started? For example can we use SystemIdleTimerReset() to and modify the Timeout for systemidle to do that? If we do that, will there be side effects?

Thanks,
Brad

Edit: Really at this point I can’t seem to get any of the power notifications, suspend or reset. I am not sure at all that the Notifications are being send.

We are using
Colibri T30 IT
BSP. 2.3
Custom Carrier Board

Hi @bertin ,

Did you try to register to the POWER_BROADCAST?

it works through MsgQueues

Not sure if you can really delay or prevent the power state transition with it though.

Yes I did that. I copied the code from Bruce Eitman’s blog from his “Windows CE: Monitor Power State Changes” I changed some of the logging and I used POWER_NOTIFY_ALL to try and get all messages. I don’t receive any messages

POWER_BROADCAST pwrStatus;
	MSGQUEUEOPTIONS PwrNotificationQ;
	HANDLE hQ;
	DWORD nBytesRead=0;
	DWORD dwFlags=0;

	PwrNotificationQ.dwSize           = 5*sizeof(POWER_BROADCAST); 
	PwrNotificationQ.dwFlags          = MSGQUEUE_NOPRECOMMIT ; 
	PwrNotificationQ.dwMaxMessages    = 5 ; 
	PwrNotificationQ.cbMaxMessage     = sizeof(POWER_BROADCAST) ; 
	PwrNotificationQ.bReadAccess      = TRUE; 
	hQ=CreateMsgQueue(NULL,&PwrNotificationQ); 
	if(hQ==NULL) 
	{ 
		RETAILMSG( 1, (TEXT("Could not create message queue\n"))); 
		return FALSE; 
	} 
	if(RequestPowerNotifications(hQ,POWER_NOTIFY_ALL)==NULL) 
	{ 
		RETAILMSG(1,(TEXT("RequestPowerNotifications failed\n"))); 
		CloseHandle( hQ ); 
		return FALSE; 
	} 
	memset( &pwrStatus, 0, sizeof( pwrStatus )); 
	//RETAILMSG(1, (TEXT("starting native power monitor\n")));
	Utils::PrintSmallRetailMsg(L"starting ResumeThread\n");
	printf("starting resumethread\n");
	while(1) 
	{ 
		if ( !ReadMsgQueue(hQ,(LPVOID)&pwrStatus,sizeof(pwrStatus), 
			&nBytesRead,INFINITE,&dwFlags) )  
case POWER_STATE_SUSPEND:  
					WriteResetTrace(strPathToTrace,L"SUSPEND");
					RETAILMSG(1, (TEXT("POWER_STATE_SUSPEND\n")));  
						break;  
				case POWER_STATE_RESET:
					WriteResetTrace(strPathToTrace,L"RESET");
					Utils::PrintSmallRetailMsg((TEXT("POWER_STATE_RESET\n")));  
						break;  

I use the SoftReset function from OpenNETCF to trigger the reset. My observer process doesn’t report any notifications from the PM.

public static void SoftReset()
    {
      int ret = NativeMethods.SetSystemPowerState(IntPtr.Zero, PowerStateFlags.Reset, NativeMethods.POWER_FORCE);
      if (ret != NativeMethods.ERROR_SUCCESS)
      {
        int returned = 0;

        if (!NativeMethods.KernelIoControl(NativeMethods.IOCTL_HAL_REBOOT, IntPtr.Zero, 0, IntPtr.Zero, 0, ref returned))
        {
          throw new Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
        }
      }
    }

Hi @bertin,

I checked the implementation of SetSystemPowerState()

There is no way of avoiding a system power state transition by means of processing POWER_BROADCAST notifications.
The power notification systems is just for informing that a state transition happened.
In theory it will also inform you about a Reset transition, but there will be no time to process that notification as the system will reboot right away.

Also note that SetSystemPowerNotification internally calls KernelIoControl with IOCTL_HAL_REBOOT.

If you need to notify another application about an planned reboot, you could send a custom message to that application and wait some times before actually calling the SoftReset() code

Ok so there is no way to process the reset transition. That is what I firstly wanted to know,

So according to the below the documentation set power state to reset

Flushes files, shuts down devices, and issues the IOCTL_HAL_REBOOT command to the kernel.

Is that correct to say that a) Toradex doesnt do that and just does the IOCTL_HAL_REBOOT or b) toradex bsp does do that, but does not give applications a chance to be notified of the impending shutdown ?

Lets say we would like would wait a minute or two before shutdown if possible (even though we know that a shutdown is coming up) and do a softreset. Would putting the device into suspend and then waiting for the hardware watchdog be a way to do that and not have to create as much custom code (like a custom event or signal file) ?

Is there way built into WinCE at all to do a "shutdown -h +5 “device_shutting_down_in_5_mins” like what you have in linux? Or only custom logic?

Hi @bertin ,

The Toradex BSP uses the standard Microsoft code for the SetSystemPowerState(reset), so it does all the steps mentioned in the MS documentation.
But there is no way an application can delay or prevent the operation even if the system send the notification, it’s basically useless in case of a reset.

You could do the trick with suspend and let the watchdog do the reset, but i don’t see how this would help to solve the issue of the delay… the suspend notitication will only be reveived by a app registered to POWER_NOTIFICATION after the system resumed (basicall same issue as reset).

A delayed Shutdown command line tool does not exist, but can easily be written using the SetSystemPowerState() API.