Search code examples
tcpmbed

Mbed Cortex-m hardfault when sending data via TCP


I have a TCPSocket* object which holds a connection to a client. This object is passed to another object to send data back to the client:

uint32_t count = 10;

char* message = new char[4];

message[0] = count & 0xff;

message[1] = (count >> 8) & 0xff;

message[2] = (count >> 16) & 0xff;

message[3] = (count >> 24) & 0xff;

client->send(&message, 4);

When this part of the program is called, the following appears on the serial line, and no data is received by the client:

    ++ MbedOS Fault Handler ++



                                                                                                          FaultType: HardFault



                                                                                                                              Context:

   R0   : 00000000

                  R1   : 10008000

                                 R2   : 00000004

                                                R3   : 2007C000

                                                               R4   : 10000914

                                                                              R5   : 00000000

                                                                                             R6   : 00000000

                                                                                                            R7   : 10004330

                                                                                                                           R8   : 10004320

       R9   : FFFFF435

                      R10  : 00000000

                                     R11  : 00000000

                                                    R12  : 00012AC1

                                                                   SP   : 10002AF0

                                                                                  LR   : 0000D1A1

                                                                                                 PC   : 00005938

                                                                                                                xPSR : 21000000

                                                                                                                               PSP  : 10002AD0

           MSP  : 10007FD8

                          CPUID: 412FC230

                                         HFSR : 40000000

                                                        MMFSR: 00000000

                                                                       BFSR : 00000082

                                                                                     UFSR : 00000000

                                                                                                     DFSR : 0000000A

                                                                                                                    AFSR : 00000000

                                                                                                                                   BFAR : 10008010

               Mode : Thread

                            Priv : Privileged

                                             Stack: PSP



                                                       -- MbedOS Fault Handler --







                                                                                 ++ MbedOS Error Info ++

                                                                                                        Error Status: 0x80FF013D Code: 317 Module: 255

                   Error Message: Fault exception

                                                 Location: 0xD337

                                                                 Error Value: 0x5938

                                                                                    Current Thread: main  Id: 0x10002B48 Entry: 0xD7D7 StackSize: 0x1000 StackMem: 0x10001B48 SP: 0x10007F88

                                                          For more info, visit: https://armmbed.github.io/mbedos-error/?error=0x80FF013D

     -- MbedOS Error Info --

Everything is in one thread so I cant see what could be causing this.

These are the relevant parts of the program:

main:

// Network interface
EthernetInterface net;

TCPSocket listener; //listens for incoming connection requests
TCPSocket* client;

CommandProcessor commandProcessor(client);

int main() {

    int remaining;
    int rcount;
    char *p;
    char *buffer = new char[16];
    nsapi_size_or_error_t result;

    int n = net.set_network("192.168.1.103","255.255.255.0","192.168.1.2");
    pc.printf("\n Success? %d\n", n);
    net.connect();

    listener.open(&net);
    listener.bind(3045);

    listener.listen(1);

    client = listener.accept(NULL);
    client->set_timeout(1000);

    led1 = 1;

    while(1) {
        int remaining = 16;
        int rcount = 0;
        p = buffer;

        while (remaining > 0 && 0 < (result = client->recv(p, remaining))) {
            p += result;
            rcount += result;
            remaining -= result;
        }

        if (remaining == 0) //full message received
        {
            commandProcessor.process(buffer);
        }
    }
}

CommandProcessor:

CommandProcessor::CommandProcessor(TCPSocket* client)
{
    this->client = client;
}

void CommandProcessor::process(char* message)
{

    switch(message[0]) { //Command is first byte of message

        case 0x3: { 

            uint32_t count = 10 ;

            char* message = new char[4];

            message[0] = count & 0xff;
            message[1] = (count >> 8) & 0xff;
            message[2] = (count >> 16) & 0xff;
            message[3] = (count >> 24) & 0xff;

            client->send(message, 4);
        }
    }
}

Solution

  • commandProcessor's client is NULL when you call commandProcessor.process(buffer).

    Why don’t you create an instance of CommandProcessor after you get a pointer to a socket from accept().

    CommandProcessor* commandProcessor;
    
    client = listener.accept(NULL);
    commandProcessor = new CommandProcessor(client);
    
    commandProcessor->process(buffer);
    

    Alternatively, you can set client with a function like this.

    void CommandProcessor::setClient(TCPSocket* client) {
        this->client = client;
    }
    

    usage:

    client = listener.accept(NULL);
    commandProcessor.setClient(client);