本程序在xenomai的基础上,用posix接口,编写了IGH的应用层代码,拓扑结构是一个master主站,两个slaves从站。主站通过PDO的方式,发送信息给从站。从站的MCU通过ethercat接口接收到信息后,控制伺服电机的运转。

#include <errno.h>

#include <mqueue.h>

#include <signal.h>

#include <pthread.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include <stdio.h>

#include <string.h>

#include <unistd.h>

#include <limits.h>

#include <sys/ioctl.h>

#include <sys/mman.h>

#include <time.h>

#include <limits.h>

#include <rtdm/rtdm.h>

#include "ecrt.h"

#define USEC_PER_SEC 1000000000

static pthread_t cyclic_thread0;

static pthread_t cyclic_thread1;

static unsigned int cycle0_us = 800000; /* max 2000000 */

static unsigned int cycle1_us = 400000; /* max 2000000 */

static int run = 1;

static ec_master_t *master = NULL;

static ec_master_state_t master_state = {};

static ec_domain_t *domain0 = NULL;

static ec_domain_state_t domain0_state = {};

static ec_domain_t *domain1 = NULL;

static ec_domain_state_t domain1_state = {};

static ec_slave_config_t *slave_0;

static ec_slave_config_state_t slave_0_state = {};

static ec_slave_config_t *slave_1;

static ec_slave_config_state_t slave_1_state = {};

typedef struct shared_use_st

{

   uint8_t slave0_stat;

   uint8_t slave1_stat;

}shared_use_info;

int shmid ;

shared_use_info shared_use;

static uint8_t *domain0_pd = NULL;

static uint8_t *domain1_pd = NULL;

#define AX58100_0            0, 0

#define S0_VID_PID           0x00000009, 0x26483052

#define AX58100_1            0, 1

#define S1_VID_PID           0x00000009, 0x26483052

unsigned int off_bytes_board0_led1_val;

unsigned int off_bytes_board0_led2_val;

unsigned int off_bytes_board0_led3_val;

unsigned int off_bytes_board0_led4_val;

unsigned int off_bytes_board0_led5_val;

unsigned int off_bytes_board0_led6_val;

unsigned int off_bytes_board0_led7_val;

unsigned int off_bytes_board0_led8_val;

unsigned int off_bytes_board0_led9_val;

unsigned int off_bytes_board0_led10_val;

unsigned int off_bytes_board0_led11_val;

unsigned int off_bytes_board0_led12_val;

unsigned int off_bytes_board0_led13_val;

unsigned int off_bytes_board0_led14_val;

unsigned int off_bytes_board0_led15_val;

unsigned int off_bytes_board0_led16_val;


unsigned int off_bytes_board0_switch1_status;

unsigned int off_bytes_board0_switch2_status;

unsigned int off_bytes_board0_switch3_status;

unsigned int off_bytes_board0_switch4_status;

unsigned int off_bytes_board0_switch5_status;

unsigned int off_bytes_board0_switch6_status;

unsigned int off_bytes_board0_switch7_status;

unsigned int off_bytes_board0_switch8_status;


unsigned int off_bits_board0_led1_val;

unsigned int off_bits_board0_led2_val;

unsigned int off_bits_board0_led3_val;

unsigned int off_bits_board0_led4_val;

unsigned int off_bits_board0_led5_val;

unsigned int off_bits_board0_led6_val;

unsigned int off_bits_board0_led7_val;

unsigned int off_bits_board0_led8_val;

unsigned int off_bits_board0_led9_val;

unsigned int off_bits_board0_led10_val;

unsigned int off_bits_board0_led11_val;

unsigned int off_bits_board0_led12_val;

unsigned int off_bits_board0_led13_val;

unsigned int off_bits_board0_led14_val;

unsigned int off_bits_board0_led15_val;

unsigned int off_bits_board0_led16_val;


unsigned int off_bits_board0_switch1_status;

unsigned int off_bits_board0_switch2_status;

unsigned int off_bits_board0_switch3_status;

unsigned int off_bits_board0_switch4_status;

unsigned int off_bits_board0_switch5_status;

unsigned int off_bits_board0_switch6_status;

unsigned int off_bits_board0_switch7_status;

unsigned int off_bits_board0_switch8_status;

unsigned int off_bytes_board1_led1_val;

