Moving to SDK4.3

Today I started a trial move from 4.2 to the latest 4.3SDK (on EMX), and I’ve a few questions, perhaps asked/answered before but I haven’t been able to find them.

  1. How do we configure to start headless? My 4.2 code was:

            if(GHI.Premium.Hardware.Configuration.LCD.Set(Configuration.LCD.HeadlessConfig))
                PowerState.RebootDevice(false, 1000);

  1. In 4.2 I turned the Ethernet Oscillator off to save power, is this still possible?

   Power.EthernetOscillatorEnable(false);

  1. In controlling the USB Client, I can’t do:

  USBClientController.Stop();
  USBClientController.Start();

and it appears this has mostly been replaced by setting the controller Active Device:


   Controller.ActiveDevice = ms;

How can I Stop() the controller without starting a new active device? Pass in a null?

  1. In 4.2 doing a Write() to a USB Stream returned the number of bytes actually written, we have quite a bit of code to handle the case where this doesn’t equal the buffer size sent to tha call.
    In 4.3 the Write() function is a void. How can we tell if the call succeeded fully or not?

TIA,
David

I had also the same problem. I have successfully build the solution but not tested yet (troubles with virtual box to launch the usb driver on seven)

For the headless config, I wrote

Display.Disable() available in Namespace GHI.Processor

I do not disable the oscillator (in 4.1 this was buggy and now I am using the ethernet)

And yes you need to pass null to the ActiveDevice method see: https://www.ghielectronics.com/downloads/man/Library_Documentation_v4.3/html/6bdf7dff-82b1-4228-6c4a-de3ae7604d08.htm

@ C-Born -

1: GHI.Processor.Display.Disable(); If it returns true, a reboot is needed.

2: That function no longer exists.

3: You are correct, passing null disables it.

4: Write loops internally until all of the bytes have been written or the amount of time specified by WriteTimeout has passed. Write is void because the base System.IO.Stream class requires it to be.

Thanks guys, that clears things up a bit.

So if the Write times out, we take an exception? Is this documented anywhere?

In the base class documentation for System.IO.Stream it says that on a successful Write the Position in the Stream is advanced by the number of bytes written, if an exception occurs the position within the Stream is unchanged.

However the GHI documentation says Position is Not Supported.

We need to know that the Write succeeded, and how many bytes were sent, or if it failed. The 4.2 method returning a count did this, the 4.3 method should support this with an exception and updated Position property, but it seems the current implementation gives us neither?

Not working for me.
Controller.ActiveDevice contains {GHI.Usb.Client.RawDevice}

When I set it to null as follows:


Controller.ActiveDevice = null;

it generates an exception:


    #### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (11) ####
    #### Message: 
    #### GHI.Usb.Client.Controller::NativeStop [IP: 0000] ####
    #### GHI.Usb.Client.Controller::set_ActiveDevice [IP: 0008] ####
    #### AlcoaAnodeMeter.Hardware.UsbTransport::Suspend [IP: 0021] ####
    #### AlcoaAnodeMeter.Hardware.BoardSetup::BoardSetupWorker [IP: 08f1] ####
A first chance exception of type 'System.InvalidOperationException' occurred in GHI.Usb.dll

@ C-Born - Currently Write will throw an InvalidOperationException when it times out, but a coming SDK will add a more descriptive OperationTimedOutException. I will look into supporting position that is updated in writes and reads in a future SDK as well.

InvalidOperationException looks to be thrown from NativeStop only when USB client has not been started. Do you have a minimal example you can post that reliably shows the error?

@ John - the InvalidOperationException is thrown when I set the Controller.ActiveDevice property to null to disable it, as per your response to my question 3.

In the 4.2 code when switching the USB between raw stream and MassStorage modes, my code would use

USBClientController.Stop();

when I replaced those calls with

Controller.ActiveDevice = null;

the exception is thrown.

If I just set the Controller.ActiveDevice to the new device, things seem to work ok. However there are some areas of code where the timing isn’t clear due to thread interaction, and the previous code stops the device on one thread and the new device is then started on another, so the first thread has to disable the USB rather than starting a new device.

If setting the ActiveDevice to null is an invalid operation, is there another way to disable it?

@ C-Born - Setting ActiveDevice to null should work. If it doesn’t for you, can you post a complete and small example so we can try to reproduce the issue?

@ John - The original application switches between Raw and MassStorage, I started building a small demo of the problem, and at the stage below I started getting the invalid operation exceptions. This isn’t the exact problem, but it could have the same root cause.
Then again it could be my code is incorrect, there is not a lot of documentation available! I would have expected to find a DetachLogicalUnit() somewhere.

For me this takes the exception the second time through the loop, debugging over serial.

David


using System;
using System.Threading;
using Microsoft.SPOT;
using GHI.Usb.Client;
using GHI.Usb;
using GHI.IO.Storage;


public class Program
{
    public static SDCard sd;

    public static void Main()
    {
        // Assume SD card is connected
        try
        {
            sd = new SDCard();
        }
        catch
        {
            throw new Exception("SD card not detected");
        }

        int i;

        for (i = 1; i < 5; ++i)
        {
            Debug.Print("Attempt: " + i);
            if (!DiskDriveMode(true))
                break;
            Thread.Sleep(10000);
            if (!DiskDriveMode(false))
                break;
            Thread.Sleep(10000);
        }
    }

    static MassStorage ms;

    static bool DiskDriveMode(bool on)
    {
        if (on)
        {
            Debug.Print("Starting Mass Storage");
            try
            {
                ms = new MassStorage();
                Controller.ActiveDevice = ms;
                ms.AttachLogicalUnit(sd, 0, "", "");
                ms.EnableLogicalUnit(0);
            }
            catch (Exception ex)
            {
                Debug.Print("Start MS:: Exception: " + ex.Message);
                return false;
            }
        }
        else
        {
            Debug.Print("Stopping Mass Storage");
            try
            {
                ms.DisableLogicalUnit(0);
                Controller.ActiveDevice = null;
            }
            catch (Exception ex)
            {
                Debug.Print("Stop MS:: Exception: " + ex.Message);
                return false;
            }
        }
        return true;
    }
}

@ C-Born - We are able to reproduce that exception. We will let you know when we have a fix for it.

@ John - Hopefully it is another manifestation of the same problem and your fix will work for our application too. Let me know if you want me to test anything on the full version.

@ C-Born - The exception in your most recent program should be fixed in the next SDK.