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.

RTOS/TM4C129XNCZAD: inter-task communication via network localhost

Part Number: TM4C129XNCZAD

Tool/software: TI-RTOS

HI all , 

I would like write a program which include 2 task . one server task , another is client task .

Here is the task's function . 

client : send data to client via localhost UDP 

Server: echo the client task's data to client  via localhost.

But the problem comes : Server could get data from client  but client couldn't get the data from Server !! . 

Server code : 

void netOpenHook()
{
	hEchoUdp = DaemonNew( SOCK_DGRAM, 0, 7, dtask_udp_echo,
		                                 OS_TASKPRINORM, OS_TASKSTKNORM, 0, 1 );
}
int dtask_udp_echo( SOCKET s, UINT32 unused )
{

    struct sockaddr_in sin1;
    struct timeval     to;
    int                i,tmp;
    char               *pBuf;
    HANDLE             hBuffer;
    int             ret = 0;
    char        IPString[16];

    (void)unused;

    // Configure our socket timeout to be 3 seconds
    to.tv_sec  = 3;
    to.tv_usec = 0;
    setsockopt( s, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof( to ) );
    setsockopt( s, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof( to ) );

    for(;;)
    {
        tmp = sizeof( sin1 );
        i = (int)recvncfrom( s, (void **)&pBuf, 0,(struct sockaddr *)&sin1, &tmp, &hBuffer );

        NtIPN2Str (sin1.sin_addr.s_addr, IPString);
        System_printf("get data from   %s:%d\n",IPString,sin1.sin_port);

        // Spit any data back out
        if( i >= 0 )
        {


//        	DumpRouteTable();
            System_printf("[%d]%s send %d byte %s to TestConsole\n",Clock_getTicks(),Task_Handle_name(Task_self()),i,pBuf);
            ret = sendto( s, pBuf, i, 0,(struct sockaddr *)&sin1, sizeof(sin1) );




            recvncfree( hBuffer );
        }
        else
            break;
    }

    // Since the socket is still open, return "1"
    // (we need to leave UDP sockets open)
    return(1);
}

client code : 

DRV_RET  sendUDPpacket()
{

    DRV_RET             ret = 0;
    struct sockaddr_in  addr;
    char        IPString[16];
    SOCKET          s;
    char buf[]="hello world";
    HANDLE             hBuffer;
    int                i,tmp;
    char               *pBuf;
    fd_set readfds;
    struct timeval timeout;
    fdOpenSession(TaskSelf());
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(7);
    addr.sin_addr.s_addr=inet_addr(LOCAL_HOST);

    NtIPN2Str (addr.sin_addr.s_addr, IPString);
    System_printf("local ip = %s\n",IPString);
    s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
//

    ret = sendto(s, buf, strlen(buf), 0,(struct sockaddr *) &addr, sizeof(addr) );


    /* Wait for the reply */
    FD_ZERO(&readfds);
    FD_SET(s, &readfds);

    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;


    if (fdSelect(s , &readfds, NULL, NULL, &timeout) != 1) {
        System_printf( " timed out waiting for reply\n");
//        status = errno;
        return -1 ;
    }



    tmp = sizeof( addr );

    System_printf("[%d]%s recieve ready!\n",Clock_getTicks(),Task_Handle_name(Task_self()));
    i = (int)recvncfrom( s, (void **)&pBuf, 0,(struct sockaddr *)&addr, &tmp, &hBuffer );
    if (i >=0 )
    {
        System_printf("return string = %s\n",pBuf);
        recvncfree( hBuffer );
    }



    fdClose( s );
    fdCloseSession(TaskSelf());

    return ret;

}

Are there anything wrong in my client code ?

