Autostart application

When I use VS2010 to debug my application everything is working, but how can I setup the application to run automatic, when disconnected from USB client. I just want to power the device throught external powersource and USB client DP, with no USB cable connected.
When I deploy in release from VS2010 I hoped the application would start automatic, but it doesn’t.
When I create an hex file and deploy it, the program starts. Also pinging doesn’t work unless I debug in VS2010.

It cannot be that you have to write a mfdeploy after a reset or power failure to startup the program right connected through USB cable?

all applications always start when you reset the board. You are correct, the concept of an embedded device is to start when power is connected and keep running until power is disconnected. I think you either have something else wrong or your app is not right.

Show us a short example app that exhibits this behavior.

Agree with Brett - NETMF apps generally start as soon as they are powered on, the debugger should not need to be connected.

Are there any exceptions thrown at runtime which are shown in the Output window? Uncaught exceptions can prevent an app from starting cleanly. If you can post sample code, one of us might be able to repro and help diagnose.

Sorry for the delay, it was very busy at work…


public partial class Program
    {
        // This method is run when the mainboard is powered up or reset.   
        private void ProgramStarted()
        {
            /*******************************************************************************************
            Modules added in the Program.gadgeteer designer view are used by typing 
            their name followed by a period, e.g.  button.  or  camera.
            
            Many modules generate useful events. Type +=<tab><tab> to add a handler to an event, e.g.:
                button.ButtonPressed +=<tab><tab>
            
            If you want to do something periodically, use a GT.Timer and handle its Tick event, e.g.:
                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick +=<tab><tab>
                timer.Start();
            *******************************************************************************************/


            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            //sdCard.SDCardMounted += sdCard_SDCardMounted;
            //sdCard.SDCardUnmounted += SdCardSdCardUnmounted;

            InitRelais();

            new Thread(InitNetworkInterface).Start();

            new Thread(RelayLoop).Start();

            //InitNetworkInterface();
            // Test to see if main program exits if thread are not set as background tasks
            while (true)
            {
                Thread.Sleep(100);
            }
        }

        private static void InitNetworkInterface()
        {
            var interfaces = NetworkInterface.GetAllNetworkInterfaces();
            if (interfaces != null && interfaces.Length > 0)
            {
                NetworkInterface networkInterface = interfaces[0];
                networkInterface.EnableStaticIP("192.168.0.150", "255.255.255.0", "192.168.0.1");
                //networkInterface.EnableStaticDns(new[] { "192.168.0.1" });
            }

            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 30000, SendTimeout = 30000 };
            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1200);
            socket.Bind(ipEndPoint);
            socket.Listen(1);
            while (true)
            {
                /*try
                {
                    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    socket.Connect(new IPEndPoint(new IPAddress(new byte[] { 192, 168, 0, 220 }), 4567));
                    socket.Send(UTF8Encoding.UTF8.GetBytes("dit is een test!"));
                }
                catch (Exception e)
                {
                    Debug.Print(e.Message);
                }

                Thread.Sleep(5000);*/

                // Wait for a client to connect.
                Socket clientSocket = socket.Accept();

                var buffer = new Byte[1024];
                clientSocket.Receive(buffer);
                clientSocket.Close();

                var text = Encoding.UTF8.GetChars(buffer);
                Debug.Print(new string(text));
                // Process the client request. true means asynchronous.
                //new ProcessClientRequest(clientSocket, true);
            }
        }

        private void RelayLoop()
        {
            int counter = 0;
            while (true)
            {
                Thread.Sleep(200);
                switch (counter++)
                {
                    case 0:
                        relays.Relay1 = !relays.Relay1;
                        break;
                    case 1:
                        relays.Relay2 = !relays.Relay2;
                        break;
                    case 2:
                        relays.Relay3 = !relays.Relay3;
                        break;
                    case 3:
                        relays.Relay4 = !relays.Relay4;
                        break;
                    case 4:
                        relays1.Relay1 = !relays1.Relay1;
                        break;
                    case 5:
                        relays1.Relay2 = !relays1.Relay2;
                        break;
                    case 6:
                        relays1.Relay3 = !relays1.Relay3;
                        break;
                    case 7:
                        relays1.Relay4 = !relays1.Relay4;
                        break;
                }
                if (counter == 8)
                    counter = 0;
            }
        }

        private void InitRelais()
        {
            relays.Relay1 = false;
            relays.Relay2 = false;
            relays.Relay3 = false;
            relays.Relay4 = false;
            relays1.Relay1 = false;
            relays1.Relay2 = false;
            relays1.Relay3 = false;
            relays1.Relay4 = false;
        }

        private static void WriteLogMsg(string msg)
        {
            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
            rootDirectory += "\\logging.txt";
            using (var sw = new FileStream(rootDirectory, FileMode.OpenOrCreate))
            {
                byte[] buffer = Encoding.UTF8.GetBytes(DateTime.Now + ": " + msg + "\r\n");
                sw.Seek(0, SeekOrigin.End);
                sw.Write(buffer, 0, buffer.Length);
                sw.Flush();
                sw.Close();
            }
        }

        private void SdCardSdCardUnmounted(SDCard sender)
        {
            Debug.Print("SD card ejected");
        }

        private void sdCard_SDCardMounted(SDCard sender, StorageDevice SDCard)
        {
            Debug.Print("SD card inserted");
            //relays1.Relay1 = !relays1.Relay1;
            if (SDCard.Volume.IsFormatted)
            {
                Debug.Print("Available folders:");
                string[] strs = Directory.GetDirectories(SDCard.Volume.RootDirectory);
                for (int i = 0; i < strs.Length; i++)
                    Debug.Print(strs[i]);

                Debug.Print("Available files:");
                strs = Directory.GetFiles(SDCard.Volume.RootDirectory);
                for (int i = 0; i < strs.Length; i++)
                    Debug.Print(strs[i]);

                WriteLogMsg("test");
                WriteLogMsg("Onnea Sun");
            }
            else
            {
                Debug.Print("SD card is not formatted");
            }
        }
    }