unsigned int off_bytes_board1_led2_val;

unsigned int off_bytes_board1_led3_val;

unsigned int off_bytes_board1_led4_val;

unsigned int off_bytes_board1_led5_val;

unsigned int off_bytes_board1_led6_val;

unsigned int off_bytes_board1_led7_val;

unsigned int off_bytes_board1_led8_val;

unsigned int off_bytes_board1_led9_val;

unsigned int off_bytes_board1_led10_val;

unsigned int off_bytes_board1_led11_val;

unsigned int off_bytes_board1_led12_val;

unsigned int off_bytes_board1_led13_val;

unsigned int off_bytes_board1_led14_val;

unsigned int off_bytes_board1_led15_val;

unsigned int off_bytes_board1_led16_val;


unsigned int off_bytes_board1_switch1_status;

unsigned int off_bytes_board1_switch2_status;

unsigned int off_bytes_board1_switch3_status;

unsigned int off_bytes_board1_switch4_status;

unsigned int off_bytes_board1_switch5_status;

unsigned int off_bytes_board1_switch6_status;

unsigned int off_bytes_board1_switch7_status;

unsigned int off_bytes_board1_switch8_status;


unsigned int off_bits_board1_led1_val;

unsigned int off_bits_board1_led2_val;

unsigned int off_bits_board1_led3_val;

unsigned int off_bits_board1_led4_val;

unsigned int off_bits_board1_led5_val;

unsigned int off_bits_board1_led6_val;

unsigned int off_bits_board1_led7_val;

unsigned int off_bits_board1_led8_val;

unsigned int off_bits_board1_led9_val;

unsigned int off_bits_board1_led10_val;

unsigned int off_bits_board1_led11_val;

unsigned int off_bits_board1_led12_val;

unsigned int off_bits_board1_led13_val;

unsigned int off_bits_board1_led14_val;

unsigned int off_bits_board1_led15_val;

unsigned int off_bits_board1_led16_val;


unsigned int off_bits_board1_switch1_status;

unsigned int off_bits_board1_switch2_status;

unsigned int off_bits_board1_switch3_status;

unsigned int off_bits_board1_switch4_status;

unsigned int off_bits_board1_switch5_status;

unsigned int off_bits_board1_switch6_status;

unsigned int off_bits_board1_switch7_status;

unsigned int off_bits_board1_switch8_status;


const static ec_pdo_entry_reg_t domain0_regs[] = {

   {AX58100_0, S0_VID_PID, 0x7010, 0x01, &off_bytes_board0_led1_val,&off_bits_board0_led1_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x02, &off_bytes_board0_led2_val,&off_bits_board0_led2_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x03, &off_bytes_board0_led3_val,&off_bits_board0_led3_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x04, &off_bytes_board0_led4_val,&off_bits_board0_led4_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x05, &off_bytes_board0_led5_val,&off_bits_board0_led5_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x06, &off_bytes_board0_led6_val,&off_bits_board0_led6_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x07, &off_bytes_board0_led7_val,&off_bits_board0_led7_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x08, &off_bytes_board0_led8_val,&off_bits_board0_led8_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x09, &off_bytes_board0_led9_val,&off_bits_board0_led9_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x10, &off_bytes_board0_led10_val,&off_bits_board0_led10_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x11, &off_bytes_board0_led11_val,&off_bits_board0_led11_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x12, &off_bytes_board0_led12_val,&off_bits_board0_led12_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x13, &off_bytes_board0_led13_val,&off_bits_board0_led13_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x14, &off_bytes_board0_led14_val,&off_bits_board0_led14_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x15, &off_bytes_board0_led15_val,&off_bits_board0_led15_val},

   {AX58100_0, S0_VID_PID, 0x7010, 0x16, &off_bytes_board0_led16_val,&off_bits_board0_led16_val},

                       

   {AX58100_0, S0_VID_PID, 0x6000, 0x01, &off_bytes_board0_switch1_status,&off_bits_board0_switch1_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x02, &off_bytes_board0_switch2_status,&off_bits_board0_switch2_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x03, &off_bytes_board0_switch3_status,&off_bits_board0_switch3_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x04, &off_bytes_board0_switch4_status,&off_bits_board0_switch4_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x05, &off_bytes_board0_switch5_status,&off_bits_board0_switch5_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x06, &off_bytes_board0_switch6_status,&off_bits_board0_switch6_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x07, &off_bytes_board0_switch7_status,&off_bits_board0_switch7_status},

   {AX58100_0, S0_VID_PID, 0x6000, 0x08, &off_bytes_board0_switch8_status,&off_bits_board0_switch8_status},

   {}

};


