Adapt to kernel 5.6+ time API changes

Building EtherCAT master debug ring on Linux v6.6 Phytium kernel
failed with:
- incomplete type 'struct timeval'
- struct timespec64 has no tv_usec member
- implicit function declaration do_gettimeofday

Linux 5.6 upstream deprecated timeval/do_gettimeofday and migrated
fully to timespec64.

Conditional compile based on LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0):
- Header: include linux/version.h in device.h for version judgment
- Data structure: ec_debug_frame_t / ec_device use timespec64 for new
  kernel, timeval for legacy
- Time subtraction: custom timerspec64_sub to replace timersub on new
  kernel
- Timestamp fetch: ktime_get_real_ts64 (5.6+), do_gettimeofday (legacy)
- Member initialization: tv_nsec / tv_usec assigned conditionally
- Log printing: divide tv_nsec by 1000 to restore us display, unified
  log format

Signed-off-by: powertree <powertree@163.com>
This commit is contained in:
powertree
2026-07-29 16:18:11 +08:00
committed by powertree
parent 2f7f884f1c
commit c4608c8ce0
2 changed files with 43 additions and 0 deletions
+34
View File
@@ -35,6 +35,7 @@
#include "master.h"
#ifdef EC_DEBUG_RING
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
#define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
@@ -45,6 +46,7 @@
} \
} while (0)
#endif
#endif
/****************************************************************************/
@@ -85,7 +87,11 @@ int ec_device_init(
#endif
#ifdef EC_DEBUG_RING
device->timeval_poll.tv_sec = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
device->timeval_poll.tv_nsec = 0;
#else
device->timeval_poll.tv_usec = 0;
#endif
#endif
device->jiffies_poll = 0;
@@ -96,7 +102,11 @@ int ec_device_init(
ec_debug_frame_t *df = &device->debug_frames[i];
df->dir = TX;
df->t.tv_sec = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
df->t.tv_nsec = 0;
#else
df->t.tv_usec = 0;
#endif
memset(df->data, 0, EC_MAX_DATA_SIZE);
df->data_size = 0;
}
@@ -397,7 +407,11 @@ void ec_device_debug_ring_append(
df->dir = dir;
if (dir == TX) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
ktime_get_real_ts64(&df->t);
#else
do_gettimeofday(&df->t);
#endif
}
else {
df->t = device->timeval_poll;
@@ -422,7 +436,11 @@ void ec_device_debug_ring_print(
int i;
unsigned int ring_index;
const ec_debug_frame_t *df;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct timespec64 t0, diff;
#else
struct timeval t0, diff;
#endif
// calculate index of the newest frame in the ring to get its time
ring_index = (device->debug_frame_index + EC_DEBUG_RING_SIZE - 1)
@@ -437,13 +455,25 @@ void ec_device_debug_ring_print(
for (i = 0; i < device->debug_frame_count; i++) {
df = &device->debug_frames[ring_index];
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
diff = timespec64_sub(t0, df->t);
#else
timersub(&t0, &df->t, &diff);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
EC_MASTER_DBG(device->master, 1, "Frame %u, dt=%u.%06u s, %s:\n",
i + 1 - device->debug_frame_count,
(unsigned int) diff.tv_sec,
(unsigned int) (diff.tv_nsec / 1000),
(df->dir == TX) ? "TX" : "RX");
#else
EC_MASTER_DBG(device->master, 1, "Frame %u, dt=%u.%06u s, %s:\n",
i + 1 - device->debug_frame_count,
(unsigned int) diff.tv_sec,
(unsigned int) diff.tv_usec,
(df->dir == TX) ? "TX" : "RX");
#endif
ec_print_data(df->data, df->data_size);
ring_index++;
@@ -469,7 +499,11 @@ void ec_device_poll(
#endif
device->jiffies_poll = jiffies;
#ifdef EC_DEBUG_RING
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
ktime_get_real_ts64(&device->timeval_poll);
#else
do_gettimeofday(&device->timeval_poll);
#endif
#endif
device->poll(device->dev);
}
+9
View File
@@ -47,6 +47,7 @@
#endif
#ifdef EC_DEBUG_RING
#include <linux/version.h>
#define EC_DEBUG_RING_SIZE 10
typedef enum {
@@ -55,7 +56,11 @@ typedef enum {
typedef struct {
ec_debug_frame_dir_t dir;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct timespec64 t;
#else
struct timeval t;
#endif
uint8_t data[EC_MAX_DATA_SIZE];
unsigned int data_size;
} ec_debug_frame_t;
@@ -84,7 +89,11 @@ struct ec_device
cycles_t cycles_poll; /**< cycles of last poll */
#endif
#ifdef EC_DEBUG_RING
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0)
struct timespec64 timeval_poll;
#else
struct timeval timeval_poll;
#endif
#endif
unsigned long jiffies_poll; /**< jiffies of last poll */