you should not have a sleep loop at the end of ProgramStarted() method. When you are finished initializing just return.

You are also mixing Gadgeteer code with non-Gadgeteer code. You should initialize ethernet with the following:

             ethernet.UseStaticIP(...);

this assumes you used the VS Gadgeteer designer.

If you use while(true) loops you block the events dispatcher.

You should work with GT.Timer and add the code to be looped to the Tick handler.

More info: http://blogs.msdn.com/b/net_gadgeteer/archive/2011/12/19/why-not-while-true.aspx

The while loop was a test because without it doesn’t worked. So you cannot start threads from the programstarted event?

I’m using a Fezz Hydra with enc28 which has not have a vs designer component. So in other thread they suggest to use this library. Is it better to use something else?

The ProgramStarted method is where you should start threads.

Today I had time to try to get my apps run automaticly on powering up the Hydra.
I just used the simpelest code to test this:


public partial class Program
    {
        private int _counter;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            InitRelais();

            var timer = new GT.Timer(1000);
            timer.Tick += TimerTick;
            timer.Start();
        }

        void TimerTick(GT.Timer timer)
        {
            RelayLoop();
        }

        private void InitRelais()
        {
            relays.Relay1 = false;
            relays.Relay2 = false;
            relays.Relay3 = false;
            relays.Relay4 = false;
            relays1.Relay1 = false;
            relays1.Relay2 = false;
            relays1.Relay3 = false;
            relays1.Relay4 = false;
        }

        private void RelayLoop()
        {
            switch (_counter++)
            {
                case 0:
                    relays.Relay1 = !relays.Relay1;
                    break;
                case 1:
                    relays.Relay2 = !relays.Relay2;
                    break;
                case 2:
                    relays.Relay3 = !relays.Relay3;
                    break;
                case 3:
                    relays.Relay4 = !relays.Relay4;
                    break;
                case 4:
                    relays1.Relay1 = !relays1.Relay1;
                    break;
                case 5:
                    relays1.Relay2 = !relays1.Relay2;
                    break;
                case 6:
                    relays1.Relay3 = !relays1.Relay3;
                    break;
                case 7:
                    relays1.Relay4 = !relays1.Relay4;
                    break;
            }
            if (_counter == 8)
                _counter = 0;
        }
    }

