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.

MSP432E401Y: How to create a TCP Client with Freertos CSS

Part Number: MSP432E401Y

The  "tcpHandler" function within the "tcpEcho.c" source file from the example "tcpecho_MSP_EXP432E401Y_freertos_ccs"  implements a tcp server function which allows socket connections requested by other network devices.

I need to modifiy tcpHandler function to implement a tcp client function which is passed the IP address and port number of a network host runing a tcp server.

Does anyone have an example of a suitable tcp client function for the MSP432 running under Freertos please?

The exisitng tcpHandler function code is as follows: 

/*
* ======== tcpHandler ========
* Creates new Task to handle new TCP connections.
*/
void *tcpHandler(void *arg0)
{
pthread_t thread;
pthread_attr_t attrs;
struct sched_param priParam;
int retc;
int detachState;
int status;
int server = -1;
struct addrinfo hints;
struct addrinfo *res, *p;
struct sockaddr_in clientAddr;
int optval;
static int clientfd;
int optlen = sizeof(optval);
socklen_t addrlen = sizeof(clientAddr);
char portNumber[MAXPORTLEN];

fdOpenSession(TaskSelf());

Display_printf(display, 0, 0, "TCP Echo example started\n");

sprintf(portNumber, "%d", *(uint16_t *)arg0);

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

/* Obtain addresses suitable for binding to */
status = getaddrinfo(NULL, portNumber, &hints, &res);
if (status != 0) {
Display_printf(display, 0, 0, "tcpHandler: getaddrinfo() failed: %s\n",
gai_strerror(status));
goto shutdown;
}

/* Open a socket */
for (p = res; p != NULL; p = p->ai_next) {
server = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (server == -1) {
continue;
}

status = bind(server, p->ai_addr, p->ai_addrlen);
if (status != -1) {
break;
}

close(server);
}

if (server == -1) {
Display_printf(display, 0, 0, "tcpHandler: failed to open socket\n");
goto shutdown;
} else if (p == NULL) {
Display_printf(display, 0, 0, "tcpHandler: could not bind to socket: %d\n", status);
goto shutdown;
} else {
freeaddrinfo(res);
res = NULL;
}

status = listen(server, NUMTCPWORKERS);
if (status == -1) {
Display_printf(display, 0, 0, "tcpHandler: listen failed\n");
goto shutdown;
}

optval = 1;
status = setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
if (status == -1) {
Display_printf(display, 0, 0, "tcpHandler: setsockopt failed\n");
goto shutdown;
}

while ((clientfd =
accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1) {

Display_printf(display, 0, 0,
"tcpHandler: Creating thread clientfd = %x\n", clientfd);

/* Set priority and stack size attributes */
pthread_attr_init(&attrs);
priParam.sched_priority = 3;

detachState = PTHREAD_CREATE_DETACHED;
retc = pthread_attr_setdetachstate(&attrs, detachState);
if (retc != 0) {
Display_printf(display, 0, 0,
"tcpHandler: pthread_attr_setdetachstate() failed");
while (1);
}

pthread_attr_setschedparam(&attrs, &priParam);

retc |= pthread_attr_setstacksize(&attrs, 2048);
if (retc != 0) {
Display_printf(display, 0, 0,
"tcpHandler: pthread_attr_setstacksize() failed");
while (1);
}

retc = pthread_create(&thread, &attrs, tcpWorker, (void *)&clientfd);
if (retc != 0) {
Display_printf(display, 0, 0,
"tcpHandler: pthread_create() failed");
while (1);
}

/* addrlen is a value-result param, must reset for next accept call */
addrlen = sizeof(clientAddr);
}

Display_printf(display, 0, 0, "tcpHandler: accept failed.\n");

shutdown:
if (res) {
freeaddrinfo(res);
res = NULL;
}
if (server != -1) {
close(server);
}

fdCloseSession(TaskSelf());

return (NULL);
}

  • Hi,

      We don't have a MSP432E tcpecho client example for FreeRTOS. However, I find a client example for TI-RTOS NDK but it is for TM4C129 which is the same silicon as MSP432E. You can reference this code and adapt to FreeRTOS. 

    /*
     *    ======== tcpEchoClient.c ========
     *    Contains BSD sockets code.
     */
    
    #include <string.h>
    
    #include <xdc/std.h>
    #include <xdc/runtime/Error.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 TCPPACKETSIZE 256
    #define NUMTCPWORKERS 3
    
    extern int inet_addr(const char *str);
    
    /*
     * Define the IP address and the port number of the TCP server
     * that this client is connection to.
     * TODO: User must change this IP address when running in his network.
     */
    #define SERVER_IPADDR "192.168.254.92"
    #define SERVER_PORT 23
    
    /*
     *  ======== tcpWorker ========
     *  Task to handle data processing when data is received by client.
     */
    Void tcpWorker(UArg arg0, UArg arg1)
    {
        int  clientfd = (int)arg0;
        int  bytesRcvd;
        int  bytesSent;
        char buffer[TCPPACKETSIZE];
    
        System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);
    
        /*
         * Socket function recv() is used to receive incoming data to buffer
         * specified by pbuf. The same data is echoed back to the remote host
         * using send().
         */
        while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0)
        {
            bytesSent = send(clientfd, buffer, bytesRcvd, 0);
            if (bytesSent < 0 || bytesSent != bytesRcvd)
            {
                System_printf("Error: send failed.\n");
                break;
            }
        }
        System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
    
        close(clientfd);
    }
    /*
     *  ======== tcpHandler ========
     *  Manage client socket creation and new Task to handle received data processing
     */
    Void tcpHandler(UArg arg0, UArg arg1)
    {
        int                status;
        int                clientfd;
        struct sockaddr_in servAddr;
        Task_Handle        taskHandle;
        Task_Params        taskParams;
        Error_Block        eb;
        char msg[] = "Hello from TM4C1294XL Connected LaunchPad\n";
    
        /*
         * Create a TCP stream socket.
         */
        clientfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (clientfd < 0) {
            System_printf("tcpHandler: socket failed\n");
            close(clientfd);
        }
    
        /*
         * Setup the Server IP address and port
         */
        memset((char *) &servAddr, 0, sizeof(servAddr));
        servAddr.sin_family = AF_INET;
        servAddr.sin_port = htons(SERVER_PORT);
        servAddr.sin_addr.s_addr = inet_addr(SERVER_IPADDR);
    
        /*
         * Connect to the server
         */
        status = connect(clientfd, (struct sockaddr *) &servAddr, sizeof(servAddr));
    
        if (status < 0) {
            System_printf("Error: client connect failed. (%d)\n",fdError());
            close(clientfd);
        }
    
        /*
         * Send a greetings message to the server
         */
        send(clientfd, msg, strlen(msg), 0);
    
        /* Init the Error_Block */
        Error_init(&eb);
    
        /*
         * Initialize the defaults and set the parameters.
         * Create a new task for each connection to process the receiving data
         * from the remote host
         */
        Task_Params_init(&taskParams);
        taskParams.arg0 = (UArg)clientfd;
        taskParams.stackSize = 1280;
        taskHandle = Task_create((Task_FuncPtr)tcpWorker, &taskParams, &eb);
        if (taskHandle == NULL) {
            System_printf("Error: Failed to create new Task\n");
            close(clientfd);
        }
    
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initEMAC();
    
        System_printf("Starting the TCP Echo Client 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);
    }

  • Thanks very much Charles, that solved my issue.