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.

CC3220SF: Calling clock_settime is messing up a simplelink (connection with MQTT lib)

Part Number: CC3220SF

In my scenario, I am connected to a wifi in STA mode. I am calling the NTP server and reading time. 

Setting the device time with sl_DeviceSet(SL_DEVICE_GENERAL, SL_DEVICE_GENERAL_DATE_TIME, sizeof(SlDateTime_t), (unsigned char *)(&objL_datetime)); works like a charm, no issues there. After that, I can connect to mqtt server using mqtt lib and I everything is working as expected .. 

But, if I call clock_settime(CLOCK_REALTIME, &objL_timespec) in just after(before the sl_DeviceSet, the MQTT connection is not working. I am getting SL_API_ABORTED (-2005) from MQTTClient_connect().I was even trying to call sl_Stop(200) and sl_Start(0,0,0) to restart simplelink ... but the issue is not disappearing

Any idea. how this could be connected and how to fix it? (commenting out clock_settime will make it work again, but thats not the prefered solution) 

Thanks, Igor 

  • Hi Igor,

    Just to make sure, if you don't call clock_settime will the mqtt connection still not work? I want to make sure it's related specifically to clock_settime.

    Jesu

  • No, if I dont call clock_settime , MQTT works well 

  • Hi Igor, 

    clock_settime also tries to set the RTC but from the RTOS. This might be causing a conflict with the DeviceSet call. May I ask why you're trying to use both?

    Jesu

  • Hello Jesu,

    I need to set the NWP time (DeviceSet call) for ssl connection. But I would like to have available time in the clock_gettime() function as well. I tried to check the clock_gettime() after setting the NWP time and it seems they are completely independent. 

    It seems that they are doing a bit different thing ... clock_settime doesnt seems to set the RTC (see clock.c from ti posix), it seems to be "only" remembering the real time offset 

    /*
     *  ======== clock_settime ========
     */
    int clock_settime(clockid_t clock_id, const struct timespec *ts)
    {
        uintptr_t       key;
    
        if (clock_id != CLOCK_REALTIME) {
            errno = EINVAL;
            return (-1);
        }
    
        if ((ts->tv_nsec < 0) || (ts->tv_nsec >= 1000000000)) {
            errno = EINVAL;
            return (-1);
        }
    
        key = HwiP_disable();
    
        _clock_gettimeMono(&refTS);
        setTS = *ts;
    
        HwiP_restore(key);
    
        return (0);
    }

    It seems, that clock_gettime is used in the TI MQTT library, but I dont expect this will cause the problem ..  I tried to check where else could be used the time from posix, but nothing what is looking suspicious to me :-(

  • Hi Igor,

    I find that if you call it after MQTT connects it works fine. Please note it is also used by MQTT_SendMsgToQueue in mqtt_client_app.c. I did not try to investigate too much but my guess is that since the MQTT library is using it in the background at start up there might be some conflict. Anyway, just use if after you get the CONNACK event and you should be good to go.

    Jesu

  • Hello Jesu, 

    it still doesnt look like a good solution. It seems that the clock is used for simplelink as well and the whole net connection gets crashed .. 

    I found maybe a "workaround", but someone from TI should see, if it is a real solution, or just a stupid fix which wll broke something else .. 

    in cc_pal.c I changed the function Semaphore_pend_handle() 

    from clock_gettime(CLOCK_REALTIME, &abstime); to clock_gettime(CLOCK_MONOTONIC, &abstime); 

    and in semaphore.c I changed function sem_timedwait()

    from if (_clock_abstime2ticks(CLOCK_REALTIME, abstime, &timeout) != 0) to if (_clock_abstime2ticks(CLOCK_MONOTONIC, abstime, &timeout) != 0)

    Can someone from TI explore this issue and check if this solution is a good way to fix that? After these changes I dont have any issues so far .. 

    Thanks, Igor 

  • Hi Igor,

    I don't suggest changing the source code. The way you're using sl_DeviceSet sets the RTC on the device. Using CLOCK_REALTIME with clock_settime does the same thing. I didn't realize this until now but if I'm not mistaken both calls accomplish the same thing. 

    Jesu

  • Hello Jesu,

    franky, I dont believe that sl_DeviceSet does the same thing as clock_settime(). At least from my experiments and observations.

    And also, when I opened a ti provided/posix/clock.c file, it looks to me that clock_settime(CLOCK_REALTIME..) is not setting the RTC in the end, it just remembers the "offset" from CLOCK_MONOTONIC clock. See the code from clock.c below (the code is already in this thread): 

    /*
     *  ======== clock_settime ========
     */
    int clock_settime(clockid_t clock_id, const struct timespec *ts)
    {
        uintptr_t       key;
    
        if (clock_id != CLOCK_REALTIME) {
            errno = EINVAL;
            return (-1);
        }
    
        if ((ts->tv_nsec < 0) || (ts->tv_nsec >= 1000000000)) {
            errno = EINVAL;
            return (-1);
        }
    
        key = HwiP_disable();
    
        _clock_gettimeMono(&refTS);
        setTS = *ts;
    
        HwiP_restore(key);
    
        return (0);
    }

    The another question should be, why the CLOCK_REALTIME clock is used in the semaphores instead of CLOCK_MONOTONIC, which makes more sense for me in these usecases.

    Igor 

  • Hi Igor,

    I believe REALTIME is used instead because typically MCUs enter low power mode when all tasks are blocked. Given the system clock is not running on low power mode but the RTC is, REALTIME is used instead.

    Also, what version of the SDK are you using? My version of clock_setttime is not the same as yours.

    /*
     *  ======== clock_settime ========
     */
    int clock_settime(clockid_t clock_id, const struct timespec *ts)
    {
    
        if (clock_id != CLOCK_REALTIME) {
            errno = EINVAL;
            return (-1);
        }
    
        if ((ts->tv_nsec < 0) || (ts->tv_nsec >= 1000000000)) {
            errno = EINVAL;
            return (-1);
        }
    
    #if BIOS_version < 0x67500
        Seconds_set(ts->tv_sec);
    #else
    {
        Seconds_Time its;
    
        its.secs = (UInt32)(ts->tv_sec);
        its.nsecs = (UInt32)(ts->tv_nsec);
        Seconds_setTime(&its);
    }
    #endif
    
        return (0);
    }

    Jesu

  • Hello Jesu, 
    we have currently integrated simplelink_cc32xx_sdk_3_20_00_06, but I checked the source code of simplelink_cc32xx_sdk_3_30_01_02 (I hope thats the latest one) and it seems to be the same as I have, even in this version (attached clock_settime from simplelink_cc32xx_sdk_3_30_01_02\source\ti\posix\freertos\).

    Igor 

  • Hi Igor,

    I did not realize you're using freertos. Looks like the freertos version of settime is different from tirtos version. I think you are right - freertos seems to be using monotonic instead of realtime. I wonder if you would get the same behavior using the TI-RTOS version of the example. Could you give it a try?

    Jesu

  • Sorry Jesu, 
    I would like to, but currently I dont have the oportunity to spend my time on changing RTOS in our project.

    Can you maybe give a try with freertos, as it is included in SDK as well? If you will face the same issue? 

    Thanks and have a nice weekend,
    Igor 

  • Hi Igor,

    I have looped in the TI-RTOS team to see if they could provide feedback here. Please wait for their response.

    Jesu

  • Hi Igor,

    We are trying to find the right engineer to look at this issue. In the meantime, can you summarize the symptoms of the failure once you call clock_settime, please? Also, would you be able to attach a small test case so that we may reproduce the issue? If you are uncomfortable posting here, we can send it through private forum channels.

    Best,

    Megan