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.

UDP CLIENTE SOCKET - NTP

Other Parts Discussed in Thread: SYSBIOS

Hi, I trying to connect my EK-TM4C129XL to an ntp server.

I'm using CCS v6, TIRTOS 2.00.02.36 and NDK 2.23.01.01.

I tried use 'sntp.h', but not success.

I can't create UDP socket that works correctly. The follow code send a packet, but don't receive anything. I tested with Wireshark on my PC.
#define UDPPORT 123
void ntpTest() { SOCKET lSocket; struct sockaddr_in sLocalAddr; fd_set readfds; int nbytes; int status; HANDLE hBuffer; char *buffer; char *hostname = (char *) "200.160.7.186"; unsigned char msg[48] = { 010, 0, 0, 0, 0, 0, 0, 0, 0 }; struct timeval { INT32 tv_sec; INT32 tv_usec; }; struct timeval time; time.tv_sec = 10; time.tv_usec = 0; memset((char *) &sLocalAddr, 0, sizeof(sLocalAddr)); sLocalAddr.sin_family = AF_INET; sLocalAddr.sin_len = sizeof(sLocalAddr); sLocalAddr.sin_addr.s_addr = inet_addr(hostname); sLocalAddr.sin_port = htons(UDPPORT); //fdOpenSession(TaskSelf()); lSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (lSocket < 0) { System_printf("udpHandler: socket failed\n"); Task_exit(); return; } if (setsockopt(lSocket, SOL_SOCKET, SO_RCVTIMEO, &time, sizeof(time)) < 0) { System_printf("udpHandler: setsockopt SO_RCVTIMEO failed\n"); fdClose(lSocket); return; } /* sendto( socket, pbuf: ponteiro para os dados a serem transmitidos size: tamanho dos dados flags, pName: ponteiro para o nome(endereço) dos destino, size: tamanho dos dados apontados por pName */ sendto(lSocket, (unsigned char *) msg, 48, 0, (struct sockaddr *) &sLocalAddr, sizeof(sLocalAddr)); //Clear (initialize) a file descriptor set FD_ZERO(&readfds); //Add a file descriptor to a file descriptor set FD_SET(lSocket, &readfds); /* Esta funcao permite que a tarefa de instruir a pilha de esperar por qualquer um de varios eventos a ocorrer e para acordar o processo somente quando um dos mais desses eventos ocorre ou quando uma determinada quantidade de tempo ja passou Parametros: maxfd: ignorado readset: Conjunto de descritores de arquivos para verificar se ha leitura writeset: Conjunto de descritores de arquivos para verificar se ha escrita exceptset: Conjunto de descritores de arquivos para verificar condicoes excepcionais timeout: ponteiro para uma estrutura de timeout The definition of the timeval structure is: struct timeval { INT32 tv_sec; INT32 tv_usec; }; *translate.google.com */ if (fdSelect(0, &readfds, NULL, NULL, NULL) != 1) { //network Erros errosRede(fdError()); } nbytes = recvncfrom(lSocket, (void **) &buffer, MSG_DONTWAIT, (struct sockaddr *) &sLocalAddr, (int *) sizeof(sLocalAddr), &hBuffer); if (nbytes >= 0) { /* print the data recv */ printf("Receivied data: %s\n", buffer); recvncfree(hBuffer); } else { status = fdError(); errosRede(status); if (status != EWOULDBLOCK) { System_printf( "udpHandler: recvfrom failed: returned: %d, error: %d\n", nbytes, status); fdClose(lSocket); } } if (lSocket) { fdClose(lSocket); } //fdCloseSession(TaskSelf()); }

Someone can help me?

Tiago

  • Hello Tiago

    Moving it to TI-RTOS Forum

    Regards
    Amit
  • Are you saying that the code never returns from the recvncfrom() call?

    Is there something preventing you from using the latest TI-RTOS and NDK products (just to rule out any known and fixed bugs)?

    Alan
  • Hi, now i can't use the latest TI-RTOS and NDK products because some parts don't work (I2C, etc). See our code here github.com/.../ProjetoEstufa, whitout ntp tests, init is on /TAREFAS/initNectar.c.

    Yes, the code not returns from the recvncfrom() call, and when return, the status is 35 (EWOULDBLOCK)

    My socket is correct?

    Tiago
  • Hi Tiago,

    What is the problem you are having with the SNTP client that's built into the NDK?  You shouldn't need to create any UDP sockets to communicate with the NTP server.  The NDK's SNTP client module will create and manage the UDP socket and NTP communication for you.

    Have you seen the SNTP client documentation?  The documentation contains example code that demonstrates how to use SNTP client in your application.

    You can find the documentation linked in the NDK release notes (see the screen shot below).


    Regarding your code above, are you sure that the content of "msg" is correct?  The NTP server may be dropping your UDP packet, which could explain why your recvncfrom is never receiving anything back.

    I highly recommend that you use the SNTP client that comes with NDK instead of trying to recreate this work yourself.

    Steve

    P.S. The SNTP client that's available in the version of the NDK that you have is a beta version.  I just want you to be aware that there will be some minor API signature changes to the SNTP client module soon.  In case you need to move to a newer version of the NDK at some point, you should be aware of this.

  • Hi Steven, before continue, I will be porting my code to the last version of TI-RTOS and NDK. If i can't fix the issue, I back here. Thank you!
  • Hello, I migrated my project to new RTOS.
    It's very simple opening a soket now :)
    but...
    Which library I need add for use "inet_addr()"?
    I did the following:

    Properties > Build > ARM Compiler > Include Options > Add dir to
    "${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}/products/ndk_2_24_02_31/packages/ti/ndk/inc/bsd"

    after:
    /* NDK BSD support */
    #include <sys/socket.h>

    But: warning #225-D

    Tiago
  • Hi Tiago,

    So you are using the SNTP client now?  Instead of trying to create your own UDP socket? :)

    Tiago Possato5 said:
    But: warning #225-D

    What is the warning?  I think you missed the second part of the warning message. Is this warning stating that inet_addr is being declared implicitly?

    inet_addr() is in the nettools library.  But, you should be getting this library linked into your application automatically if you are using the NDK in your configuration (*.cfg) file (i.e. if you have "xdc.useModule('ti.ndk.config.Global')" in the configuration file.

    I think you can get around this by adding a declaration for inet_addr() in the file that you're trying to call it from.  Like this:

        extern unsigned int inet_addr(const char *str);

    Alternatively, you could try using the inet_pton() API.

    Steve

  • Hi, I'm in the fight here, but i'm losing :)

    see my code:

    #include <string.h>
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/drivers/GPIO.h>
    
    /* Example/Board Header file */
    #include "Board.h"
    
    /* NDK BSD support */
    #include <ti/ndk/inc/netmain.h>
    #include <ti/ndk/inc/_stack.h>
    
    #include <ti/ndk/nettools/sntp/sntp.h>
    
    #include <time.h>
    extern unsigned int inet_addr(const char *str);
    
    //Simulation
    uint32_t h = 1434752826;
    
    uint32_t get(void) {
    	return h;
    }
    
    void set(uint32_t newtime) {
    	h = newtime;
    }
    //End of simulation code
    
    Void taskNtp() {
    	System_printf("Initializing NTP\n");
    	System_flush();
    //	delay to get address
    	Task_sleep(5000);
    
    	SNTP_start(&get, &set, 0);
    
    	struct sockaddr_in ipv4addr;
    	struct sockaddr_in6 ipv6addr;
    	ipv4addr.sin_family = AF_INET;
    	ipv4addr.sin_port = htons(123);
    	ipv4addr.sin_addr.s_addr = inet_addr("200.160.0.8");
    	ipv6addr.sin6_family = AF_INET6;
    	ipv6addr.sin6_port = htons(123);
    	IPv6StringToIPAddress("2001:12ff::8", (IP6N *) &ipv6addr.sin6_addr);
    	ipv6addr.sin6_scope_id = 1;
    
    #define SIZE (sizeof(struct sockaddr_in) + sizeof(struct sockaddr_in6))
    	unsigned char ntpServers[SIZE];
    	int currPos = 0;
    	memcpy((ntpServers + currPos), &ipv4addr, sizeof(struct sockaddr_in));
    	currPos += sizeof(struct sockaddr_in);
    	memcpy((ntpServers + currPos), &ipv6addr, sizeof(struct sockaddr_in6));
    	currPos += sizeof(struct sockaddr_in6);
    
    	SNTP_setservers((struct sockaddr *) ntpServers, 2);
    }
    
    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);
    }

    And my error:

    Using MAC address in flash
    Starting the UDP 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
    Initializing NTP
    Network Added: If-1:172.16.31.22
    Service Status: DHCPC    : Enabled  : Running  : 017
    00005.003 syncTime: Error: socket create/init failed (46)
    
    ti.sysbios.family.arm.m3.Hwi: line 1087: E_hardFault: FORCED
    ti.sysbios.family.arm.m3.Hwi: line 1164: E_busFault: PRECISERR: Immediate Bus Fault, exact addr known, address: ffffffff
    Exception occurred in background thread at PC = 0x00013376.
    Core 0: Exception occurred in ThreadType_Task.
    Task name: {unknown-instance-name}, handle: 0x200004c8.
    Task stack base: 0x20000518.
    Task stack size: 0x500.
    R0 = 0xffffffff  R8  = 0xffffffff
    R1 = 0x00000001  R9  = 0xffffffff
    R2 = 0x00000000  R10 = 0xffffffff
    R3 = 0x200008d4  R11 = 0xffffffff
    R4 = 0xffffffff  R12 = 0x00000000
    R5 = 0xffffffff  SP(R13) = 0x200008f8
    R6 = 0xffffffff  LR(R14) = 0x00019be3
    R7 = 0xffffffff  PC(R15) = 0x00013376
    PSR = 0xa1000000
    ICSR = 0x00423803
    MMFSR = 0x00
    BFSR = 0x82
    UFSR = 0x0000
    HFSR = 0x40000000
    DFSR = 0x0000000b
    MMAR = 0xffffffff
    BFAR = 0xffffffff
    AFSR = 0x00000000
    Terminating execution...

    I can't understand the use of functions

    uint32_t (*GetTimeFxn)(void);
    void (*SetTimeFxn)(uint32_t newtime);

    In my project, i will use an RTC, like is written on sntp.h File Reference

    Tiago

  • Tiago,

    00005.003 syncTime: Error: socket create/init failed (46)

    This is happening because there is effectively a race condition.  With the SNTP_start() and SNTP_setservers calls in a Task, the code is running before the network stack has initialized and or obtained its IP address.  If the network had initialized and obtained the IP address prior to SNTP_start()/setservers() calls, I believe you wouldn't have seen this error.

    There are a couple of ways to fix this:

    1. The simplest way, but least precise method is to add a call to Task_sleep() to the beginning of taskNtp().  Maybe sleep for 1 or 2 seconds, which should buy you enough time for the network stack to initialize and obtain an IP address from DHCP.

    2. Move the content of taskNtp() into a (non Task) hook function and assign it to the NDK "network IP address hook".  This hook is called by the NDK whenever an IP address is added (or removed, which is important) to or from the system.

    You know that the stack has been initialized at this point (at least the IPv4 part of the stack) because this hook function is called after the IP address has been obtained from the DHCP server.

    To do this, you need to do the following:

    a. In the *.cfg file, set the NDK's network IP address hook:

    b. define the hook function, basically just reusing the same code you wrote in ntpTask():

    tiagoStackInitHook(unsigned int ipAddr, unsigned int ifId, unsigned int fAdd)
    {
        /* only perform inititalization when IP address is added */
        if (fAdd) {
            /* copy content of ntpTask() here to perform SNTP inititalization */
        else {
            /* if IP address is being removed, assume network stack is being shutdown or rebooted */
            SNTP_stop();
        }
    }

    I can't understand the use of functions

    uint32_t (*GetTimeFxn)(void);
    void (*SetTimeFxn)(uint32_t newtime);

    If you will use an actual real time clock in hardware, these functions should be used to set and get the time to/from the actual RTC.

    So, you should implement your functions to be something like:

    uint32_t get(void) {
        uint32_t h;
        h = <call the appropriate API to get the current time from the RTC>
        return h;
    }
    
    void set(uint32_t newtime) {
        /* let 'setRtcTime' be an API that sets the time of the actual RTC> */
        setRtcTime(newtime);
    }

    For "practice," you could use the MYTIME module that's in the NDK (next to SNTP).  It was created as an easy way to track the time for systems without an actual RTC, or for early development just to ease the process of getting SNTP up and running without having to worry about the RTC and APIs required to configure the hardware.

    Steve

  • Tiago Possato5 said:
    ti.sysbios.family.arm.m3.Hwi: line 1087: E_hardFault: FORCED ti.sysbios.family.arm.m3.Hwi: line 1164: E_busFault: PRECISERR: Immediate Bus Fault, exact addr known, address: ffffffff Exception occurred in background thread at PC = 0x00013376. Core 0: Exception occurred in ThreadType_Task. Task name: {unknown-instance-name}, handle: 0x200004c8. Task stack base: 0x20000518. Task stack size: 0x500. R0 = 0xffffffff R8 = 0xffffffff R1 = 0x00000001 R9 = 0xffffffff R2 = 0x00000000 R10 = 0xffffffff R3 = 0x200008d4 R11 = 0xffffffff R4 = 0xffffffff R12 = 0x00000000 R5 = 0xffffffff SP(R13) = 0x200008f8 R6 = 0xffffffff LR(R14) = 0x00019be3 R7 = 0xffffffff PC(R15) = 0x00013376 PSR = 0xa1000000 ICSR = 0x00423803 MMFSR = 0x00 BFSR = 0x82 UFSR = 0x0000 HFSR = 0x40000000 DFSR = 0x0000000b MMAR = 0xffffffff BFAR = 0xffffffff AFSR = 0x00000000 Terminating execution...

    As for this, I didn't expect that the app should crash.  I'll have to see if I can reproduce this on my side.

    Steve