const static ec_pdo_entry_reg_t domain1_regs[] = {

   {AX58100_1, S1_VID_PID, 0x7010, 0x01, &off_bytes_board1_led1_val, &off_bits_board1_led1_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x02, &off_bytes_board1_led2_val, &off_bits_board1_led2_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x03, &off_bytes_board1_led3_val, &off_bits_board1_led3_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x04, &off_bytes_board1_led4_val, &off_bits_board1_led4_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x05, &off_bytes_board1_led5_val, &off_bits_board1_led5_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x06, &off_bytes_board1_led6_val, &off_bits_board1_led6_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x07, &off_bytes_board1_led7_val, &off_bits_board1_led7_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x08, &off_bytes_board1_led8_val, &off_bits_board1_led8_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x09, &off_bytes_board1_led9_val, &off_bits_board1_led9_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x10, &off_bytes_board1_led10_val,&off_bits_board1_led10_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x11, &off_bytes_board1_led11_val,&off_bits_board1_led11_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x12, &off_bytes_board1_led12_val,&off_bits_board1_led12_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x13, &off_bytes_board1_led13_val,&off_bits_board1_led13_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x14, &off_bytes_board1_led14_val,&off_bits_board1_led14_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x15, &off_bytes_board1_led15_val,&off_bits_board1_led15_val},

   {AX58100_1, S1_VID_PID, 0x7010, 0x16, &off_bytes_board1_led16_val,&off_bits_board1_led16_val},


   {AX58100_1, S1_VID_PID, 0x6000, 0x01, &off_bytes_board1_switch1_status, &off_bits_board1_switch1_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x02, &off_bytes_board1_switch2_status, &off_bits_board1_switch2_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x03, &off_bytes_board1_switch3_status, &off_bits_board1_switch3_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x04, &off_bytes_board1_switch4_status, &off_bits_board1_switch4_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x05, &off_bytes_board1_switch5_status, &off_bits_board1_switch5_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x06, &off_bytes_board1_switch6_status, &off_bits_board1_switch6_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x07, &off_bytes_board1_switch7_status, &off_bits_board1_switch7_status},

   {AX58100_1, S1_VID_PID, 0x6000, 0x08, &off_bytes_board1_switch8_status, &off_bits_board1_switch8_status},

   {}

};


/***************************************************************************/

/*Config PDOs*/

static ec_pdo_entry_info_t slave_0_pdo_entries[] = {

//input  (write)

   {0x7010, 0x01, 16},

   {0x7010, 0x02, 16},

   {0x7010, 0x03, 16},

   {0x7010, 0x04, 16},

   {0x7010, 0x05, 16},

   {0x7010, 0x06, 16},

   {0x7010, 0x07, 16},

   {0x7010, 0x08, 16},

   {0x7010, 0x09, 16},

   {0x7010, 0x10, 16},

   {0x7010, 0x11, 16},

   {0x7010, 0x12, 16},

   {0x7010, 0x13, 16},

   {0x7010, 0x14, 16},

   {0x7010, 0x15, 16},

   {0x7010, 0x16, 16},

//output  (read)

   {0x6000, 0x01, 8}, /* Switch 1      0x7e*/

   {0x6000, 0x02, 8}, /* Switch 2      0x81            0x83     0x85              0x87       0x89*/

   {0x6000, 0x03, 8}, /* Switch 3      正确0  错误1             位置1(00-07) */

   {0x6000, 0x04, 8}, /* Switch 4      0x7e                     位置2(08-15) */

   {0x6000, 0x05, 8}, /* Switch 5                               位置3(16-23) */

   {0x6000, 0x06, 8}, /* Switch 6                               位置4(24-31) */

   {0x6000, 0x07, 8}, /* Switch 7                               正确0  错误1 */

   {0x6000, 0x08, 8}, /* Switch 8                               0x7e*/

};


