This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Data lost in NDK because of a too small receive-buffer.

Other Parts Discussed in Thread: OMAP-L138, SYSBIOS

Hello,

We are using a LogicPD evoBoard with a OMAP-L138 (C6748-DSP). For the OMAP-software we use SysBios 6.30.3.46 and NDK 2.20.3.24. The OMAP-evoBoard is connected to another DSP-evoBoard over ethernet. The OMAP connects as TCP-client to the other DSP and receives during runtime a bigger amount of data.

With the code:

        fdOpenSession((HANDLE)TaskSelf());

        // configure Address and port:
        struct sockaddr_in sin;
        sin.sin_family      = AF_INET;
        sin.sin_addr.s_addr = 0x021FA8C0;
        sin.sin_port        = htons(12002);

        // create socket:
        g_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        // connect to other DSP:
        connect(g_socket, (PSA)&sin, sizeof(sin))

we open a connection to the other DSP and with:

        while(receivedDataSize < 1)
        {
            receivedDataSize = recv(g_socket, buffer, sizeInByte, MSG_DONTWAIT);
        }

we poll if their is some new data received.

The problem is that we work with polling to get the received data from the stack. Is their a way to work with callback functions so that the stack calls a function in our software if their is new received data in the stack?

 

 

Another item is that we have sometimes the problem that we do not receive all data in the OMAP, that was send by the other DSP. We solved this problem by increasing the NDK-receive-buffer with:

int test = 0x4000;
int testSize = sizeof(test);
int ret = setsockopt(g_socketBlackFin, SOL_SOCKET, SO_RCVBUF, &test, testSize);

But we are not sure if 0x4000 Bytes for the receive-buffer is big enough for our use.

Because of that we want to implement an error-handling for the case of lost data because of a too small receive-buffer. Is their a way to get the information from the stack if data is thrown because of an overloaded receive-buffer?

 

Thanks for any help,

Andreas

 

 

  • Andreas,

    You can specify that the recv() function block until data is received using the following flag:

    MSG_WAITALL Requests that the operation block until the full request is
    satisfied. However, the call may still return less data than
    requested if an error or disconnect occurs, or the next data to be
    received is of a different type than that returned.

    (see spru524_pg.pdf for details on recv())

    Then, if there is no data incoming, this task will pend and a task switch should occur, allowing other tasks in your system to run.  When data comes in, it will unblock and become ready to run, and will then receive the data.  (Also, sockets should be created in blocking mode by default.)

    Andreas Martens said:

    Because of that we want to implement an error-handling for the case of lost data because of a too small receive-buffer. Is their a way to get the information from the stack if data is thrown because of an overloaded receive-buffer?

    I would have to dig into this to see.  I don't think so, but let me check to see if this is supported.

    Steve

     

  • Andreas,

    Andreas Martens said:

    Because of that we want to implement an error-handling for the case of lost data because of a too small receive-buffer. Is their a way to get the information from the stack if data is thrown because of an overloaded receive-buffer?

    looking at the driver code, I don't see any support for a hook function.  However, I do see that the code is keeping track of times where packets are dropped due to memory issues.

    I believe you should have the code to the driver, so you could update it to call any function you desire when this happens.  I've pasted the code here with a suggested change in red.

    Steve

    /* ethdriver.c */

    static EMAC_Pkt *RxPacket(Handle hApplication, EMAC_Pkt *cslPkt)
    {
            PBM_Handle  hPkt;

            if( (Uint32)hApplication != 0x12345678 )
        {
                return NULL;
        }

            hPkt = PBM_alloc(PktMTU + 4 + PKT_PREPAD);
            if (hPkt)
            {
                    PBM_setValidLen((PBM_Handle) cslPkt->AppPrivate, cslPkt->ValidLen);
                PBM_setIFRx((PBM_Handle) cslPkt->AppPrivate, pPDI->hEther );
                PBMQ_enq( &pPDI->PBMQ_rx, (PBM_Handle) cslPkt->AppPrivate );

            /* Notify NDK stack of pending Rx Ethernet packet */
                    STKEVENT_signal( pPDI->hEvent, STKEVENT_ETHERNET, 1 );

            PBM_setDataOffset( hPkt, PKT_PREPAD );
                    cslPkt->AppPrivate  = (Uint32)hPkt;
                    cslPkt->pDataBuffer = PBM_getDataBuffer(hPkt);
                    cslPkt->BufferLen   = PBM_getBufferLen(hPkt);
                    cslPkt->DataOffset = PBM_getDataOffset(hPkt);

    #ifdef EXTERNAL_MEMORY
                    /* Clean the cache for external addesses */
                     if( (UINT32)(PBM_getDataBuffer(cslPkt->AppPrivate)) & EXTMEM )
                       OEMCacheClean( (void *)(PBM_getDataBuffer(cslPkt->AppPrivate)), PBM_getBufferLen(cslPkt->AppPrivate) );
    #endif
                    return( cslPkt );
            }

            /* Increment the statistics to account for packets dropped because
             * of memory squeeze
         */
            memory_squeeze_error++;

            /* call back into application when packet dropped due to memory limitations */

                     myCallBackFxn(memory_squeeze_error);

            return cslPkt;
    }