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.

read TCP header failed

Other Parts Discussed in Thread: AM3359, SYSBIOS

Hi Guys,

I used my AM3359 ICE V2 board as a TCP server(MODBUS TCP SERVER) to communicate with a client.  The server can get the command from client but every time the client side gives an error message "Read TCP Header Failed".  Two questions here:

1)Can some one tell me what is the problem here, why the client gives the error message?

2) if the client read tcp header failed, whether it will resend the same command again or not?

Thanks and have a good day!

Software I used:

Sys_BIOS, NDK; 

Hardware:

AM3359 ICE V2 

Here is PART of my test code:

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if( s == INVALID_SOCKET )
{
printf("failed socket create (%d)\n",fdError());
if( pBuf )
mmBulkFree( pBuf );
if( s != INVALID_SOCKET )
fdClose( s );
}

/* Prepare address for connect */
bzero( &sin1, sizeof(struct sockaddr_in) );
sin1.sin_family = AF_INET;
sin1.sin_addr.s_addr = address; // 192.168.1.2
//sin1.sin_port = htons(7);
sin1.sin_port = htons(502); // modbus tcp port is 502

if (bind (s, (PSA) &sin1, sizeof (sin1)) < 0) {
printf("failed bind (%d)\n",fdError());
if( pBuf )
mmBulkFree( pBuf );
if( s != INVALID_SOCKET )
fdClose( s );
}
/* listen socket */


if ( listen( s, 5) < 0 )
{
printf("listen failed(%d)\n",fdError());
if( pBuf )
mmBulkFree( pBuf );
if( s != INVALID_SOCKET )
fdClose( s );
}