static ec_pdo_info_t slave_0_pdos[] = {

   {0x1601, 16, slave_0_pdo_entries + 0}, /* DO RxPDO-Map */

   {0x1a00, 8, slave_0_pdo_entries + 16}, /* DI TxPDO-Map */

};


static ec_sync_info_t slave_0_syncs[] = {

   {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},

   {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},

   {2, EC_DIR_OUTPUT, 1, slave_0_pdos + 0, EC_WD_ENABLE},

   {3, EC_DIR_INPUT, 1, slave_0_pdos + 1, EC_WD_DISABLE},

   {0xff}

};


/**************************************************************************/

/*Config PDOs*/

static ec_pdo_entry_info_t slave_1_pdo_entries[] = {

//input  (write)

   {0x7010, 0x01, 16}, /* LED 1  0x7e  标志*/

   {0x7010, 0x02, 16}, /* LED 2  功能选择 0x80          0x82            0x84  0x86  0x88 */

   {0x7010, 0x03, 16}, /* LED 3           位置低16      阶段加速1低16      */

   {0x7010, 0x04, 16}, /* LED 4           位置高16      阶段加速1高16      */

   {0x7010, 0x05, 16}, /* LED 5           速度低16      阶段加速2低16      */

   {0x7010, 0x06, 16}, /* LED 6           速度高16      阶段加速2高16      */

   {0x7010, 0x07, 16}, /* LED 7           加速度低16    阶段减速1低16      */

   {0x7010, 0x08, 16}, /* LED 8           加速度高16    阶段减速1高16      */

   {0x7010, 0x09, 16}, /* LED 9           减速度低16    阶段减速2低16      */

   {0x7010, 0x10, 16}, /* LED 16          减速度高16    阶段减速2高16       */

   {0x7010, 0x11, 16},

   {0x7010, 0x12, 16},

   {0x7010, 0x13, 16},

   {0x7010, 0x14, 16},

   {0x7010, 0x15, 16},

   {0x7010, 0x16, 16},

//output  (read)

   {0x6000, 0x01, 8}, /* Switch 1      0x7e*/

   {0x6000, 0x02, 8}, /* Switch 2      0x81            0x83     0x85              0x87       0x89*/

   {0x6000, 0x03, 8}, /* Switch 3      正确0  错误1             位置1(00-07) */

   {0x6000, 0x04, 8}, /* Switch 4      0x7e                     位置2(08-15) */

   {0x6000, 0x05, 8}, /* Switch 5                               位置3(16-23) */

   {0x6000, 0x06, 8}, /* Switch 6                               位置4(24-31) */

   {0x6000, 0x07, 8}, /* Switch 7                               正确0  错误1 */

   {0x6000, 0x08, 8}, /* Switch 8                               0x7e*/

};


static ec_pdo_info_t slave_1_pdos[] = {

   {0x1601, 16, slave_1_pdo_entries + 0}, /* DO RxPDO-Map */

   {0x1a00, 8, slave_1_pdo_entries + 16}, /* DI TxPDO-Map */

};


static ec_sync_info_t slave_1_syncs[] = {

   {0, EC_DIR_OUTPUT, 0, NULL, EC_WD_DISABLE},

   {1, EC_DIR_INPUT, 0, NULL, EC_WD_DISABLE},

   {2, EC_DIR_OUTPUT, 1, slave_1_pdos + 0, EC_WD_ENABLE},

   {3, EC_DIR_INPUT, 1, slave_1_pdos + 1, EC_WD_DISABLE},

   {0xff}

};


/*************************************************************************/

void check_master_state(void)

{

   ec_master_state_t ms;

   ecrt_master_state(master, &ms);

   if (ms.slaves_responding != master_state.slaves_responding)

       printf("%u slave(s).\n", ms.slaves_responding);


   if (ms.al_states != master_state.al_states)

       printf("AL states: 0x%02X.\n", ms.al_states);


   if (ms.link_up != master_state.link_up)

       printf("Link is %s.\n", ms.link_up ? "up" : "down");


   master_state = ms;

}


void check_domain0_state(void)

{

   ec_domain_state_t ds;


   ecrt_domain_state(domain0, &ds);

   if (ds.working_counter != domain0_state.working_counter)

       printf("Domain0: WC %u.\n", ds.working_counter);


   if (ds.wc_state != domain0_state.wc_state)

       printf("Domain0: State %u.\n", ds.wc_state);


   domain0_state = ds;

}


