From 636c2b63bc936214a45e61e69f08cbca1d891457 Mon Sep 17 00:00:00 2001 From: Chinky Date: Fri, 12 Jan 2024 17:14:29 +0800 Subject: [PATCH] =?UTF-8?q?io=5Ftest=20=20=E8=BE=93=E5=87=BA=E6=B5=81?= =?UTF-8?q?=E6=B0=B4=E7=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 9 ++ osal/intime/osal.c | 2 +- test/linux/tj30_test/tj30_test.c | 155 ++++++++++++++++++++++--------- 3 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fcee2ea --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "files.associations": { + "time.h": "c", + "time_t.h": "c", + "struct_timeval.h": "c", + "features.h": "c", + "random": "c" + } +} \ No newline at end of file diff --git a/osal/intime/osal.c b/osal/intime/osal.c index 357edc1..cc7f9a1 100644 --- a/osal/intime/osal.c +++ b/osal/intime/osal.c @@ -54,7 +54,7 @@ boolean osal_timer_is_expired (osal_timert * self) stop_time.tv_usec = self->stop_time.usec; is_not_yet_expired = timercmp (¤t_time, &stop_time, <); - return is_not_yet_expired == FALSE; + return is_not_yet_expired == FALSE; // !is_not_yet_expired } int osal_usleep(uint32 usec) diff --git a/test/linux/tj30_test/tj30_test.c b/test/linux/tj30_test/tj30_test.c index 415bfb2..a09ef8f 100644 --- a/test/linux/tj30_test/tj30_test.c +++ b/test/linux/tj30_test/tj30_test.c @@ -16,16 +16,22 @@ #include #include #include -#include #include #include #include #include +#include #include "ethercat.h" #define NSEC_PER_SEC 1000000000 #define EC_TIMEOUTMON 500 +#define TEST_STEP_CYCLETIME (500 * 1000) // us +#define INPUT_CHECK_TIMEOUT (50 * 1000) // us +#define MAX_SLAVE 8 + +#define ROL_U16(a, n) ((uint16_t)((a) << (n) | (a) >> (16 - n))) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) struct sched_param schedp; char IOmap[4096]; @@ -45,14 +51,50 @@ volatile int wkc; boolean inOP; uint8 currentgroup = 0; -void redtest(char *ifname, char *ifname2) +typedef struct { - int cnt, i, j, oloop, iloop; + ssize_t input_bytes; + ssize_t output_bytes; + uint8_t outputs[4]; + uint8_t inputs[4]; + ec_timet input_change_ts[32]; + ec_timet output_change_ts[32]; + ec_timet in_out_diff_ts[32]; + ec_timet max_in_out_diff_ts[32]; + bool result[32]; +} io_test_t; - printf("Starting Redundant test\n"); +io_test_t io_test[MAX_SLAVE] = {0}; + +static uint16_t test_list[] = + { + ROL_U16(0x0201u, 0), + ROL_U16(0x0201u, 1), + ROL_U16(0x0201u, 2), + ROL_U16(0x0201u, 3), + ROL_U16(0x0201u, 4), + ROL_U16(0x0201u, 5), + ROL_U16(0x0201u, 6), + ROL_U16(0x0201u, 7), + ROL_U16(0x0201u, 8), + ROL_U16(0x0201u, 9), + ROL_U16(0x0201u, 10), + ROL_U16(0x0201u, 11), + ROL_U16(0x0201u, 12), + ROL_U16(0x0201u, 13), + ROL_U16(0x0201u, 14), + ROL_U16(0x0201u, 15), + 0xFFFFu, +}; + +void tj30_test(char *ifname) +{ + int cnt, i; + + printf("Starting TJ30-XXXX test\n"); /* initialise SOEM, bind socket to ifname */ - (void)ifname2; + // if (ec_init_redundant(ifname, ifname2)) if (ec_init(ifname)) { @@ -76,10 +118,20 @@ void redtest(char *ifname, char *ifname2) ec_slave[cnt].state, (int)ec_slave[cnt].pdelay, ec_slave[cnt].hasdc); printf(" Out:%p,%4d In:%p,%4d\n", ec_slave[cnt].outputs, ec_slave[cnt].Obytes, ec_slave[cnt].inputs, ec_slave[cnt].Ibytes); - /* check for EL2004 or EL2008 */ - if (!digout && ((ec_slave[cnt].eep_id == 0x0af83052) || (ec_slave[cnt].eep_id == 0x07d83052))) + // /* check for TJ30-1616DN */ + // if (!digout && (ec_slave[cnt].eep_id == 0x85301616)) + // { + // digout = ec_slave[cnt].outputs; + // } + io_test[cnt].input_bytes = ec_slave[cnt].Ibytes; + if (io_test[cnt].input_bytes == 0 && ec_slave[cnt].Ibits > 0) { - digout = ec_slave[cnt].outputs; + io_test[cnt].input_bytes = 1; + } + io_test[cnt].output_bytes = ec_slave[cnt].Obytes; + if (io_test[cnt].output_bytes == 0 && ec_slave[cnt].Obits > 0) + { + io_test[cnt].output_bytes = 1; } } expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC; @@ -93,16 +145,7 @@ void redtest(char *ifname, char *ifname2) dorun = 1; /* wait for all slaves to reach OP state */ ec_statecheck(0, EC_STATE_OPERATIONAL, 5 * EC_TIMEOUTSTATE); - oloop = ec_slave[0].Obytes; - if ((oloop == 0) && (ec_slave[0].Obits > 0)) - oloop = 1; - if (oloop > 8) - oloop = 8; - iloop = ec_slave[0].Ibytes; - if ((iloop == 0) && (ec_slave[0].Ibits > 0)) - iloop = 1; - if (iloop > 8) - iloop = 8; + if (ec_slave[0].state == EC_STATE_OPERATIONAL) { printf("Operational state reached for all slaves.\n"); @@ -112,15 +155,15 @@ void redtest(char *ifname, char *ifname2) { printf("Processdata cycle %5d , Wck %3d, DCtime %12" PRId64 ", dt %12" PRId64 ", O:", dorun, wkc, ec_DCtime, gl_delta); - for (j = 0; j < oloop; j++) - { - printf(" %2.2x", *(ec_slave[0].outputs + j)); - } - printf(" I:"); - for (j = 0; j < iloop; j++) - { - printf(" %2.2x", *(ec_slave[0].inputs + j)); - } + // for (j = 0; j < oloop; j++) + // { + // printf(" %2.2x", *(ec_slave[0].outputs + j)); + // } + // printf(" I:"); + // for (j = 0; j < iloop; j++) + // { + // printf(" %2.2x", *(ec_slave[0].inputs + j)); + // } printf("\r"); fflush(stdout); osal_usleep(20000); @@ -141,7 +184,7 @@ void redtest(char *ifname, char *ifname2) } } } - printf("Request safe operational state for all slaves\n"); + printf("\nRequest safe operational state for all slaves\n"); ec_slave[0].state = EC_STATE_SAFE_OP; /* request SAFE_OP state for all slaves */ ec_writestate(0); @@ -205,7 +248,9 @@ OSAL_THREAD_FUNC_RT ecatthread(void *ptr) { struct timespec ts, tleft; int ht; + size_t idx = 0; int64 cycletime; + osal_timert tmr = {0}; clock_gettime(CLOCK_MONOTONIC, &ts); ht = (ts.tv_nsec / 1000000) + 1; /* round to nearest ms */ @@ -225,22 +270,40 @@ OSAL_THREAD_FUNC_RT ecatthread(void *ptr) add_timespec(&ts, cycletime + toff); /* wait to cycle start */ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, &tleft); - if (dorun > 0) + if (dorun <= 0) { - wkc = ec_receive_processdata(EC_TIMEOUTRET); - - dorun++; - /* if we have some digital output, cycle */ - if (digout) - *digout = (uint8)((dorun / 16) & 0xff); - - if (ec_slave[0].hasdc) - { - /* calulate toff to get linux time and DC synced */ - ec_sync(ec_DCtime, cycletime, &toff); - } - ec_send_processdata(); + continue; } + dorun++; + wkc = ec_receive_processdata(EC_TIMEOUTRET); + + if (osal_timer_is_expired(&tmr)) + { + osal_timer_start(&tmr, TEST_STEP_CYCLETIME); + + uint16_t test_val = test_list[idx]; + idx++; + if (idx >= ARRAY_SIZE(test_list)) + { + idx = 0; + } + + for (int i = 1; i <= ec_slavecount; i++) + { + for (int j = 0; j < io_test[i].output_bytes; j++) + { + *(ec_slave[i].outputs + j) = (uint8_t)((test_val >> (j % 2)) & 0xff); + io_test[i].outputs[j] = *(ec_slave[i].outputs + j); + } + } + } + + if (ec_slave[0].hasdc) + { + /* calulate toff to get linux time and DC synced */ + ec_sync(ec_DCtime, cycletime, &toff); + } + ec_send_processdata(); } } @@ -330,10 +393,10 @@ int main(int argc, char *argv[]) printf("SOEM (Simple Open EtherCAT Master)\nRedundancy test\n"); - if (argc > 3) + if (argc == 3) { dorun = 0; - ctime = atoi(argv[3]); + ctime = atoi(argv[2]); /* create RT thread */ osal_thread_create_rt(&thread1, stack64k * 2, &ecatthread, (void *)&ctime); @@ -342,11 +405,11 @@ int main(int argc, char *argv[]) osal_thread_create(&thread2, stack64k * 4, &ecatcheck, NULL); /* start acyclic part */ - redtest(argv[1], argv[2]); + tj30_test(argv[1]); } else { - printf("Usage: red_test ifname1 ifname2 cycletime\nifname = eth0 for example\ncycletime in us\n"); + printf("Usage: red_test ifname1 cycletime\nifname = eth0 for example\ncycletime in us\n"); ec_adaptert *adapter = NULL; printf("\nAvailable adapters:\n");