else
{
printf("listen correct\n");
while(1){
struct sockaddr_in clisinaddr;
int clilen = sizeof(clisinaddr);
SOCKET clisok;

printf("before the accept test is: %d\n", clilen);
clisok = accept(s, (PSA) &clisinaddr, &clilen);
printf(" test value is: %d\n", clilen);
if(clisok == INVALID_SOCKET){
printf("accept error %d\n", fdError());
if( pBuf )
mmBulkFree( pBuf );
if( s != INVALID_SOCKET )
fdClose( s );
}
else {
printf("accept correct\n");

printf("===== received data ====\n");
gotdatabyte = recv( clisok, pBuf, 50, MSG_PEEK );
printf("the received data is: %d byte\n", gotdatabyte);
if( gotdatabyte < 0 )
{
printf("recv failed (%d)\n",fdError());
// goto leave; //break;
}

for (j = 0; j< gotdatabyte; j++){
printf("received data byte %d is: %d\n", j, *(pBuf+j));
}

 ProcessReceivedMessage();  // process the command, in this function changed the pBuf, the size will be different from the original received pBuf

// send the response to client

if( send( client_socket, pBuf, 10, 0 ) < 0 )
{
printf("send failed (%d)\n",fdError());
}

mmZeroInit( pBuf, (uint)MODBUS_RX_BUFFER_SIZE);
fdClose( client_socket );

  • Which versions of SYS/BIOS and NDK are you using?
  • Can you share your .cfg file?
  • Hi Alan,

    Thanks for your reply. Here is the NDK and SYS/BIOS version:
    NDK: 2.24.1.18
    SYS/BIOS: 6.41.0.26
    Here is my .cfg file:

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Mmu = xdc.useModule('ti.sysbios.family.arm.a8.Mmu');
    var GateHwi = xdc.useModule('ti.sysbios.gates.GateHwi');
    /*
    * Program.argSize sets the size of the .args section.
    * The examples don't use command line args so argSize is set to 0.
    */
    Program.argSize = 0x0;

    /*
    * Uncomment this line to globally disable Asserts.
    * All modules inherit the default from the 'Defaults' module. You
    * can override these defaults on a per-module basis using Module.common$.
    * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
    */

    /*
    * Uncomment this line to keep module names from being loaded on the target.
    * The module name strings are placed in the .const section. Setting this
    * parameter to false will save space in the .const section. Error and
    * Assert messages will contain an "unknown module" prefix instead
    * of the actual module name.
    Defaults.common$.namedModule = false;
    */

    /*
    * Minimize exit handler array in System. The System module includes
    * an array of functions that are registered with System_atexit() to be
    * called by System_exit().
    */
    System.maxAtexitHandlers = 1;

    /*
    * Uncomment this line to disable the Error print function.
    * We lose error information when this is disabled since the errors are
    * not printed. Disabling the raiseHook will save some code space if
    * your app is not using System_printf() since the Error_print() function
    * calls System_printf().
    Error.raiseHook = null;
    */

    /*
    * Uncomment this line to keep Error, Assert, and Log strings from being
    * loaded on the target. These strings are placed in the .const section.
    * Setting this parameter to false will save space in the .const section.
    * Error, Assert and Log message will print raw ids and args instead of
    * a formatted message.
    Text.isLoaded = false;
    */

    /*
    * Uncomment this line to disable the output of characters by SysMin
    * when the program exits. SysMin writes characters to a circular buffer.
    * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
    */

    /*
    * The BIOS module will create the default heap for the system.
    * Specify the size of this default heap.
    */
    BIOS.heapSize = 0x155000;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x6000;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 0x200;

    System.SupportProxy = SysMin;

    Mmu.enableMMU = false;

    Clock.tickPeriod = 500;
    var Global = xdc.useModule('ti.ndk.config.Global');
    var Ip = xdc.useModule('ti.ndk.config.Ip');

    Global.netSchedulerPri = Global.NC_PRIORITY_HIGH;
    Global.debugAbortLevel = Global.DBG_ERROR;
    Global.debugPrintLevel = Global.DBG_NONE;

    //Global.stackThreadUser = "&NDKACD_stackThread";

    var Tcp = xdc.useModule('ti.ndk.config.Tcp');
    var Udp = xdc.useModule('ti.ndk.config.Udp');

    Ip.ResolveIP = false;
    Ip.dhcpClientMode = 0;
    Ip.CallByIP = false;
    Ip.autoIp = false;
    Ip.address = "192.168.1.2";
    Ip.gatewayIpAddr = "192.168.1.1";
    Ip.mask = "255.255.255.0";
    Global.ndkTickPeriod = 200;
    Global.kernTaskPriLevel = 11;
    Global.serviceReportHook = null;
    Global.IPv6 = false;

    Task.defaultStackSize = 4096;
    Task.idleTaskStackSize = 4096;


    BIOS.libType = BIOS.LibType_Custom;

    Program.sectionsExclude = "^\\.bss|^\\.neardata|^\\.rodata|^\\.data|^\\.stack|^\\.far:NDK_PACKETMEM|^\\.far:NDK_MMBUFFER";
    Mmu.defaultAttrs.type = Mmu.FirstLevelDesc_RESERVED;
    Ip.enableForwarding = true;
    Ip.enableFiltering = false;
    Global.stackBeginHook = null;
    Global.stackInitHook = null;
    Global.stackDeleteHook = "&MyStackThreadDelete";
    Ip.IfIdXValid = false;
    Global.networkIPAddrHook = "&myIPAddrHook";
    Semaphore.supportsEvents = true;
    BIOS.rtsGateType = BIOS.NoLocking;
    Clock.timerId = -1;



    P.S. I built my code based on the example code "ethernetip_adapter". I followed the introduction by"AM335x SYSBIOS Industrial SDK 01.01.00.06 User Guide.pdf" to remove the ethernet/ip application and use it as a switch application. What I used is to build a MODBUS TCP server on am3359 ice v2.0 board and communicate with MODBUS TCP client via ethernet.

    Thanks.

    Regards,
    Aaron
  • I have questions about a couple of things in your .cfg file.

    1) Why is the MMU disabled? Without the MMU enabled, the data cache is disabled. This SEVERELY affects performance.
    2) Why is the Clock.tickPeriod set to 500us?
    3) Why is the BIOS.rtsGateType set to NoLocking? This is a little dangerous when multiple threads call certain RTS functions simultaneously (rand(), printf(), ...) as these functions are explicitly NOT re-entrant. (read this link for details on non-reentrant RTS functions processors.wiki.ti.com/.../Reentrant ).

    Alan
  • Hi Alan,

    To tell you truth, I have no idea of how to configure .cfg file. This is the first time using SYS/BIOS. I wrote my code based on the "ethernetip_adapter" example code and I do nothing for the .cfg file. Could you give me some advice or some introductions? Any materials? Thank you so much!


    Regards,
    Aaron
  • Aaron,

    Since you are using the Industrial SDK and its examples, I went ahead and moved this thread over to the device forum in case an IDSK expert there can add anything further.
  • Hi Guys,

    Can anyone give some suggestions? Thanks.


    Aaron