Cerberus Freeze with ENC28

I did a lot of research on the forum and I don’t seem to be the only one Cerb. freezing problems. I did many tests and it is very difficult to put the finger on the problem since the system freezes completely.

I believe that it is the “socket.poll” method that causes the freeze. I would like to be able to use the product in commercial projects, but as long as this bug remains it is impossible. If someone wants to help me I can provide my programs.

I really like Cerberus and I wish to solve this issue.

Don’t use socket.poll for the moment. Of course you are right. If the method is there it must work…

But I’m not aware of any reason why this method should be necessary… Look at the socket.listen etc…

Thanks Alex for your reply. By reading what is written on MSDN: “Listen causes a connection-oriented Socket to listen for incoming connection attempts.” Is it a good practice to use this method for UDP communication?

Why not. If you have to respond to another client, then put receiving on its own thread and use the ReceiveFrom method…

And why we can not use the socket.poll at the moment. What is the problem with this function? Every UDP server sample I found on Internet use that function to listen incoming packet.

Well, I have not said that you cannot use it, but I come from the .NET world (Full Framework, NetCF and NetMF) and never needed the poll method. I did several networking projects - both TCP and UDB - servers and clients -synchron and asychronous…

I think the framework does already a higher abstraction, so that it is not necessary to use “poll”. This is just my understanding…

I tried without the socket.poll function but the mainboard still freezes. I find it very difficult to know why freezing occurs, but I believe there is a link with the amount of simultaneous client request that the processor receives.

My desktop program use a parallel for loop to send udp paquet to address from 2 to 254. Without this parallel loop the cerberus does not crash. But with it, it fails after few seconds.

Do I have a memory overflow? How could I get the system failure? Try Catch returns nothing!

Ethernet needs a reliable power source. Maybe power is the cause of what you are seeing.

Yes I read this and this is why I bought DP Power module connected with a 120V power supply. Despite that, the problem occurs.

How much power is needed? Should it be something else? Why the mainboard freeze and does not respond to anything else, i.e. button module and so on. Does SPI can crash the microprocessor with bad command?

I have two different network and I am having the same problem on each of them.

Annoying :frowning:

Latest sdk? Can you give us a somewhat simple example that we can run it here and see the crash?

Could someone try the following code snippet. The first is the Cerbuino Net App and the second is a console App. Adjust the IP address for you configuration.

I use a 6 cores CPU so the parallel loop execute pretty fast. After a moment, less than a minute for me, the Cerbuino stop responding. I have to reset the board. I don’t know how to trap this failure. I really want to discover a way to catch and handle this failure.

I use netmf 4.3 and lastest GHI Sdk.

Cerbuino Net

Imports GT = Gadgeteer
Imports GTM = Gadgeteer.Modules
Imports System.Net
Imports System.Net.Sockets

Namespace GadgeteerApp1
    Partial Public Class Program

        Private ServerSocket As Socket
        Private ListenerThread As Thread

        ' This is run when the mainboard is powered up or reset. 
        Public Sub ProgramStarted()
            Debug.Print("Program Started")

            Try
                '########################## Network Configuration
                Mainboard.Ethernet.Open()
                Mainboard.Ethernet.EnableDhcp()
                Mainboard.Ethernet.EnableDynamicDns()
                Debug.Print("Waiting for DHCP")
                While Mainboard.Ethernet.IPAddress = "0.0.0.0"
                    Thread.Sleep(500)
                End While
                Debug.Print(Mainboard.Ethernet.IPAddress)
            Catch ex As Exception

            End Try

            ListenerThread = New Thread(New ThreadStart(AddressOf Listen))
            ListenerThread.Priority = ThreadPriority.Normal
            ListenerThread.Start()

        End Sub

        Public Sub Listen()
            Try
                ServerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
                Dim EndPoint As IPEndPoint = New IPEndPoint(System.Net.IPAddress.Parse(Mainboard.Ethernet.IPAddress), 50000)
                Dim sender As New IPEndPoint(IPAddress.Any, 0)
                Dim senderEndPoint As EndPoint = CType(sender, EndPoint)

                ServerSocket.Bind(EndPoint)

                While True
                    Try
                        If ServerSocket.Poll(-1, SelectMode.SelectRead) Then
                            Dim buffer As Byte() = New Byte(ServerSocket.Available - 1) {}
                            Dim length As Integer = ServerSocket.ReceiveFrom(buffer, senderEndPoint)
                            If DirectCast(senderEndPoint, IPEndPoint).Address.ToString <> Mainboard.Ethernet.IPAddress Then
                                Debug.Print("Data Received from : " + DirectCast(senderEndPoint, IPEndPoint).Address.ToString)
                            End If
                        End If

                    Catch ex As Exception
                        Debug.Print(ex.Message)
                    End Try

                End While


            Catch ex As Exception
                Debug.Print(ex.Message)
            End Try

        End Sub

    End Class
