Эх сурвалжийг харах

feat: add time diff monitor

Signed-off-by: sakumisu <1203593632@qq.com>
sakumisu 3 сар өмнө
parent
commit
c72df81d7a
3 өөрчлөгдсөн 87 нэмэгдсэн , 16 устгасан
  1. 15 5
      include/ec_master.h
  2. 43 10
      src/ec_cmd.c
  3. 29 1
      src/ec_master.c

+ 15 - 5
include/ec_master.h

@@ -85,8 +85,8 @@ typedef struct ec_master {
     ec_netdev_stats_t netdev_stats;
     ec_netdev_stats_t netdev_stats;
     ec_stats_t stats;
     ec_stats_t stats;
     ec_master_phase_t phase;
     ec_master_phase_t phase;
-    bool active;        /**< Master is started. */
-    bool scan_done;     /**< Slave scan is done. */
+    bool active;    /**< Master is started. */
+    bool scan_done; /**< Slave scan is done. */
 
 
     ec_datagram_t main_datagram; /**< Main datagram for slave scan & state change & config & sii */
     ec_datagram_t main_datagram; /**< Main datagram for slave scan & state change & config & sii */
 
 
@@ -95,9 +95,19 @@ typedef struct ec_master {
     ec_dlist_t cyclic_datagram_queue; /**< Queue of cyclic datagrams(internal use)*/
     ec_dlist_t cyclic_datagram_queue; /**< Queue of cyclic datagrams(internal use)*/
     uint8_t datagram_index;
     uint8_t datagram_index;
 
 
-    ec_slave_t *dc_ref_clock;           /**< DC reference clock slave. */
-    ec_datagram_t dc_ref_sync_datagram; /**< Datagram used for synchronizing the reference clock to the master clock. */
-    ec_datagram_t dc_all_sync_datagram; /**< Datagram used for synchronizing all slaves to the master clock. */
+    ec_slave_t *dc_ref_clock;                /**< DC reference clock slave. */
+    ec_datagram_t dc_ref_sync_datagram;      /**< Datagram used for synchronizing the reference clock to the master clock. */
+    ec_datagram_t dc_all_sync_datagram;      /**< Datagram used for synchronizing all slaves to the master clock. */
+    ec_datagram_t systime_diff_mon_datagram; /**< Datagram used for reading the system time difference between master and reference clock. */
+
+    uint32_t min_systime_diff;
+    uint32_t max_systime_diff;
+    uint32_t curr_systime_diff;
+    uint32_t systime_diff_count;
+    uint64_t total_systime_diff;
+    bool systime_diff_enable;
+
+    uint64_t interval;
 
 
     ec_slave_t *slaves;
     ec_slave_t *slaves;
     uint32_t slave_count;
     uint32_t slave_count;

+ 43 - 10
src/ec_cmd.c

@@ -116,6 +116,9 @@ static void ec_master_cmd_show_help(void)
     EC_LOG_RAW("  perf -s <time>                                 Start performance test\n");
     EC_LOG_RAW("  perf -s <time>                                 Start performance test\n");
     EC_LOG_RAW("  perf -v                                        Show performance statistics\n");
     EC_LOG_RAW("  perf -v                                        Show performance statistics\n");
 #endif
 #endif
+    EC_LOG_RAW("  timediff -s                                    Enable system time diff monitor\n");
+    EC_LOG_RAW("  timediff -d                                    Disable system time diff monitor\n");
+    EC_LOG_RAW("  timediff -v                                    Show system time diff statistics\n");
     EC_LOG_RAW("  help                                           Show this help\n\n");
     EC_LOG_RAW("  help                                           Show this help\n\n");
 }
 }
 
 
@@ -677,16 +680,6 @@ int ethercat(int argc, const char **argv)
     } else if (strcmp(argv[1], "master") == 0) {
     } else if (strcmp(argv[1], "master") == 0) {
         ec_master_cmd_master(global_cmd_master);
         ec_master_cmd_master(global_cmd_master);
         return 0;
         return 0;
-#ifdef CONFIG_EC_PERF_ENABLE
-    } else if (strcmp(argv[1], "perf") == 0) {
-        if (argc >= 4 && strcmp(argv[2], "-s") == 0) {
-            ec_perf_init(&global_cmd_master->perf, atoi(argv[3]));
-            return 0;
-        } else if (argc >= 3 && strcmp(argv[2], "-v") == 0) {
-            ec_perf_print_statistics(&global_cmd_master->perf);
-            return 0;
-        }
-#endif
     } else if (strcmp(argv[1], "slaves") == 0) {
     } else if (strcmp(argv[1], "slaves") == 0) {
         // ethercat slaves
         // ethercat slaves
         if (argc == 2) {
         if (argc == 2) {
@@ -926,6 +919,46 @@ int ethercat(int argc, const char **argv)
             }
             }
             return 0;
             return 0;
         }
         }