void check_domain1_state(void)

{

   ec_domain_state_t ds;


   ecrt_domain_state(domain1, &ds);

   if (ds.working_counter != domain1_state.working_counter)

       printf("Domain1: WC %u.\n", ds.working_counter);


   if (ds.wc_state != domain1_state.wc_state)

       printf("Domain1: State %u.\n", ds.wc_state);


   domain1_state = ds;

}


uint32_t check_slave0_config_states(void)

{

   ec_slave_config_state_t s;


   ecrt_slave_config_state(slave_0, &s);

   if (s.al_state != slave_0_state.al_state)

       printf("slave0: State 0x%02X.\n", s.al_state);


   if (s.online != slave_0_state.online)

       printf("slave0: %s.\n", s.online ? "online" : "offline");


   if (s.operational != slave_0_state.operational)

       printf("slave0: %soperational.\n\n\n", s.operational ? "" : "Not ");

   slave_0_state = s;

return s.al_state;

}


uint32_t check_slave1_config_states(void)

{

   ec_slave_config_state_t s;


   ecrt_slave_config_state(slave_1, &s);

   if (s.al_state != slave_1_state.al_state)

       printf("slave1: State 0x%02X.\n", s.al_state);


   if (s.online != slave_1_state.online)

       printf("slave1: %s.\n", s.online ? "online" : "offline");


   if (s.operational != slave_1_state.operational)

       printf("slave1: %soperational.\n\n\n", s.operational ? "" : "Not ");

   slave_1_state = s;

return s.al_state;

}


/*******************************************************************************/


void *cyclic_task0_thread(void *arg)

