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.

TMS320C6678: BSD socket create always fail when the socket function is called in posix pthread

Part Number: TMS320C6678
Other Parts Discussed in Thread: SYSBIOS

os: Linux Centos 

sdk version: psdk 6.00.00.07, this includes all relevant packages, ndk , pdk, bios and ipc ,etc. 

ccs: 8.3

I'm trying to migrate our software to use the latest processor sdk from MCSDK2.1. I've successfully compile our software using all packages from PSDK.  I've encounter some problems along the way, but i have resolved all compiling errors. One complaint that i have is that I've seen a lot of meaningless API changes in the CSL that basically just add or remove "underscores" in the API.   

Now the real problem is that i see socket creation errors when i use the bsd socket call in the posix pthread. Most threads in our software are posix pthreads created using posix APIs, not ti task or ndk tasks. In our software, we create a task in the main function that creates all the pthreads that run all of our production software. In some of those threads, I create sockets by calling BSD style socket API. This has worked with the old tool chain , aka MCSDK2.x. Our software is fairly complicated, so I modified the NIMU_emacExample_EVMC6678C66BiosExampleProject, aka the ndk hellworld example to track down whats causing the socket call error. 

In the main function of the code, i created a task to create a pthread which runs a function that simply creates a socket using the BSD socket API in the Network Service BSD header file. I got the same error, socket call always return -1 in the following code.  

extern "C" int dtask_udp_hello2( void )
{

    while(!networkStackStarted)
    {
        Task_sleep(1000);
    }
   fdOpenSession((void *)pthread_self());

   int skt;
   skt = (int) socket(AF_INET,SOCK_DGRAM,0);
   if(skt==-1)
   {

       printf("socket create failed.\n");
   }
   fdCloseSession(pthread_self());

   return 0;
}

I've also tried setting the autoOpenCloseFd to true in the sysbios configuration file and removed the fdOpenSession and fdCloseSession function calls. That didn't work either. I need some help at this point.

i'm attaching the example project. To build the project, change the variable "NS_INSTALL_PATH" to point to where your Network Service module(ns_2_60_00_07) is install. This variable is defined in "Project" -> "Properties"->"CCS Build" -> tab "Variables".

 