+    } else if (argc >= 3 && strcmp(argv[1], "timediff") == 0) {
+        if (strcmp(argv[2], "-s") == 0) {
+            uintptr_t flags;
+
+            flags = ec_osal_enter_critical_section();
+            global_cmd_master->systime_diff_enable = true;
+            global_cmd_master->curr_systime_diff = 0;
+            global_cmd_master->min_systime_diff = 0xffffffff;
+            global_cmd_master->max_systime_diff = 0;
+            global_cmd_master->systime_diff_count = 0;
+            global_cmd_master->total_systime_diff = 0;
+            ec_osal_leave_critical_section(flags);
+
+        } else if (strcmp(argv[2], "-d") == 0) {
+            uintptr_t flags;
+
+            flags = ec_osal_enter_critical_section();
+            global_cmd_master->systime_diff_enable = false;
+            ec_osal_leave_critical_section(flags);
+        } else if (strcmp(argv[2], "-v") == 0) {
+            for (uint32_t i = 0; i < 10; i++) {
+                EC_LOG_RAW("System Time Diff curr = %d, min = %d, max = %d, avg = %d ns\n",
+                           global_cmd_master->curr_systime_diff,
+                           global_cmd_master->min_systime_diff,
+                           global_cmd_master->max_systime_diff,
+                           global_cmd_master->total_systime_diff / global_cmd_master->systime_diff_count);
+                ec_osal_msleep(1000);
+            }
+        }
+        return 0;
+#ifdef CONFIG_EC_PERF_ENABLE
+    } else if (strcmp(argv[1], "perf") == 0) {
+        if (argc >= 4 && strcmp(argv[2], "-s") == 0) {
+            ec_perf_init(&global_cmd_master->perf, atoi(argv[3]));
+            return 0;
+        } else if (argc >= 3 && strcmp(argv[2], "-v") == 0) {
+            ec_perf_print_statistics(&global_cmd_master->perf);
+            return 0;
+        }
+#endif
     } else {
     } else {
     }
     }
 
 

+ 29 - 1
src/ec_master.c

@@ -478,6 +478,9 @@ int ec_master_init(ec_master_t *master, uint8_t master_index)
     ec_datagram_init(&master->main_datagram, EC_MAX_DATA_SIZE);
     ec_datagram_init(&master->main_datagram, EC_MAX_DATA_SIZE);
     ec_datagram_init(&master->dc_ref_sync_datagram, 8);
     ec_datagram_init(&master->dc_ref_sync_datagram, 8);
     ec_datagram_init(&master->dc_all_sync_datagram, 8);
     ec_datagram_init(&master->dc_all_sync_datagram, 8);
+    ec_datagram_init(&master->systime_diff_mon_datagram, 4);
+
+    ec_datagram_brd(&master->systime_diff_mon_datagram, ESCREG_OF(ESCREG->SYS_TIME_DIFF), 4);
 
 
     master->scan_lock = ec_osal_mutex_create();
     master->scan_lock = ec_osal_mutex_create();
     if (!master->scan_lock) {
     if (!master->scan_lock) {
@@ -537,6 +540,8 @@ int ec_master_start(ec_master_t *master, uint32_t period_us)
     master->expected_working_counter = 0;
     master->expected_working_counter = 0;
     master->actual_pdo_size = 0;
     master->actual_pdo_size = 0;
     master->phase = EC_OPERATION;
     master->phase = EC_OPERATION;
+    master->interval = 0;
+    master->systime_diff_enable = false;
 
 
     for (uint32_t slave_idx = 0; slave_idx < master->slave_count; slave_idx++) {
     for (uint32_t slave_idx = 0; slave_idx < master->slave_count; slave_idx++) {
         slave = &master->slaves[slave_idx];
         slave = &master->slaves[slave_idx];
@@ -814,10 +819,31 @@ EC_FAST_CODE_SECTION static void ec_master_cyclic_process(void *arg)
         return;
         return;
     }
     }
 
 
+    ec_master_receive(master);
+
 #ifdef CONFIG_EC_PERF_ENABLE
 #ifdef CONFIG_EC_PERF_ENABLE
     ec_perf_polling(&master->perf);
     ec_perf_polling(&master->perf);
 #endif
 #endif
-    ec_master_receive(master);
+    if (master->systime_diff_enable) {
+        if (master->systime_diff_mon_datagram.state == EC_DATAGRAM_RECEIVED) {
+            master->curr_systime_diff = EC_READ_U32(master->systime_diff_mon_datagram.data) & 0x7fffffff;
+
+            if (master->curr_systime_diff < master->min_systime_diff) {
+                master->min_systime_diff = master->curr_systime_diff;
+            }
+
+            if (master->curr_systime_diff > master->max_systime_diff) {
+                master->max_systime_diff = master->curr_systime_diff;
+            }
+            master->systime_diff_count++;
+            master->total_systime_diff += master->curr_systime_diff;
+        }
+
+        if ((master->interval % 10) == 0) {
+            ec_datagram_zero(&master->systime_diff_mon_datagram);
+            ec_master_queue_datagram(master, &master->systime_diff_mon_datagram);
+        }
+    }
 
 
     master->actual_working_counter = 0;
     master->actual_working_counter = 0;
     ec_dlist_for_each_entry_safe(cyclic_datagram, n, &master->cyclic_datagram_queue, queue)
     ec_dlist_for_each_entry_safe(cyclic_datagram, n, &master->cyclic_datagram_queue, queue)
@@ -846,4 +872,6 @@ EC_FAST_CODE_SECTION static void ec_master_cyclic_process(void *arg)
     }
     }
 
 
     ec_master_send(master);
     ec_master_send(master);
+
+    master->interval++;
 }
 }