【问题标题】:Windows Mobile 6.5 GPS Device - WaitForMultipleObjects returns 258 (timeout)Windows Mobile 6.5 GPS 设备 - WaitForMultipleObjects 返回 258(超时)
【发布时间】:2012-04-23 00:51:18
【问题描述】:

我在 2008-2009 年为 Windows mobile 6.1 创建了一个在后台实时跟踪位置的 GPS 程序。多年来,它在这些设备上运行良好。出于某种原因,相同的代码从未在 Windows Mobile 6.5 上完美运行。

经过多个小时的操作(主要是在没有人使用设备的情况下),我从函数“WaitForMultipleObjects”收到“超时”(代码 258):

this.GPSEvent_WaitValue = WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

再一次,这可以工作几个小时,突然之间,如果没有:就不可能获得另一个职位: 更新: - 重启设备(GoogleMap 确认没有 GPS 设备存在!)

这与 Windows Mobile 进入睡眠状态和减慢我的线程速度有关。

以下是核心代码(改编自 Microsoft SDK 示例):

/// <summary>
/// When "WindowsMobile" wake up the program to check for a new position
/// </summary>
private void OnNextGPSEvent_Callback()
{
  int SecondsToNextWakeUp = ETL.Mobile.Device.ScheduledCallback.MINIMUM_SECONDTONEXTWAKEUP;

  switch (this.SleepingState)
  {
    case SleepingStateType.SleepingForNextPosition:
      // Get position
      this.GPSEvent_WaitValue = (WaitForEventThreadResultType)WaitForMultipleObjects(2, this.GPSEvent_Handles, 0, 45000);

      switch (this.GPSEvent_WaitValue)
      {
        case WaitForEventThreadResultType.Event_LocationChanged:
          // Got a new position
          this.FireLocationChanged(this.GetCurrentPosition());

          // Manage device shutdown (save battery)
          if (this.PositionFrequency > MIN_SECONDS_FREQUENCY_FORDEVICE_SHUTDOWN)
          {
            // Close device
            this.CloseDevice();
            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;

        case WaitForEventThreadResultType.Event_StateChanged:
          break;

        case WaitForEventThreadResultType.Timeout:
        case WaitForEventThreadResultType.Failed:
        case WaitForEventThreadResultType.Stop:
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<
          // >>>>>>>>>>>>>> This is where the error happens <<<<<<<<<<<<<<<<<<<<<<<<<<<

          // Too many errors
          this.ConsecutiveErrorReadingDevice++;
          if (this.ConsecutiveErrorReadingDevice > MAX_ERRORREADINGDEVICE)
          {
            this.CloseDevice();

            SecondsToNextWakeUp = (this.PositionFrequency - GPSDEVICE_LOAD_SECONDS_LOAD_TIME);
            this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
          }
          else
          {
            // Default Wait Time
            this.SleepingState = SleepingStateType.SleepingForNextPosition;
          }

          break;
      }
      #endregion
      break;

    case SleepingStateType.SleepingBeforeDeviceWakeUp:
      this.OpenDevice();

      SecondsToNextWakeUp = GPSDEVICE_LOAD_SECONDS_LOAD_TIME;
      this.SleepingState = SleepingStateType.SleepingForNextPosition;
      break;
  }

  if (this.IsListeningGPSEvent)
  {
    // Ajustement du prochain rappel
    this.NextGPSEvent_Callback.SecondToNextWakeUp = SecondsToNextWakeUp;
    this.NextGPSEvent_Callback.RequestWakeUpCallback();
  }
}
/// <summary>
///Create Thread
/// </summary>
private void StartListeningThreadForGPSEvent()
{
  // We only want to create the thread if we don't have one created already and we have opened the gps device
  if (this._GPSEventThread == null)
  {
    // Create and start thread to listen for GPS events
    this._GPSEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(this.ListeningThreadForGPSEvent));
    this._GPSEventThread.Start();
  }
}
private void ListeningThreadForGPSEvent()
{
  this.GPSEvent_WaitValue = WaitForEventThreadResultType.Stop;
  this.IsListeningGPSEvent = true;

  // Allocate handles worth of memory to pass to WaitForMultipleObjects
  this.GPSEvent_Handles = Helpers.LocalAlloc(12);
  Marshal.WriteInt32(this.GPSEvent_Handles, 0, this._StopHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 4, this._NewLocationHandle.ToInt32());
  Marshal.WriteInt32(this.GPSEvent_Handles, 8, this._GPSDeviceStateChanged.ToInt32());

  this.Start_NextGPSEvent_Timer(this.PositionFrequency);
  this.SleepingState = SleepingStateType.SleepingBeforeDeviceWakeUp;
  this.OnNextGPSEvent_Callback();
}

【问题讨论】:

  • 我今天早上已经重现了这个问题(这并不容易)。我虽然谷歌地图能够重置 GPSID,但事实并非如此。我试过杀死我的程序,但没有任何效果。似乎只有一个选择:重新启动!我怎样才能像那样使整个设备的 GPS 崩溃??
  • 我发现社区做了一些应用程序来重置 GPS 设备。那没有做任何事情。我将检查自己以编程方式重置 GPSID 服务。
  • 刚刚写了一个小程序重置GPSID服务。它也没有工作。代码的位置不够,但这里有一点: IntPtr hGPS = CreateFile("GPD0:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (hGPS.ToInt32() != INVALID_HANDLE_VALUE) { int Out = 0; UInt32 DeviceIOValue = DeviceIoControl(hGPS, ioctlCode, null, 0, null, 0, ref Out, IntPtr.Zero);关闭手柄(hGPS)}

标签: windows-mobile gps compact-framework


【解决方案1】:

Windows Mobile 5/6 SDK 中包含的 C# GPS 示例是否有同样的问题?如果是这样,那么这可能是驱动程序问题,您需要与您的硬件制造商或 OEM 联系。

您可以通过轮询 GPS 驱动程序而不是依赖中间驱动程序接口的位置更改回调来缓解此问题。

没有重置 GPS 硬件的标准方法。 GPS 在有程序使用时“开启”,而在没有程序使用时“关闭”(或处于极低功耗模式)。如果您的 GPS 在 WWAN 芯片上,您可以通过关闭和打开 WWAN 调制解调器来重置它。或者,一些 GPS 芯片接受 ASCII 或二进制串行命令来重置 GPS 本身,但这些是特定于芯片组的。您需要向您的 GPS 芯片组制造商查询这些代码。

您的 GPSID 重置代码(我假设来自 here)与强制所有 GPSID 客户端断开连接将 GPS 置于低功耗状态相同,但实际上可能不会重置硬件。

【讨论】:

  • 您好,感谢您的回复。您在这篇文章中看到的代码是基于 SDK 的。它已被增强,仅在设备进入睡眠状态时保持活力。所以我猜你是对的,这是驱动程序问题。由于相同的代码适用于任何 InterMec (winMo 6.1) 设备,而不适用于摩托罗拉 (winMo 6.5.3),因此它要么是这个版本,要么是 Windows Mobile 版本。由于 WinMo 没有更多的未来和这个无法解决的问题,我取消了这个项目。
猜你喜欢
  • 2012-07-29
  • 2010-12-11
  • 2012-02-03
  • 1970-01-01
  • 2014-02-17
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2013-09-01
相关资源
最近更新 更多