I build it in release mode --> right click in VS solution --> click deploy --> deploy succeeded.
Remove USB cable from pc, click reset --> nothing happens

I also tried not hitting the reset button and just disconnect the powersupply and reconnect it --> nothing happens.

When I click debug in VS relais toggle (hardware)

I also put the Program as startup object in VS project settings.

Now I tried creating a .hex file with MFDeploy. When I deploy it to Hydra, MFDEPLOY says after reboot, application is being started.

How can the Hydra do this automatic on power up?

I reflashed my Hydra to be sure that I’m on the latest firmware.
setup an Ip address through MFDEPLOY
tried pinging the Hydra → host unreachable…

So it seems my Hydra doesn’t work without deploying first everytime to the device after reset or power disconnected?

I uploaded my project → http://www.itandu.be/SunCoach.Hardware.zip

Here’s a simple code example that flashes a multicolour LED on/off in blue. Do you have the smart multicolour LED module?

namespace GadgeteerApp1
{
    public partial class Program
    {
        bool Blue = true;
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

                GT.Timer timer = new GT.Timer(1000); // every second (1000ms)
                timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
                timer.Start();

            led.GreenBlueSwapped = true;
        }

        void timer_Tick(GT.Timer timer)
        {
            if (Blue)
            {
                led.RemoveBlue();
                Blue=false; 
            }
            else
            {
                led.AddBlue();
                Blue = true;
            }
        }
    }
}

I have just deployed that to my Hydra, the unplugged the Hydra and connected it to a USB cable powered from a 5v transformer. Blue light starts flashing as expected.

i don’t have the multicolor led, but I’ll try to connect my usb dp not with an external power supply but with a usb power supply. I bought the DP one so I wouldn’t have to use usb, because in the comment for ENC28 is stated to better use an external power supply with the usb client dp module.

I’ll try this out and post back with the results. Is there by any change some setting I need to change to get the autostart to work? Through mfdeploy? An address mapping/ register value?

No - this has always been the standard function of a Fez device. In the embedded world, nothing else makes sense - a device starts when it is plugged in and stops when disconnected from power. In between, it does what you tell it to…

What other modules do you have? Lets try a diagnostic with something you have… do you have an LED and an extender module for instance, or a LED7R module? Or even a display, although that’s a lot more advanced than what I would want to check first.

I only have relais, ENC28 and a SDCard, And a DP and a normal USB Client (Powersupply)

I found the issue --> I connected a relay to socket 14 of Hydra and then the board didn’t start up correctly!
I removed all modules and then the ping started to work when only connection PSU.
Then I readded the modules one by one, and found that adding relay to socket 14 stop the hydra from working… Specs say that I can use that socket for a Relay right?

Strange. Maybe one of the pins is responsible for boot mode that is causing it to not boot. Not sure.

If this is a Seeed Studio relay Please check the Solder on the Relay Socket…they seem to use different sockets than those used by GHI… their sockets have shorter legs and they don’t stick out of the socket to be soldered, so they attach very poorly, and you can’t even fix them because they are completely hidden under neat the socket.

Anyway you can always use the MotherBoard LED to test your application like this:
put this inside your Program Start. and watch the LED on the motherboard. (Hydra and Spider both have it). it should start blinking.


        for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(500);
                PulseDebugLED(); 
            }

i can confirm that if i plug my Seeed relay module to any Y socket, Hydra doesn’t boot and i can’t ping it from MFDeploy. as soon as i unplug the relay board, and plug in an LED for example, it works as it should.

So yes something is wrong…

Thanks.

Could someone from GHI please confirm that plugging in the Seeed Relay to ny Y socket on the Hydra causes it to NOT Start the Application and to Not respond to Pings from MFDeploy.?

thanks.