psdkHelloWorld.zip

  • This is a custom board, or TMDSEVM6678?

    Thanks,
    Yordan

  • I tried both our custom board and the c6678 EVM, both have the same errors. The example i attached is for the EVM. 

  • Hi,

    Thanks for providing the CCS project and I was able to reproduce that skt = (int) socket(AF_INET,SOCK_DGRAM,0); return -1. I will check why is that and update.

    Regards, Eric

  • Wei Chen,

    I have built your attached example (thanks for providing this). I see some build warnings I'll have to investigate.

    I am trying to understand the step you are taking. It sounds like you started with MCSDK 2.1 and are migrating to Processor SDK C667x 6.00.00.07.

    I don't recognize MCSDK 2.1. Would you provide the download link or a product link so that I can study it.

    Thanks,
    ~Ramsey

  • Ramsey,

     sorry about the confusion. I meant MCSDK2.0 for keystone I device, .

    Link to the downlinking the packages seems broken for some reason tho. 

    essential what happened was that I tried to migrate our software based on MCSDK2.0 to Processor SDK. But I always get errors when I call "socket" function, so my software basically crashes because of these socket errors. I purposely crash the software because this error is pretty severe. Our software is complicated,   so I resulted to create a much simpler example that calls the "socket" function which also gives me the same erroneous result. 

    steps are simple:

    1. create a task and lets call it "Task A". in the main statically,

    2. create a pthread in the "Task A". The pthread is created with a thread function that simply creates a socket. 

    The above procedure mimics what I have in our software. im basing the example I provided above off of the NIMU_emacExample_EVMC6678C66BiosExampleProject example in the pdk package in processor sdk.

    All source code changes are in the helloWorld.c and testSocket.cpp files. I added the following line to the sysbios config file to add posix support, 

    var Settings = xdc.useModule('ti.posix.tirtos.Settings');


    In addition, the example above also might be using dhcp instead of static IP address. Similar project can be also created base off of the helloWorld ndk example from MCSDK2.0. If it helps, I can try to create the same example using mcsdk2.0 when I get back to the office on Tuesday. 

  • Wei Chen,

    Thanks for clarifying the MCSDK 2.1 reference.

    I think you are calling the wrong function when creating the file descriptor table.

    Try replacing pthread_self() with Task_self() in your call to fdOpenSession():

    fdOpenSession((void *)Task_self());

    Also, have a look at the User Guide Section 2.3.1.

    <SDK>/ndk_3_60_00_13/docs/ndk/NDK_Users_Guide.html

    You will need to update all your session API calls.

    ~Ramsey

  • Hi, Ramsey,

    I've been through the ndk user guide. I tried both pthread_self() and Task_self(), the result is the same.  They should be the same. Like i mentioned above, all of the threads running in my code are pthreads. Therefore, The fdOpenSession is called actually in context of a pthread not a task in this example. Therefore pthread_self() should have worked.  

  • Wei Chen,

    The call to fdOpenSession() needs a pointer to a SYS/BIOS task object, which is what Task_self() will return. The call to pthread_self() will return a pointer to a pthread_t object.

    Having fixed that much, I think the example is failing for other reasons. For instance, I don't see where the example is waiting for the network to start. It looks to me that the call to socket() is happening too soon.

    From what I can see, you are using a nimu example. Unfortunately, such an example is not setup correctly for making BSD network calls. For a complete networking example, you must have NDK configuration, hooks, and appropriate startup calls.

    I suggest you fix the call to fdOpenSession() in your application, and see what happens. If your application continues to fail, then we need to find an appropriate network example for testing.

    ~Ramsey

  • l have tried running it with Task_self() and just tried again, it failed.  pthread_self actually returns what Task_self() returns. There is a layer of software abstraction that maps pthread_self to Task_self().

    and in regards to waiting for network stack to start:

    there is something in the example to wait for network stack to start,  in file socketTest.cpp,  see while loop in the code below

    extern "C" int dtask_udp_hello2( void )
    {
    
        while(!networkStackStarted)
        {
            Task_sleep(1000);
        }
       fdOpenSession((void *)pthread_self());
    
       int skt;
       skt = (int) socket(AF_INET,SOCK_DGRAM,0);
       if(skt==-1)
       {
    
           printf("socket create failed.\n");
       }
       fdCloseSession(pthread_self());
    
       return 0;
    }.

    networkStackStarted is set in the "NetworkOpen" function in helloWorld.c.


    The above sequence have worked with mcsdk2.0. That's what I have been doing for over three years. not sure what you mean by this example is not setup correctly for BSD. NDK merely setups the transport. After the transport setup, BSD should work independently from the NDK according to the user guide. I'm keepngiall of the sources files using BSD API completely separate from the NDK api. That's what the User's guide is suggesting.  If it helps, i can setup the equivalent example using mcsdk2.0's ndk helloWorld example to show that it works. 
    Lastly, i think the conversation can be much more effective if you have the same setup on your side to replicate the problem.

  • Wei Chen,

    Okay. Thanks for testing the application. Looks like you are doing everything correctly. I'll have to investigate further.

    No need to setup the MCSDK 2.0 example. I believe you that this used to work. I'm trying to figure out what needs to change for the new NDK release. I'll keep you posted.

    ~Ramsey

  • Wei Chen,

    I am coordinating with the Processor SDK team. I expect to have an update for you by tomorrow. Sorry for the delay.

    ~Ramsey

  • no problem. Thanks Ramsey

  • Hi Wei,

    There are couple things...

    1. Please use TaskSelf() instead Task_self or pthread_self in the fdOpenSession. 

    2. You are not initializing the SlNetSock interface. I'm attaching a file that we are using on another product (please ignore the Display calls). The netIPAddrHook is called when the IP is obtained. You can then call SlNetSock_init, etc. 

    /*
     * Copyright (c) 2015-2019, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *    ======== tcpEchoHooks.c ========
     */
    
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    #include <pthread.h>
    
    #include <ti/ndk/inc/netmain.h>
    
    #include <ti/ndk/slnetif/slnetifndk.h>
    #include <ti/net/slnetif.h>
    #include <ti/net/slnetutils.h>
    
    #include <ti/display/Display.h>
    #include <ti/drivers/emac/EMACMSP432E4.h>
    
    #define TCPPORT 1000
    
    #define TCPHANDLERSTACK 2048
    #define IFPRI  4   /* Ethernet interface priority */
    
    /* Prototypes */
    extern void *tcpHandler(void *arg0);
    
    extern Display_Handle display;
    
    /*
     *  ======== netIPAddrHook ========
     *  user defined network IP address hook
     */
    void netIPAddrHook(uint32_t IPAddr, unsigned int IfIdx, unsigned int fAdd)
    {
        pthread_t           thread;
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
        int                 detachState;
        uint32_t            hostByteAddr;
        static uint16_t arg0 = TCPPORT;
        static bool createTask = true;
        int32_t status = 0;
    
        if (fAdd) {
            Display_printf(display, 0, 0, "Network Added: ");
        }
        else {
            Display_printf(display, 0, 0, "Network Removed: ");
        }
    
        /* print the IP address that was added/removed */
        hostByteAddr = NDK_ntohl(IPAddr);
        Display_printf(display, 0, 0, "If-%d:%d.%d.%d.%d\n", IfIdx,
                (uint8_t)(hostByteAddr>>24)&0xFF, (uint8_t)(hostByteAddr>>16)&0xFF,
                (uint8_t)(hostByteAddr>>8)&0xFF, (uint8_t)hostByteAddr&0xFF);
    
        status = SlNetSock_init(0);
        if (status != 0) {
            Display_printf(display, 0, 0, "SlNetSock_init fail (%d)\n",
                status);
        }
    
        status = SlNetIf_init(0);
        if (status != 0) {
            Display_printf(display, 0, 0, "SlNetIf_init fail (%d)\n",
                status);
        }
    
        status = SlNetUtil_init(0);
        if (status != 0) {
            Display_printf(display, 0, 0, "SlNetUtil_init fail (%d)\n",
                status);
        }
    
        status = SlNetIf_add(SLNETIF_ID_2, EMACMSP432E4_ETHERNET_NAME,
                (const SlNetIf_Config_t *)&SlNetIfConfigNDK, IFPRI);
        if (status != 0) {
            Display_printf(display, 0, 0, "SlNetIf_add fail (%d)\n",
                status);
        }
    
        if (fAdd && createTask) {
            /*
             *  Create the Task that farms out incoming TCP connections.
             *  arg0 will be the port that this task listens to.
             */
    
            /* Set priority and stack size attributes */
            pthread_attr_init(&attrs);
            priParam.sched_priority = 1;
    
            detachState = PTHREAD_CREATE_DETACHED;
            retc = pthread_attr_setdetachstate(&attrs, detachState);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_attr_setdetachstate() failed\n");
                while (1);
            }
    
            pthread_attr_setschedparam(&attrs, &priParam);
    
            retc |= pthread_attr_setstacksize(&attrs, TCPHANDLERSTACK);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_attr_setstacksize() failed\n");
                while (1);
            }
    
            retc = pthread_create(&thread, &attrs, tcpHandler, (void *)&arg0);
            if (retc != 0) {
                Display_printf(display, 0, 0,
                        "netIPAddrHook: pthread_create() failed\n");
                while (1);
            }
    
            createTask = false;
        }
    }
    
    /*
     *  ======== serviceReportHook ========
     *  NDK service report hook
     */
    void serviceReportHook(uint32_t item, uint32_t status, uint32_t report, void *h)
    {
        static char *taskName[] = {"Telnet", "HTTP", "NAT", "DHCPS", "DHCPC", "DNS"};
        static char *reportStr[] = {"", "Running", "Updated", "Complete", "Fault"};
        static char *statusStr[] =
            {"Disabled", "Waiting", "IPTerm", "Failed","Enabled"};
    
        Display_printf(display, 0, 0, "Service Status: %-9s: %-9s: %-9s: %03d\n",
                taskName[item - 1], statusStr[status], reportStr[report / 256],
                report & 0xFF);
    }
    
    /*
     *  ======== netOpenHook ========
     *  NDK network open hook
     */
    void netOpenHook()
    {
    }
    

    Can you try these two changes and see if that helps? More details about the SlNetSock layer are in the User Guide (NS_Users_Guide.html).

    Todd

  • Thanks. Todd, i will try it out. 

    seems like some stuff in the file is platform specific. Is there any example out there for c6678? if not, i'd recommend that TI provide some examples for the NS module. Because currently , there is none in there. Thanks.

  • i can't build it. i get the following errors,  .

    I did a grep in the psdk installation directory. These functions dont exist. 

  • Wei,

    Can you attach the entire build log? Please attach it instead of copy/paste.

    Todd

  • hi , Todd,

    I rebuilt the NDK and it worked. seems like the ndk shipped with processor sdk has mbedtls lib dependency. 

    I did some initial testing, socket call now works, however, the following code returns error, 

            status = SlNetIf_add(SLNETIF_ID_1, "CC78 ETH",
                        (const SlNetIf_Config_t *)&SlNetIfConfigNDK, 4);
            if (status != 0) {
                printf( "SlNetIf_add fail (%d)\n",
                        status);
           }

    but it seems like the bsd socket will work without adding the interface. Im doing further testing and will post my final finding so it might be useful for the others. 

  • Wei,

    Glad to hear you got past the issue. 

    Can you step into SlNetIf_add and see what is failing? 

    Todd

  • Todd,

    update:

    i kept getting bind failures for the socket. not sure if it has anything to do with SlNetIf_add failure,

    i get "SlNetIf_add fail (-2006)" when i tried to call SlNetIf_add.

    do you know whats the correct param to use for the first, second and the fourth argument for c6678?

  • Hi Wei,

    -2006 is in slneterr.h

    /* Parameters are invalid */
    #define SLNETERR_RET_CODE_INVALID_INPUT                                 (-2006L)

    Looking at the SlNetIf_add code, there could be two reasons for this. Can you step in to see which one it is? You might have called SlNetIf_add twice with the same id. This would cause the failure.

    Todd

  • hi todd,

    i tried to step into the code , but its not stepping through correctly, i believe its because the library i linked with was built with different source code then whats shipped with packcage. I'm trying to figure out how to rebuild the library, "slnetsock_release.a".

  • the following line failed in sletifndk.c line 2324. 

    dev = NIMUFindByName((char*)ifName);

    The interface name i passed into the SlNetIf_add function is bad. But what interface name should i use? i dont think there is any example that shows how to call the function for c6678. I tried to pass NULL, but it failed too.  

  • Wei,

    It's the name specified by the NIMU driver. Which NIMU driver are you using? You can look at the NIMUDeviceTable structure to find the init function where the name is usually set. You can also get the NETIF_DEVICE pointer via NIMUFindByIndex(). This structure has the name it it.

    Todd

  • ok, i tried the following code to add the interface, it worked,

    status = SlNetIf_add(SLNETIF_ID_1,"eth0",(const SlNetIf_Config_t*)&SlNetIfConfigNdk,4);
    
    

    but i get another error when i try to receive a packet using recvfrom. the code asserted at line 1564, in  sletifndk.c.

    The problem is that from->sa_family is 0. I attached the example again with some updates. psdkHelloWorld2.zip

  • Wei,

    What is the value in of from->sa_family? Just for validation, the assert I'm looking at is

    assert(from->sa_family == AF_INET);
    

    Why are you opening and closing of the fdSession so much in the task? Note: unfortunately I don't have access to a board right now (I'm travelling) so I cannot run the example. You have several tasks. Can you let me know which one has the recvfrom failure?

    Todd

  • value is 0, 

    i thought the open and close was causing the error. but i tried with only openFdSesssion once at the beginning and close at the end. Same result.

    and just FYI, the "recv" function work, but not the recvfrom funciton. I was able to get udp messages using the recv function. 

  • so turns out, it has something to do with the non blocking flag (MSG_DONTWAIT) or (SO_NONBLOCKING). It doesn't seem to like that i'm trying to make a non-blocking call. 

  • so i think the assert is triggering unnecessarily,

    "recvfrom" calls SockRecv (via NDK_recvfrom) in ndk_3_60_00_13/packages/ti/ndk/sock/sock.c.  function "SockRecv" doesnt write into the struct sockaddr when MSG_DONTWAIT is set and there is no message waiting in the network queue. See line 1515 in sock.c. There causes the assert to be triggered whenever MSG_DONTWAIT is set and there is nothing to get from the network queue. See below for the calltrack to SockRecv.

    so the call trace from the recvfrom is 

    recvfrom calls NDK_recvfrom(ndk_3_60_00_13/packages/ti/ndk/stack/fdt/socket.c),

    NDK_recv calls SockRecv,

    so i think we might be able to solve the problem by adding a check to the assert in slnetifndk.c,

    if(!(flags&MSG_DONTWAIT))
    {
      assert(from->sa_family==AF_INET);
    
    }

  • Wei,

    I looked into this and this is indeed a bug in the NDK. I filed a bug (NDK-469: SlNetIfNDK_recvFrom will trigger an incorrect assert if MSG_DONTWAIT is passed in the flags) to get this resolved. 

    To unblock you for now, I'd suggest modifying your code to call 

    remaddr->sa_family = AF_INET;
    int rxLength = recvfrom(skt,rxBuf, rxBufSize,MSG_DONTWAIT, (struct sockaddr *)&remaddr, (socklen_t*)&addrLen);

     recvfrom won't clear your sockaddr struct, so this extra bit of code will allow you to get past the assert. 

    Regards,

    Dalton

  • ok, thanks. 

    in addtion, the ndk module "slnetifndk.ae66" shipped with the psdk is built to link to "mbedtls" library by default. and TI doesn't ship mbedtls lib. This resulted in the build failure if one tries to use slnetifndk.ae66 for 6678. The solution to this problem was to rebuild ndk without "mbedtls". 

  • Wei,

    Thanks. We're working with the PDK team to include a BSD example in the SDK in the future to make this much easier. Thanks for your patience with this threads. 

    Todd