{

   struct     timespec next_period;

int        cycle_counter = 0;

uint32_t   status;

uint16_t   pos1=0,pos2=0;

uint8_t    step=0;

   uint8_t    status2;

uint8_t    status3;

   uint8_t    status4;

uint8_t    status5;

   uint8_t    status6;

uint8_t    status7;

char       *tip;

void       *shm = NULL;

shared_use_info *slave_stat;

struct sched_param param = { .sched_priority = 83 };

pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

   clock_gettime(CLOCK_REALTIME, &next_period);

shm = shmat(shmid, NULL, 0);

   shm = shmat(shmid, 0, 0);

   if (shm == (void *)-1) {

       fprintf(stderr, "shmat failed\n");

       exit(EXIT_FAILURE);

   }

slave_stat = (shared_use_info *)shm;

slave_stat->slave0_stat=0;

printf("slave 1 time = %ld s\n", next_period.tv_sec);

printf("slave 1 time = %ld ns\n", next_period.tv_nsec);

 

   while (run) {

       next_period.tv_nsec += cycle0_us * 1000;

       while (next_period.tv_nsec >= USEC_PER_SEC) {

  next_period.tv_nsec -= USEC_PER_SEC;

  next_period.tv_sec++;

 }

       clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next_period, NULL);

 cycle_counter++;

 

 ecrt_master_receive(master);

 ecrt_domain_process(domain0);


       if (!(cycle_counter % 10)) {

  check_domain0_state();

  check_master_state();

 }

 //Check for slave configuration state(s)

 status=check_slave0_config_states();

 if(status != 0x8) {

  ecrt_domain_queue(domain0);

  ecrt_master_send(master);

  slave_stat->slave0_stat=0;

  continue;

 }

 else {

  slave_stat->slave0_stat=1;

 }

 if(!(slave_stat->slave1_stat))

  continue;

 

 if(step == 0) {

  pos2+=7;

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led1_val,  0x007e );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led2_val,  0x0080 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led3_val,  pos1   );//位置

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led4_val,  pos2   );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led5_val,  0xff00 );//速度

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led6_val,  0x0fff );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led7_val,  0x0a00 );//加速度

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led8_val,  0x0000 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led9_val,  0x00a0 );//减速度

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led10_val, 0x0000 );

  step++;

  printf("slave 0 time = %ld s\n", next_period.tv_sec);

  printf("slave 0 time = %ld ns\n", next_period.tv_nsec);

 }

 else if(step == 1) {

  EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  EC_READ_U8(domain0_pd + off_bytes_board0_switch3_status);

  step++;

 }

 else if(step == 2) {

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led1_val,  0x007e );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led2_val,  0x0082 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led3_val,  0x0500 );//阶段加速1

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led4_val,  0x0000 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led5_val,  0x0500 );//阶段加速2

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led6_val,  0x0000 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led7_val,  0x0050 );//阶段减速1

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led8_val,  0x0000 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led9_val,  0x0050 );//阶段减速2

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led10_val,  0x0000 );

  step++;

 }

 else if(step == 3) {

  EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  EC_READ_U8(domain0_pd + off_bytes_board0_switch3_status);

  step++;

 }

 else if(step == 4) {

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led1_val,  0x007e );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led2_val,  0x0084 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led3_val,  0x007e );

  step++;

 }

 else if(step == 5) {

  EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  EC_READ_U8(domain0_pd + off_bytes_board0_switch7_status);

  step++;

 }

 else if(step == 6) {

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led1_val,  0x007e );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led2_val,  0x0086 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led3_val,  0x007e );

  step++;

 }

 else if(step == 7) {

  EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  EC_READ_U8(domain0_pd + off_bytes_board0_switch7_status);

  step++;

 }

 else if(step == 8) {

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led1_val,  0x007e );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led2_val,  0x0088 );

  EC_WRITE_U16(domain0_pd + off_bytes_board0_led3_val,  0x007e );

  step++;

 }

 else if(step == 9) {

  EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  EC_READ_U8(domain0_pd + off_bytes_board0_switch7_status);

  step++;

 }

 else {

  step++;

 }


 if (step <= 10) {  

  ecrt_domain_queue(domain0);

  ecrt_master_send(master);

 }

 

 if( (step == 3) || (step == 5) ) {

  status2 = EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  status3 = EC_READ_U8(domain0_pd + off_bytes_board0_switch3_status);

 }

 else if( (step == 7) || (step == 9) || (step == 11) ) {

  status2 = EC_READ_U8(domain0_pd + off_bytes_board0_switch2_status);

  status7 = EC_READ_U8(domain0_pd + off_bytes_board0_switch7_status);

 }


 if( (step == 3) ||(step == 5) ||(step == 7) ||(step == 9) ||(step == 11) ) {

  printf("step %d board0 State 0x%x :",step, status2);

  switch (status2) {

   case 0x81:  tip = status3 ? "fail" :  "sucess" ; break;

   case 0x83:  tip = status3 ? "fail" :  "sucess" ; break;

   case 0x85:  tip = status7 ? "fail" :  "sucess" ; break;

   case 0x87:  tip = status7 ? "fail" :  "sucess" ; break;

   case 0x89:  tip = status7 ? "fail" :  "sucess" ; break;

   default  :  tip = "fail";

  }

  printf("%s\n", tip);

 }

 

 

 if(step == 11){

  step=0;

  //return NULL;

 }

   }


   return NULL;  

}


void *cyclic_task1_thread(void *arg)