Brenden

  • Hi Brenden,

    I'll take a look at the code and get back to you. In the meantime, what TI-RTOS version are you using?

    Todd
  • my TIRTOS version :2.16.0.08

  • Hi Brenden,

    You need two different UDP ports. Here are two files you can use. Import UDP Echo and replace the two files. You see that the client is sending to 1000 and the receiving on 1001. The server is receiving on 1000 and sending on 1001.

    /*
     * Copyright (c) 2015, 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.
     */
    
    /*
     *    ======== udpEcho.c ========
     *    Contains BSD sockets code.
     */
    
    #include <string.h>
    
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/drivers/GPIO.h>
    
    /* NDK BSD support */
    #include <sys/socket.h>
    
    /* Example/Board Header file */
    #include "Board.h"
    
    #define UDPPACKETSIZE 256
    
    Void echoFxnClient(UArg arg0, UArg arg1)
    {
        int                bytesRcvd;
        int                bytesSent;
        int                status;
        int                client;
        struct sockaddr_in localAddr;
        struct sockaddr_in serverAddr;
        socklen_t          addrlen;
        char               buffer[UDPPACKETSIZE];
        int                i;
    
        for (i = 0; i < UDPPACKETSIZE; i++) {
            buffer[i] = i;
        }
    
        Task_sleep(10000);
    
        client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (client == -1) {
            System_abort("Error: socket not created.\n");
        }
    
        memset(&serverAddr, 0, sizeof(serverAddr));
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_addr.s_addr = htonl(127<<24 | 1);
        serverAddr.sin_port = htons(arg0);
    
        addrlen = sizeof(serverAddr);
    
        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        localAddr.sin_port = htons(arg0 + 1);
    
       status = bind(client, (struct sockaddr *)&localAddr, sizeof(localAddr));
       if (status == -1) {
           System_abort("Error: echoFxnClient bind failed.\n");
       }
    
        bytesSent = sendto(client, buffer, UDPPACKETSIZE, 0,
                           (struct sockaddr *)&serverAddr, addrlen);
        if (bytesSent <= 0) {
            System_abort("Error: sendto failed\n");
        }
    
        bytesRcvd = recvfrom(client, buffer, UDPPACKETSIZE, 0,
                            (struct sockaddr *)&serverAddr, &addrlen);
    
        if (bytesRcvd <= 0) {
            System_abort("Error: sendto failed\n");
        }
    }
    
    /*
     *  ======== echoFxn ========
     *  Echoes UDP messages.
     *
     */
    Void echoFxnServer(UArg arg0, UArg arg1)
    {
        int                bytesRcvd;
        int                bytesSent;
        int                status;
        int                server;
        fd_set             readSet;
        struct sockaddr_in localAddr;
        struct sockaddr_in clientAddr;
        socklen_t          addrlen;
        char               buffer[UDPPACKETSIZE];
    
        server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (server == -1) {
            System_printf("Error: socket not created.\n");
            goto shutdown;
        }
    
        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        localAddr.sin_port = htons(arg0);
    
        status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
        if (status == -1) {
            System_printf("Error: bind failed.\n");
            goto shutdown;
        }
    
        do {
            /*
             *  readSet and addrlen are value-result arguments, which must be reset
             *  in between each select() and recvfrom() call
             */
            FD_ZERO(&readSet);
            FD_SET(server, &readSet);
            addrlen = sizeof(clientAddr);
    
            /* Wait forever for the reply */
            status = select(server + 1, &readSet, NULL, NULL, NULL);
            if (status > 0) {
                if (FD_ISSET(server, &readSet)) {
                    bytesRcvd = recvfrom(server, buffer, UDPPACKETSIZE, 0,
                            (struct sockaddr *)&clientAddr, &addrlen);
    
                    buffer[0] = buffer[0] + 3;
                    if (bytesRcvd > 0) {
                        bytesSent = sendto(server, buffer, bytesRcvd, 0,
                                (struct sockaddr *)&clientAddr, addrlen);
                        if (bytesSent < 0 || bytesSent != bytesRcvd) {
                            System_printf("Error: sendto failed.\n");
                            goto shutdown;
                        }
                    }
                }
            }
        } while (status > 0);
    
    shutdown:
        if (server > 0) {
            close(server);
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initEMAC();
    
        /* Turn on user LED */
        GPIO_write(Board_LED0, Board_LED_ON);
    
        System_printf("Starting the UDP Echo example\nSystem provider is set to "
                      "SysMin. Halt the target to view any SysMin contents in"
                      " ROV.\n");
        /* SysMin will only print to the console when you call flush or exit */
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    /*
     * Copyright (c) 2015, 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.
     */
    
    /*
     *    ======== udpEchoHooks.c ========
     *    Contains non-BSD sockets code (NDK Network Open Hook)
     */
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    #define UDPPORT 1000
    
    /* Prototypes */
    Void echoFxnServer(UArg arg0, UArg arg1);
    Void echoFxnClient(UArg arg0, UArg arg1);
    
    /*
     *  ======== netOpenHook ========
     *  NDK network open hook used to initialize IPv6
     */
    void netOpenHook()
    {
        Task_Handle taskHandle;
        Task_Params taskParams;
        Error_Block eb;
    
        /* Make sure Error_Block is initialized */
        Error_init(&eb);
    
        /*
         *  Create the Task that handles UDP "connections."
         *  arg0 will be the port that this task listens to.
         */
        Task_Params_init(&taskParams);
        taskParams.stackSize = 2048;
        taskParams.priority = 1;
        taskParams.arg0 = UDPPORT;
        taskHandle = Task_create((Task_FuncPtr)echoFxnServer, &taskParams, &eb);
        if (taskHandle == NULL) {
            System_abort("main: Failed to create echoFxnServer Task\n");
        }
        taskParams.arg0 = UDPPORT;
        taskHandle = Task_create((Task_FuncPtr)echoFxnClient, &taskParams, &eb);
        if (taskHandle == NULL) {
            System_abort("main: Failed to create echoFxnClient Task\n");
        }
    }
    

    Todd

    [not sure where the number in the hook file came from...copy/paste the contents into the udpEchoHooks.c file in the UDP Echo project]

  • Thanks for your reply , Todd .
    BTW, May I know NDK 2.16.08 include Intertask communication by init socket with AF_TASK ?
  • This thread talks about AF_TASK: e2e.ti.com/.../213163

    Todd