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.

TcpEcho example fail to send and receive

Hello all,

I am trying to run TcpEcho example, but I'm facing some issues that I can't run properly.

First I was trying to connect via DCHP as original procedure, but I get the same error F002 already posted here acouple months ago.

I have checked the TM2C129 Emac issue and looks like the TI-RTOS TivaC version I am using (2.14.00.10) has already updated the EMACsnow.c file with the working around. I have also installed on my PC a DCHP server, so I don't understand where can be the problem

I also tried to use an static IP, changing it on .cfg file. I went a little bit further, now I can create a socket, bind it and connect it. Once the tcpHandler create a thread and call task tcpWorker, I get -1 as result of recv() call. Tried also to monitor the error by using fdError() function and the result is also -1, which is not mentioned for recv() function as a error result.

Please, anyone has a hint how could I go around this issue?

Thank you in advance.

Bests,

Douglas 

  • Hi Douglas,

    Could you provide the console output from CCS?  I found this, which may be helpful to you

    https://e2e.ti.com/support/embedded/tirtos/f/355/t/428105

    Best regards,

        Janet

  • Hi Janet,

    Thanks for the hint. I had already seen this post, but it was not so useful for me since I could see my MAC in ROV, therefore I printed on Console.

    Please check the Console output below for Static IP configuration and the for using DHCP. As you can see, I tried to connect twice, but both without success. Besides, I can not check what error is going on.

    Using MAC address in flash
    ulUser0 0xb61a00
    ulUser1 0x8ff602
    MAC 0: 0x0
    MAC 1: 0x1a
    MAC 2: 0xb6
    MAC 3: 0x2
    MAC 4: 0xf6
    MAC 5: 0x8f
    Starting the TCP Echo example
    System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
    Network Added: If-1:169.254.254.1
    fdOpensSession success
    Socket created - Port 35091     <-- I am using port 5001 for this test.
    Socket bind
    Socket waiting for accept
    tcpHandler: Creating thread clientfd = 536910756
    tcpWorker: start clientfd = 0x20009ba4
    Error recv function - fdError = -1
    tcpWorker stop clientfd = 0x20009ba4
    tcpHandler: Creating thread clientfd = 536911268
    tcpWorker: start clientfd = 0x20009da4
    Error recv function - fdError = -1
    tcpWorker stop clientfd = 0x20009da4

    This is the DHCP version output:

    Using MAC address in flash
    ulUser0 0xb61a00
    ulUser1 0x8ff602
    MAC 0: 0x0
    MAC 1: 0x1a
    MAC 2: 0xb6
    MAC 3: 0x2
    MAC 4: 0xf6
    MAC 5: 0x8f
    Starting the TCP Echo example
    System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
    Service Status: DHCPC : Enabled : : 000
    Service Status: DHCPC : Enabled : Running : 000
    fdOpensSession success
    Socket created - Port 35091
    Socket bind
    Socket waiting for accept
    Service Status: DHCPC : Enabled : Fault : 002

    Like the post you mentioned, after a while I get this fault message and get no IP. I have a DHCP server installed and running on PC, but it doesn't work.

    This is what I get when I try to check the MAC in the ROV:

     

    I may be searching for on wrong place, therefore i printed the information at the Console. My MAC is 00:1A:B6:02:F6:8F.

    Thank you. 

    Bests,

    Douglas

  • Hi Douglas,
    With the statically configured IP address, can you try stepping into the recv() code and see where it's failing? Unfortunately, recv() returns -1 if any error occurs, so it's hard to tell why it's failing. You should find the socket.c code in
    <TI_RTOS_INSTALL>/products/<ndk>/packages/ti/ndk/stack/fdt/
    Thanks,
    Janet
  • Most sockets APIs return -1 upon failure. If -1 is returned, you should try calling fdError() to get the error code associated with what went wrong (or just 'errno' if using the BSD version of the APIs).

    You can then check the error code against those found in ti/ndk/inc/serrno.h

    Steve
  • Hi Janet,

    I tried you suggestion and found a very strange behaviour on NDK_recv() function, which I explain below on code and disassembly as well:

    int NDK_recv( SOCKET s, void *pbuf, int size, int flags )
    {  <-3. Come back to beginning
        FILEDESC *pfd = (FILEDESC *)s;
        int  error = 0;
        INT32    rxsize;
    
        llEnter();   <- 1. Starts here entering on kernel
    
        /* Lock the fd - type must be SOCK / SOCK6 / PIPE / RAWETH */
        if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) ) <- 2. Lock the FD type     
    <- 4. Check the FD again
    { llExit(); return( SOCKET_ERROR ); printf("Call in fdint_lockfd\n\r"); } /* Receive data */ if( pfd->Type == HTYPE_SOCK ){
    error = SockRecv(pfd, pbuf, (INT32)size, flags, 0, &rxsize); printf("Call in Receive data: pfd->Type HTYPE_SOCK\n\r"); } #ifdef _INCLUDE_IPv6_CODE else if( pfd->Type == HTYPE_SOCK6 ) error = Sock6Recv(pfd, pbuf, (INT32)size, flags, 0, &rxsize); #endif else if( pfd->Type == HTYPE_RAWETHSOCK ) { /* For now, we only support no-copy version of recv on * raw ethernet sockets, so return error on recv(). */ error = EOPNOTSUPP; printf("Call in Receive data: pfd->Type HTYPE_RAWETHSOCK\n\r"); } else { error = PipeRecv(pfd, pbuf, (INT32)size, flags, &rxsize); printf("Call in PipeRecv: Error\n\r"); } <- 5. Goes directly to this point without perform if else due a jump in assembly (see below) if (error) { <- 6. Starts the if(error) /* Unlock the fd with error */ fdint_unlockfd( pfd, error ); printf("Call in fdint_unlockfd if error\n\r"); llExit(); return (SOCKET_ERROR); } /* Success. Unlock the fd without error */ fdint_unlockfd( pfd, 0 ); printf("Call in fdint_lockfd if success\n\r"); llExit(); return ((int)rxsize); }

    Disassembly:

              NDK_recv():
    00011268:   B5FE     PUSH            {R1, R2, R3, R4, R5, R6, R7, LR}
    0001126a:   461F     MOV             R7, R3
    0001126c:   4616     MOV             R6, R2
    0001126e:   460D     MOV             R5, R1
    00011270:   4604     MOV             R4, R0
     635          llEnter();
    00011272:   F7FAF839 BL              llEnter    <- 1. Starts here entering on kernel
    638 if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) ) 00011276: 2100 MOVS R1, #0 <- 2. Lock the FD type 00011278: 4620 MOV R0, R4 0001127a: F002F9C7 BL fdint_lockfd 630 { 0001127e: 463B MOV R3, R7 <-3. Come back to beginning - As per Disassembly, it goes to line 630 which is the first of the C code file
    00011280: 4632 MOV R2, R6 00011282: 4629 MOV R1, R5 638 if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) ) 00011284: F1B03FFF CMP.W R0, #4294967295 <- 4. Check the FD again 00011288: D018 BEQ $C$L54 <- 4a. - Jumps to addr 112bc (see below) 645 /* Receive data */ 0001128a: 6820 LDR R0, [R4] 0001128c: 280A CMP R0, #10 0001128e: D009 BEQ $C$L51 651 else if( pfd->Type == HTYPE_SOCK6 ) 00011290: 2817 CMP R0, #23 00011292: D005 BEQ $C$L50 659 error = EOPNOTSUPP; 00011294: A802 ADD R0, SP, #8 00011296: 9000 STR R0, [SP] 00011298: 4620 MOV R0, R4 0001129a: F7FAFD1F BL PipeRecv 0001129e: E008 B $C$L52 656 /* For now, we only support no-copy version of recv on $C$L50: 000112a0: 202D MOVS R0, #45 657 * raw ethernet sockets, so return error on recv(). 000112a2: E007 B $C$L53 646 if( pfd->Type == HTYPE_SOCK ){ $C$L51: 000112a4: 2000 MOVS R0, #0 000112a6: AF02 ADD R7, SP, #8 000112a8: 9000 STR R0, [SP] 000112aa: 4620 MOV R0, R4 000112ac: 9701 STR R7, [SP, #4] 000112ae: F7F5FA25 BL SockRecv $C$L52: 000112b2: B140 CBZ R0, $C$L55 664 error = PipeRecv(pfd, pbuf, (INT32)size, flags, &rxsize); $C$L53: 000112b4: 4601 MOV R1, R0 000112b6: 4620 MOV R0, R4 000112b8: F002FEB4 BL fdint_unlockfd 666 } $C$L54: 000112bc: F7FFFC74 BL llExit <- 5. Come directly to this point calling kernel exit due a jump on address 11288 668 { 000112c0: F04F30FF MOV.W R0, #4294967295 <- 6. Starts the if(error)
    000112c4: BDFE POP {R1, R2, R3, R4, R5, R6, R7, PC} 672 llExit(); $C$L55: 000112c6: 4620 MOV R0, R4 000112c8: 2100 MOVS R1, #0 000112ca: F002FEAB BL fdint_unlockfd 674 return (SOCKET_ERROR); 000112ce: F7FFFC6B BL llExit 676 000112d2: 9802 LDR R0, [SP, #8] 000112d4: BDFE POP {R1, R2, R3, R4, R5, R6, R7, PC} 000112d6: 0000 LSLS R0, R0, #0

    After the 6th step the C code finish the NDK_recv() function and stays at close bracket of recv() function on socket.h header. On disassembly it goes to another address (00015f06) which is the same point of the recv() function of socket.h.

    Therefore I get no result from recv() once IHMO the code is not properly performed. It seems the disassembled code does not matchs to this socket.c code.

    I tried also to insert the folder you suggested on lookup source but again without success.

    Do you have any idea else I could check?

    Thank you!

    Douglas 

              NDK_recv():00011268:   B5FE     PUSH            {R1, R2, R3, R4, R5, R6, R7, LR}0001126a:   461F     MOV             R7, R30001126c:   4616     MOV             R6, R20001126e:   460D     MOV             R5, R100011270:   4604     MOV             R4, R0 635          llEnter();00011272:   F7FAF839 BL              llEnter 638          if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) )00011276:   2100     MOVS            R1, #000011278:   4620     MOV             R0, R40001127a:   F002F9C7 BL              fdint_lockfd 630      {0001127e:   463B     MOV             R3, R700011280:   4632     MOV             R2, R600011282:   4629     MOV             R1, R5 638          if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) )00011284:   F1B03FFF CMP.W           R0, #429496729500011288:   D018     BEQ             $C$L54 645          /* Receive data  */0001128a:   6820     LDR             R0, [R4]0001128c:   280A     CMP             R0, #100001128e:   D009     BEQ             $C$L51 651          else if( pfd->Type == HTYPE_SOCK6 )00011290:   2817     CMP             R0, #2300011292:   D005     BEQ             $C$L50 659              error = EOPNOTSUPP;00011294:   A802     ADD             R0, SP, #8 00011296:   9000     STR             R0, [SP]00011298:   4620     MOV             R0, R40001129a:   F7FAFD1F BL              PipeRecv0001129e:   E008     B               $C$L52 656              /* For now, we only support no-copy version of recv on           $C$L50:000112a0:   202D     MOVS            R0, #45 657               * raw ethernet sockets, so return error on recv().000112a2:   E007     B               $C$L53 646          if( pfd->Type == HTYPE_SOCK ){          $C$L51:000112a4:   2000     MOVS            R0, #0000112a6:   AF02     ADD             R7, SP, #8 000112a8:   9000     STR             R0, [SP]000112aa:   4620     MOV             R0, R4000112ac:   9701     STR             R7, [SP, #4]000112ae:   F7F5FA25 BL              SockRecv          $C$L52:000112b2:   B140     CBZ             R0, $C$L55 664              error = PipeRecv(pfd, pbuf, (INT32)size, flags, &rxsize);          $C$L53:000112b4:   4601     MOV             R1, R0000112b6:   4620     MOV             R0, R4000112b8:   F002FEB4 BL              fdint_unlockfd 666          }          $C$L54:000112bc:   F7FFFC74 BL              llExit 668          {000112c0:   F04F30FF MOV.W           R0, #4294967295000112c4:   BDFE     POP             {R1, R2, R3, R4, R5, R6, R7, PC} 672              llExit();          $C$L55:000112c6:   4620     MOV             R0, R4000112c8:   2100     MOVS            R1, #0000112ca:   F002FEAB BL              fdint_unlockfd 674              return (SOCKET_ERROR);000112ce:   F7FFFC6B BL              llExit 676      000112d2:   9802     LDR             R0, [SP, #8]000112d4:   BDFE     POP             {R1, R2, R3, R4, R5, R6, R7, PC}000112d6:   0000     LSLS            R0, R0, #0

  • Hi Steve,

    Yes, I tried do that, but fdError() fxn returns -1 as well. As per the files serrno.h the -1 result is not related to the function it is failing (recv).
    I wrote the step-by-step to Janet above trough out the code and waiting for approval to post it.

    thanks
    Douglas
  • Hi Douglas,
    If the disassembly does not match the C code, then it sounds like you are linking with an old library. I noticed you have print statements in your NDK_recv() function. Did you rebuild the NDK after you made those changes?
    Thanks,
    Janet
  • Hi Janet,

    I followed your last suggestion and rebuilt the NDK with command

    gmake -f tirtos.mak ndk

    After a big job, I rebuilt again the tcpexample and unfortunately I am still getting the same strange behaviour as before. It doesn't receive nothing and error continue being -1.

    I am using TIRTOS for TivaC version 2.14.00.10. I tried to update but got a fail. 

    Does it suggest any hardware issue? I will try to do the same in a M3 processor to check.

    Thank you!

    Douglas

  • Hi Douglas,
    From your first post, it does seem like there is some hardware issue. Were you able to step into the recv() function after rebuilding (and hopefully source code lines in debugger are correctly aligned)? It would be good to know where in recv() the failure is.
    Best regards,
    Janet
  • Hi Janet,

    Well, things seems to getting complicated. After the rebuild the NDK, I got into the recv() function and the behaviour was still the same(still seems the disassembled code is different).

    So, then I updated the RTOS-TivaC for version 2_14_04_31 (was 2_14_00_10), rebuild the example and tested with this new version, but the result was exactly as before. I dind't rebuil this new version of NDK, but it looks like the problem will remain.

    Again the step-by-step inside the recv(), this time I hope I can edit properly.

    int NDK_recv( SOCKET s, void *pbuf, int size, int flags )
    { <- 3. Goes back to beginning
    FILEDESC *pfd = (FILEDESC *)s;
    int error = 0;
    INT32 rxsize;

    llEnter(); <- 1. Enter into kernel

    /* Lock the fd - type must be SOCK / SOCK6 / PIPE / RAWETH */
    if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) )  <- 2. Execute if    <-4. Check again the if (see below in disassembly it really does it twice)
    {
    llExit();
    return( SOCKET_ERROR );
    }

    /* Receive data */
    if( pfd->Type == HTYPE_SOCK )
    error = SockRecv(pfd, pbuf, (INT32)size, flags, 0, &rxsize);
    #ifdef _INCLUDE_IPv6_CODE
    else if( pfd->Type == HTYPE_SOCK6 )
    error = Sock6Recv(pfd, pbuf, (INT32)size, flags, 0, &rxsize);
    #endif
    else if( pfd->Type == HTYPE_RAWETHSOCK )
    {
    /* For now, we only support no-copy version of recv on
    * raw ethernet sockets, so return error on recv().
    */
    error = EOPNOTSUPP;
    }
    else
    error = PipeRecv(pfd, pbuf, (INT32)size, flags, &rxsize);

    if (error)
    {
    /* Unlock the fd with error */
    fdint_unlockfd( pfd, error );

    llExit();    <-5. Jump to here to exit kernel (in the disassembly is possible to see the jump)

    return (SOCKET_ERROR); <-6. Return and get out
    }

    /* Success. Unlock the fd without error */
    fdint_unlockfd( pfd, 0 );

    llExit();

    return ((int)rxsize);
    }

    DISASSEMBLY

    630 {
    NDK_recv():
    00011280: B5FE PUSH {R1, R2, R3, R4, R5, R6, R7, LR}
    00011282: 461F MOV R7, R3
    00011284: 4616 MOV R6, R2
    00011286: 460D MOV R5, R1
    00011288: 4604 MOV R4, R0
    635 llEnter();   Step 1 above
    0001128a: F7FAF8AF BL llEnter
    638 if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) )  Step 2 above
    0001128e: 2100 MOVS R1, #0
    00011290: 4620 MOV R0, R4
    00011292: F002F9AB BL fdint_lockfd
    630 {  Step 3 above
    00011296: 463B MOV R3, R7
    00011298: 4632 MOV R2, R6
    0001129a: 4629 MOV R1, R5
    638 if ((fdint_lockfd(pfd, 0) == SOCKET_ERROR) ) Step 4 above - repeats if
    0001129c: F1B03FFF CMP.W R0, #4294967295
    000112a0: D018 BEQ $C$L54 Jumps to this address
    645 if( pfd->Type == HTYPE_SOCK )
    000112a2: 6820 LDR R0, [R4]
    000112a4: 280A CMP R0, #10
    000112a6: D009 BEQ $C$L51
    651 else if( pfd->Type == HTYPE_RAWETHSOCK )
    000112a8: 2817 CMP R0, #23
    000112aa: D005 BEQ $C$L50
    659 error = PipeRecv(pfd, pbuf, (INT32)size, flags, &rxsize);
    000112ac: A802 ADD R0, SP, #8
    000112ae: 9000 STR R0, [SP]
    000112b0: 4620 MOV R0, R4
    000112b2: F7FAFD97 BL PipeRecv
    000112b6: E008 B $C$L52
    656 error = EOPNOTSUPP;
    $C$L50:
    000112b8: 202D MOVS R0, #45
    657 }
    000112ba: E007 B $C$L53
    646 error = SockRecv(pfd, pbuf, (INT32)size, flags, 0, &rxsize);
    $C$L51:
    000112bc: 2000 MOVS R0, #0
    000112be: AF02 ADD R7, SP, #8
    000112c0: 9000 STR R0, [SP]
    000112c2: 4620 MOV R0, R4
    000112c4: 9701 STR R7, [SP, #4]
    000112c6: F7F5FA19 BL SockRecv
    $C$L52:
    ......... ...
    666 llExit();
    $C$L54:
    000112d4: F7FFFC74 BL llExit  Step 5 above
    668 return (SOCKET_ERROR); Step 6 above
    000112d8: F04F30FF MOV.W R0, #4294967295
    000112dc: BDFE POP {R1, R2, R3, R4, R5, R6, R7, PC}
    672 fdint_unlockfd( pfd, 0 );
    $C$L55:
    000112de: 4620 MOV R0, R4
    000112e0: 2100 MOVS R1, #0
    000112e2: F002FEAF BL fdint_unlockfd
    674 llExit();
    000112e6: F7FFFC6B BL llExit
    676 return ((int)rxsize);
    000112ea: 9802 LDR R0, [SP, #8]
    000112ec: BDFE POP {R1, R2, R3, R4, R5, R6, R7, PC}
    000112ee: 0000 LSLS R0, R0, #0

    Do you have any other hint I could check? Why the disassembly remains different even after rebuild and/or updating?

    Thank you

    Douglas

  • Hi Douglas,
    It looks to me like fdint_lockfd() is failing. (You may be jumping around in the debugger due to optimization. ) You didn't change the example code or configuration in any way, correct?
    Thanks,
    Janet
  • Hi Janet,
    Yes, I did, but I believe without results modifications. I did the following modification:
    1. Changed the tcpWorker task from:
    while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0)
    to
    bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0);
    while (bytesRcvd > 0)

    2. I changed the netopenHook. Instead of creating the tcpHandler task dynamically, I did it statically in the cfg file and in the hook just posted a semaphore to start the task when this hook is executed. Then in the task I inserted the fdOpenSession() function.

    3. I inserted the board IP statically in the cfg file, so I am not using the DHCP.

    Do you believe these changes would affect the result?
    Thanks
    Douglas
  • Hi Douglas,
    Changing to use a static IP address is fine. I tried this and the example still worked. However, I haven't been able to get #2 to work. Is there any reason you needed the tcpHandler to be created statically? Can you try changing that back to how it was originally?
    Also, you are probabaly calling bytesRcvd = recv(...) inside the while () loop, but in case not, you would need to do that given your change in #1.
    Best regards,
    Janet