{

   struct     timespec next_period;

int        cycle_counter = 0;

uint32_t   status;

uint16_t   pos1=0xffff,pos2=0xffff;

uint8_t    step=0;

   uint8_t    status2;

uint8_t    status3;

   uint8_t    status4;

uint8_t    status5;

   uint8_t    status6;

uint8_t    status7;

char       *tip;

void       *shm = NULL;

shared_use_info *slave_stat;

struct sched_param param = { .sched_priority = 82 };//数值越大,对应的优先级越大

pthread_setschedparam(pthread_self(), SCHED_FIFO, &param);

   clock_gettime(CLOCK_REALTIME, &next_period);

shm = shmat(shmid, NULL, 0);

   shm = shmat(shmid, 0, 0);

   if (shm == (void *)-1) {

       fprintf(stderr, "shmat failed\n");

       exit(EXIT_FAILURE);

   }

slave_stat = (shared_use_info *)shm;

slave_stat->slave1_stat=0;

printf("slave 1 time = %ld s\n", next_period.tv_sec);

printf("slave 1 time = %ld ns\n", next_period.tv_nsec);

 

   while (run) {

       next_period.tv_nsec += cycle1_us * 1000;

       while (next_period.tv_nsec >= USEC_PER_SEC) {

  next_period.tv_nsec -= USEC_PER_SEC;

  next_period.tv_sec++;

 }

       clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next_period, NULL);

 cycle_counter++;

 

 ecrt_master_receive(master);

 ecrt_domain_process(domain1);

 

       if (!(cycle_counter % 10)) {

  check_domain1_state();

  check_master_state();

 }  

 //Check for slave configuration state(s)

 status=check_slave1_config_states();

 if(status != 0x8) {

  ecrt_domain_queue(domain1);

  ecrt_master_send(master);

  slave_stat->slave1_stat=0;

  continue;

 }

 else {

  slave_stat->slave1_stat=1;

 }

 if(!(slave_stat->slave0_stat))

  continue;

 

 if(step == 0) {

  pos2-=7;

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led1_val,  0x007e );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led2_val,  0x0080 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led3_val,  pos1   );//位置

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led4_val,  pos2   );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led5_val,  0xff00 );//速度

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led6_val,  0x0fff );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led7_val,  0x0a00 );//加速度

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led8_val,  0x0000 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led9_val,  0x00a0 );//减速度

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led10_val, 0x0000 );

  step++;

  printf("slave 1 time = %ld s\n", next_period.tv_sec);

  printf("slave 1 time = %ld ns\n", next_period.tv_nsec);

 }

 else if(step == 1) {

  EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  EC_READ_U8(domain1_pd + off_bytes_board1_switch3_status);

  step++;

 }

 else if(step == 2) {

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led1_val,  0x007e );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led2_val,  0x0082 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led3_val,  0x0500 );//阶段加速1

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led4_val,  0x0000 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led5_val,  0x0500 );//阶段加速2

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led6_val,  0x0000 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led7_val,  0x0050 );//阶段减速1

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led8_val,  0x0000 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led9_val,  0x0050 );//阶段减速2

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led10_val, 0x0000 );

  step++;

 }

 else if(step == 3) {

  EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  EC_READ_U8(domain1_pd + off_bytes_board1_switch3_status);

  step++;

 }


 else if(step == 4) {

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led1_val,  0x007e );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led2_val,  0x0084 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led3_val,  0x007e );

  step++;

 }

 else if(step == 5) {

  EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  EC_READ_U8(domain1_pd + off_bytes_board1_switch7_status);

  step++;

 }

 else if(step == 6) {

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led1_val,  0x007e );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led2_val,  0x0086 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led3_val,  0x007e );

  step++;

 }

 else if(step == 7) {

  EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  EC_READ_U8(domain1_pd + off_bytes_board1_switch7_status);

  step++;

 }

 else if(step == 8) {

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led1_val,  0x007e );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led2_val,  0x0088 );

  EC_WRITE_U16(domain1_pd + off_bytes_board1_led3_val,  0x007e );

  step++;

 }

 else if(step == 9) {

  EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  EC_READ_U8(domain1_pd + off_bytes_board1_switch7_status);

  step++;

 }

 else {

  step++;

 }


 if (step <= 10) {  

  ecrt_domain_queue(domain1);

  ecrt_master_send(master);

 }

 

 if( (step == 3) || (step == 5) ) {

  status2 = EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  status3 = EC_READ_U8(domain1_pd + off_bytes_board1_switch3_status);

 }

 else if( (step == 7) || (step == 9) || (step == 11) ) {

  status2 = EC_READ_U8(domain1_pd + off_bytes_board1_switch2_status);

  status7 = EC_READ_U8(domain1_pd + off_bytes_board1_switch7_status);

 }


 if( (step == 3) ||(step == 5) ||(step == 7) ||(step == 9) ||(step == 11) ) {

  printf("step %d board1 State 0x%x :",step, status2);

  switch (status2) {

   case 0x81:  tip = status3 ? "fail" :  "sucess" ; break;

   case 0x83:  tip = status3 ? "fail" :  "sucess" ; break;

   case 0x85:  tip = status7 ? "fail" :  "sucess" ; break;

   case 0x87:  tip = status7 ? "fail" :  "sucess" ; break;

   case 0x89:  tip = status7 ? "fail" :  "sucess" ; break;

   default  :  tip = "fail";

  }

  printf("%s\n", tip);

 }

 

 if(step == 11){

  step=0;

  // if (shmdt(shm) == -1) {

   // fprintf(stderr, "shmdt failed\n");

   // exit(EXIT_FAILURE);

  // }

  //return NULL;

 }

   }

   if (shmdt(shm) == -1) {

       fprintf(stderr, "shmdt failed\n");

       exit(EXIT_FAILURE);

   }

   return NULL;  

}