End Namespace

Console App

Imports System.Net.Sockets
Imports System.Net
Imports System.Text
Imports System.Threading

Module Module1

    Private ServerSocket As Socket

    Sub Main()

        ServerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
        Dim localEndPoint As IPEndPoint = New IPEndPoint(System.Net.IPAddress.Parse("192.168.2.24"), 50000)

        Dim remoteIP As IPEndPoint

        ServerSocket.Bind(localEndPoint)

        Dim Messagebuffer As Byte() = Encoding.UTF8.GetBytes("{1.0:R:25693:1:2}")

        While True

            Parallel.For(2, 254, Sub(i)
                                     remoteIP = New IPEndPoint(IPAddress.Parse("192.168.2" + "." + i.ToString), 50000)
                                     ServerSocket.SendTo(Messagebuffer, remoteIP)
                                     Thread.Sleep(5)
                                 End Sub)

        End While

    End Sub

End Module

I tried my code with an hydra board with the latest firmware and running netmf 4.3. After many hours running, the board do not freeze. For me it sounds like a cerberus related problem.

Nobody else with this issue?

@ jango_jas - The Cerberus boards have very limited memory on them. They can only handle a handful of connections at a time. The current limits are around 6 UDP and 8 TCP. Even though UDP is connection-less, lwip might maintain some internal state.

If you execute less of the parallel loops, say 10-20, does it perform better? Something to keep in mind is that Microsoft is still doing a lot of work internally on lwip to improve reliability and performance. 252 connections virtually at once may be too much for it to handle on such a limited device.

Could you also try to capture a Wireshark trace and send it to us? There may be some hints in there.

@ John - I have a WireShark capture. How could I send it to you?

@ jango_jas - I’ve direct messaged you.

@ jango_jas - You should see some improvements in your program in the next SDK.

@ John - John, may I ask you more details about the limitation in connections on Cerberus?

I’ll explain: I made a project on Cerberus with a WebEvent “data.json” that respond with a JSON sintax. A service asks the Cerberus’s data each 2 minutes making a web request at “http://CERBERUS IP ADDRESS/data.json”.
Well, Cerberus replies happily but after 4-5 days it stops to reply at the web request.

I tested with the debugger and, after the well known 4-5 days, it throws an exception… like if the (limited) memory is full!

Now, I’ve “bypassed” this issue doing a Reboot() each 24 hous … it’s a bad solution, I know, but I needed it to work absolutely … also, I didn’t know where to optimize the code I wrote because I simply prepare a string (with data to response) and I pass it to the responder object in “WebEventReceived” event!

@ BigFoot - Are there specific limitation you would like details on? Due to the limited amount of memory on the cerb family, the networking stack buffers are very limited.

@ John - Yes!

Just because I think that issues I’m encountering working with the WebEvent class are all around these limitations.

@ BigFoot - Your issue sounds more like a memory leak if you are getting the OutOfMemory exception.