This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Modifications to the "wireless timer synchronization" example

Hello,

at the moment I am working on a project with a nRF52840DK as central and multiple nRF52DKs as peripherals. The code on the central is based on the "ble_app_uart_c" example and the code on the peripherals is based on the "ble_app_uart" example of the wireless timer sync demo. (This code is availabe here: https://github.com/nordic-auko/nRF5-ble-timesync-demo)

There is also a great blog post regarding the wireless timer sync: https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/wireless-timer-synchronization-among-nrf5-devices 

Of course, I had to made some modifications to the examples to integrate my application in the code. Audun, the author of the blog entry about this synchronization and a great engineer, already helped me a lot. But I have still some questions about my modifications and the consequences of them.

I made two modifcaitons to the wireless time sync code in total: 

Modification 1

On the central side I made on change in time_sync.c:

static void timers_capture(uint32_t * p_sync_timer_val, uint32_t * p_count_timer_val, uint32_t * p_peer_counter)
{
    ...
    if (nrf_atomic_flag_set_fetch(&m_timestamp_capture_flag) != 0)
    {
        // Not thread-safe
        // APP_ERROR_CHECK_BOOL(false); // I had to comment out this line!
    }
    ...
}

I had to comment out this error check line.

Question 1: What does "not thread-safe" mean in this case?

Question 2: Are there any side effects, which I sould be aware of?

Modification 2

The second modification is on the peripheral in main.c:

static void ts_evt_callback(const ts_evt_t* evt)
{
    ...
    switch (evt->type)
    {
        ...
        case TS_EVT_TRIGGERED:
        if (m_gpio_trigger_enabled)
        {
            uint32_t tick_target;
    
            tick_target = evt->params.triggered.tick_target + 2;
    
            uint32_t err_code = ts_set_trigger(tick_target, nrf_gpiote_task_addr_get(NRF_GPIOTE_TASKS_OUT_3));
            //APP_ERROR_CHECK(err_code); // I had to comment out this line!
        }
        else
        {
            // Ensure pin is low when triggering is stopped
            nrf_gpiote_task_set(NRF_GPIOTE_TASKS_CLR_3);
        }
        break;
        ...
    }
}

I had to comment out this error check line. I do not use the default toggeling GPIOs or any other GPIOs on the peripheral side.

Question 3: Is it okey to comment this out, when I am not using any GPIOs?

Question 4: Are there any side effects, which I sould be aware of?

General:

With this changes the timer synchronization works as it should. 

I am only using the get ticks function of the timer sync:

ts_timestamp_get_ticks_u64()

The timer sync libary gets enabled on the peripherals every 10 sec for 1 sec for power saving purposes. This works also fine.

------------------------------------------------------------------------------

Any kind of feedback is always appreciated. Thank you very much in advance.

Best regards,

Michael

Parents
  • Hi,

    Question 1: What does "not thread-safe" mean in this case?

    It means that you cannot make calls here from different threads or interrupt priorities as that can cause unexpected behavior, this is using a physical resource after all. So the check that is failing is intended to fail when it is detected that a second thread is using this function at the same time. Think of m_timestamp_capture_flag as a semaphore, and this code checks that the semaphore is not allready taken, and if it is, it is an error.

    Question 2: Are there any side effects, which I sould be aware of?

    There is a lot happening in the timers_capture() function, and depending on where the first one is when the second call happens a lot of things can happen. The point is that this *will* cause problems, and is why the check is there. You just need to make sure to avoid this problem. In practice that will be by either calling it form only one place or always calling it from the same interrupt priority.

    Question 3: Is it okey to comment this out, when I am not using any GPIOs?

    Blindly ignorring errors is never a good idea. Have you debugged in the implementation of ts_set_trigger() to see exactly why it fails in this case? And is that something you can explain and know is not a problem? If so, you can specifically ignore that error code. But never ignore an error without knowing it is not a problem.

    Question 4: Are there any side effects, which I sould be aware of?

    I have no way to know. I do not know what happens in your application. But again, just ignoring error codes and hoping for the best is a very bad idea and a great way to cause problems for yourself further down the line.

    Einar

Reply
  • Hi,

    Question 1: What does "not thread-safe" mean in this case?

    It means that you cannot make calls here from different threads or interrupt priorities as that can cause unexpected behavior, this is using a physical resource after all. So the check that is failing is intended to fail when it is detected that a second thread is using this function at the same time. Think of m_timestamp_capture_flag as a semaphore, and this code checks that the semaphore is not allready taken, and if it is, it is an error.

    Question 2: Are there any side effects, which I sould be aware of?

    There is a lot happening in the timers_capture() function, and depending on where the first one is when the second call happens a lot of things can happen. The point is that this *will* cause problems, and is why the check is there. You just need to make sure to avoid this problem. In practice that will be by either calling it form only one place or always calling it from the same interrupt priority.

    Question 3: Is it okey to comment this out, when I am not using any GPIOs?

    Blindly ignorring errors is never a good idea. Have you debugged in the implementation of ts_set_trigger() to see exactly why it fails in this case? And is that something you can explain and know is not a problem? If so, you can specifically ignore that error code. But never ignore an error without knowing it is not a problem.

    Question 4: Are there any side effects, which I sould be aware of?

    I have no way to know. I do not know what happens in your application. But again, just ignoring error codes and hoping for the best is a very bad idea and a great way to cause problems for yourself further down the line.

    Einar

Children
Related