void signal_handler(int sig)

{

printf("exit program...\n");

   run = 0;

}


/****************************************************************************/


int main(int argc, char **argv)

{

int ret;

pthread_attr_t thattr;

   signal(SIGTERM, signal_handler);

   signal(SIGINT, signal_handler);


   ret = mlockall(MCL_CURRENT | MCL_FUTURE);

if(ret)

 printf("mlockall failure\n");


   shmid = shmget(IPC_PRIVATE, sizeof(shared_use_info), IPC_CREAT|0600 ) ;

   if ( shmid < 0 ) {

       printf("get shm  ipc_id error") ;

       return -1 ;

   }

   master = ecrt_request_master(0);

   if (!master) {

       exit(EXIT_FAILURE);

   }


   domain0 = ecrt_master_create_domain(master);

   if (!domain0) {

       exit(EXIT_FAILURE);

   }

   domain1 = ecrt_master_create_domain(master);

   if (!domain1) {

       exit(EXIT_FAILURE);

   }

printf("Creating slave configurations...\n");

   if (!(slave_0 = ecrt_master_slave_config(master, AX58100_0, S0_VID_PID))) {

       fprintf(stderr, "Failed to get slave configuration for slave0!\n");

       exit(EXIT_FAILURE);

   }

   if (!(slave_1 = ecrt_master_slave_config(master, AX58100_1, S1_VID_PID))) {

       fprintf(stderr, "Failed to get slave configuration for slave1!\n");

       exit(EXIT_FAILURE);

   }

// ecrt_slave_config_overlapping_pdos(slave_0, 1);

// ecrt_slave_config_overlapping_pdos(slave_1, 1);

   printf("Configuring PDOs...\n");


   if (ecrt_slave_config_pdos(slave_0, EC_END, slave_0_syncs)) {

       fprintf(stderr, "Failed to configure slave0 PDOs!\n");

       exit(EXIT_FAILURE);

   }

   if (ecrt_slave_config_pdos(slave_1, EC_END, slave_1_syncs)) {

       fprintf(stderr, "Failed to configure slave1 PDOs!\n");

       exit(EXIT_FAILURE);

   }


   if (ecrt_domain_reg_pdo_entry_list(domain0, domain0_regs)) {

       fprintf(stderr, "PDO entry registration failed!\n");

       exit(EXIT_FAILURE);

   }


   if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {

       fprintf(stderr, "PDO entry registration failed!\n");

       exit(EXIT_FAILURE);

   }

   printf("Activating master...\n");

   if (ecrt_master_activate(master)) {

       exit(EXIT_FAILURE);

   }

   else {

       printf("*Master activated*\n");

   }


   if (!(domain0_pd = ecrt_domain_data(domain0))) {

       exit(EXIT_FAILURE);

   }


   if (!(domain1_pd = ecrt_domain_data(domain1))) {

       exit(EXIT_FAILURE);

   }

   pthread_attr_init(&thattr);

pthread_attr_setschedpolicy(&thattr, SCHED_FIFO);

   ret = pthread_create(&cyclic_thread0, &thattr, &cyclic_task0_thread, NULL);

   if (ret) {

       printf("%s: pthread_create cyclic task0 failed\n", strerror(-ret));

 return 1;

   }

   ret = pthread_create(&cyclic_thread1, &thattr, &cyclic_task1_thread, NULL);

   if (ret) {

       printf("%s: pthread_create cyclic task1 failed\n", strerror(-ret));

 return 1;

   }

   pthread_join(cyclic_thread0, NULL);

   pthread_join(cyclic_thread1, NULL);

pthread_attr_destroy(&thattr);

   ecrt_release_master(master);

   if (shmctl(shmid, IPC_RMID, 0) == -1) {

       fprintf(stderr, "shmctl(IPC_RMID) failed\n");

       exit(EXIT_FAILURE);

   }

   printf("End of Program\n");

   return EXIT_SUCCESS;

}