master/master.c
changeset 1489 f77a1182b6f4
parent 1485 5ddc3a455059
child 1500 ed1a733efbc5
equal deleted inserted replaced
1488:3fb343e3fac0 1489:f77a1182b6f4
    73 void ec_master_clear_slave_configs(ec_master_t *);
    73 void ec_master_clear_slave_configs(ec_master_t *);
    74 void ec_master_clear_domains(ec_master_t *);
    74 void ec_master_clear_domains(ec_master_t *);
    75 static int ec_master_idle_thread(void *);
    75 static int ec_master_idle_thread(void *);
    76 static int ec_master_operation_thread(void *);
    76 static int ec_master_operation_thread(void *);
    77 #ifdef EC_EOE
    77 #ifdef EC_EOE
    78 void ec_master_eoe_run(unsigned long);
    78 static int ec_master_eoe_thread(void *);
    79 #endif
    79 #endif
    80 void ec_master_find_dc_ref_clock(ec_master_t *);
    80 void ec_master_find_dc_ref_clock(ec_master_t *);
    81 
    81 
    82 /*****************************************************************************/
    82 /*****************************************************************************/
    83 
    83 
   156     master->frames_timed_out = 0;
   156     master->frames_timed_out = 0;
   157 
   157 
   158     master->thread = NULL;
   158     master->thread = NULL;
   159 
   159 
   160 #ifdef EC_EOE
   160 #ifdef EC_EOE
   161     init_timer(&master->eoe_timer);
   161     master->eoe_thread = NULL;
   162     master->eoe_timer.function = ec_master_eoe_run;
       
   163     master->eoe_timer.data = (unsigned long) master;
       
   164     master->eoe_running = 0;
       
   165     INIT_LIST_HEAD(&master->eoe_handlers);
   162     INIT_LIST_HEAD(&master->eoe_handlers);
   166 #endif
   163 #endif
   167 
   164 
   168     master->internal_lock = SPIN_LOCK_UNLOCKED;
   165     init_MUTEX(&master->io_sem);
   169     master->request_cb = NULL;
   166     master->request_cb = NULL;
   170     master->release_cb = NULL;
   167     master->release_cb = NULL;
   171     master->cb_data = NULL;
   168     master->cb_data = NULL;
   172 
   169 
   173     INIT_LIST_HEAD(&master->sii_requests);
   170     INIT_LIST_HEAD(&master->sii_requests);
   378 
   375 
   379 /*****************************************************************************/
   376 /*****************************************************************************/
   380 
   377 
   381 /** Internal locking callback.
   378 /** Internal locking callback.
   382  */
   379  */
   383 int ec_master_request_cb(void *master /**< callback data */)
   380 int ec_master_request_cb(void *data /**< callback data */)
   384 {
   381 {
   385     spin_lock(&((ec_master_t *) master)->internal_lock);
   382     ec_master_t *master = (ec_master_t *) data;
       
   383     down(&master->io_sem);
   386     return 0;
   384     return 0;
   387 }
   385 }
   388 
   386 
   389 /*****************************************************************************/
   387 /*****************************************************************************/
   390 
   388 
   391 /** Internal unlocking callback.
   389 /** Internal unlocking callback.
   392  */
   390  */
   393 void ec_master_release_cb(void *master /**< callback data */)
   391 void ec_master_release_cb(void *data /**< callback data */)
   394 {
   392 {
   395     spin_unlock(&((ec_master_t *) master)->internal_lock);
   393     ec_master_t *master = (ec_master_t *) data;
       
   394     up(&master->io_sem);
   396 }
   395 }
   397 
   396 
   398 /*****************************************************************************/
   397 /*****************************************************************************/
   399 
   398 
   400 /** Starts the master thread.
   399 /** Starts the master thread.
   951 
   950 
   952     while (!kthread_should_stop()) {
   951     while (!kthread_should_stop()) {
   953         ec_datagram_output_stats(&master->fsm_datagram);
   952         ec_datagram_output_stats(&master->fsm_datagram);
   954 
   953 
   955         // receive
   954         // receive
   956         spin_lock_bh(&master->internal_lock);
   955         down(&master->io_sem);
   957         ecrt_master_receive(master);
   956         ecrt_master_receive(master);
   958         spin_unlock_bh(&master->internal_lock);
   957         up(&master->io_sem);
   959 
   958 
   960         if (master->fsm_datagram.state == EC_DATAGRAM_SENT)
   959         if (master->fsm_datagram.state == EC_DATAGRAM_SENT)
   961             goto schedule;
   960             goto schedule;
   962 
   961 
   963         // execute master state machine
   962         // execute master state machine
   965             break;
   964             break;
   966         ec_fsm_master_exec(&master->fsm);
   965         ec_fsm_master_exec(&master->fsm);
   967         up(&master->master_sem);
   966         up(&master->master_sem);
   968 
   967 
   969         // queue and send
   968         // queue and send
   970         spin_lock_bh(&master->internal_lock);
   969         down(&master->io_sem);
   971         ec_master_queue_datagram(master, &master->fsm_datagram);
   970         ec_master_queue_datagram(master, &master->fsm_datagram);
   972         ecrt_master_send(master);
   971         ecrt_master_send(master);
   973         spin_unlock_bh(&master->internal_lock);
   972         up(&master->io_sem);
   974         
   973         
   975 schedule:
   974 schedule:
   976         if (ec_fsm_master_idle(&master->fsm)) {
   975         if (ec_fsm_master_idle(&master->fsm)) {
   977             set_current_state(TASK_INTERRUPTIBLE);
   976             set_current_state(TASK_INTERRUPTIBLE);
   978             schedule_timeout(1);
   977             schedule_timeout(1);
  1037 #ifdef EC_EOE
  1036 #ifdef EC_EOE
  1038 /** Starts Ethernet over EtherCAT processing on demand.
  1037 /** Starts Ethernet over EtherCAT processing on demand.
  1039  */
  1038  */
  1040 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
  1039 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
  1041 {
  1040 {
  1042     if (master->eoe_running) {
  1041     struct sched_param param = { .sched_priority = 0 };
       
  1042 
       
  1043     if (master->eoe_thread) {
  1043         EC_WARN("EoE already running!\n");
  1044         EC_WARN("EoE already running!\n");
  1044         return;
  1045         return;
  1045     }
  1046     }
  1046 
  1047 
  1047     if (list_empty(&master->eoe_handlers))
  1048     if (list_empty(&master->eoe_handlers))
  1050     if (!master->request_cb || !master->release_cb) {
  1051     if (!master->request_cb || !master->release_cb) {
  1051         EC_WARN("No EoE processing because of missing locking callbacks!\n");
  1052         EC_WARN("No EoE processing because of missing locking callbacks!\n");
  1052         return;
  1053         return;
  1053     }
  1054     }
  1054 
  1055 
  1055     EC_INFO("Starting EoE processing.\n");
  1056     EC_INFO("Starting EoE thread.\n");
  1056     master->eoe_running = 1;
  1057     master->eoe_thread = kthread_run(ec_master_eoe_thread, master,
  1057 
  1058             "EtherCAT-EoE");
  1058     // start EoE processing
  1059     if (IS_ERR(master->eoe_thread)) {
  1059     master->eoe_timer.expires = jiffies + 10;
  1060         int err = (int) PTR_ERR(master->eoe_thread);
  1060     add_timer(&master->eoe_timer);
  1061         EC_ERR("Failed to start EoE thread (error %i)!\n", err);
       
  1062         master->eoe_thread = NULL;
       
  1063         return;
       
  1064     }
       
  1065 
       
  1066     sched_setscheduler(master->eoe_thread, SCHED_NORMAL, &param);
       
  1067     set_user_nice(master->eoe_thread, 0);
  1061 }
  1068 }
  1062 
  1069 
  1063 /*****************************************************************************/
  1070 /*****************************************************************************/
  1064 
  1071 
  1065 /** Stops the Ethernet over EtherCAT processing.
  1072 /** Stops the Ethernet over EtherCAT processing.
  1066  */
  1073  */
  1067 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */)
  1074 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */)
  1068 {
  1075 {
  1069     if (!master->eoe_running) return;
  1076     if (master->eoe_thread) {
  1070 
  1077         EC_INFO("Stopping EoE thread.\n");
  1071     EC_INFO("Stopping EoE processing.\n");
  1078 
  1072 
  1079         kthread_stop(master->eoe_thread);
  1073     del_timer_sync(&master->eoe_timer);
  1080         master->eoe_thread = NULL;
  1074     master->eoe_running = 0;
  1081         EC_INFO("EoE thread exited.\n");
       
  1082     }
  1075 }
  1083 }
  1076 
  1084 
  1077 /*****************************************************************************/
  1085 /*****************************************************************************/
  1078 
  1086 
  1079 /** Does the Ethernet over EtherCAT processing.
  1087 /** Does the Ethernet over EtherCAT processing.
  1080  */
  1088  */
  1081 void ec_master_eoe_run(unsigned long data /**< master pointer */)
  1089 static int ec_master_eoe_thread(void *priv_data)
  1082 {
  1090 {
  1083     ec_master_t *master = (ec_master_t *) data;
  1091     ec_master_t *master = (ec_master_t *) priv_data;
  1084     ec_eoe_t *eoe;
  1092     ec_eoe_t *eoe;
  1085     unsigned int none_open = 1;
  1093     unsigned int none_open, sth_to_send, all_idle;
  1086     unsigned long restart_jiffies;
  1094 
  1087 
  1095     if (master->debug_level)
  1088     list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1096         EC_DBG("EoE thread running.\n");
  1089         if (ec_eoe_is_open(eoe)) {
  1097 
  1090             none_open = 0;
  1098     while (!kthread_should_stop()) {
  1091             break;
  1099         none_open = 1;
  1092         }
  1100         all_idle = 1;
  1093     }
  1101 
  1094     if (none_open)
  1102         list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1095         goto queue_timer;
  1103             if (ec_eoe_is_open(eoe)) {
  1096 
  1104                 none_open = 0;
  1097     // receive datagrams
  1105                 break;
  1098     if (master->request_cb(master->cb_data))
  1106             }
  1099         goto queue_timer;
  1107         }
       
  1108         if (none_open)
       
  1109             goto schedule;
       
  1110 
       
  1111         // receive datagrams
       
  1112         if (master->request_cb(master->cb_data))
       
  1113             goto schedule;
       
  1114         
       
  1115         ecrt_master_receive(master);
       
  1116         master->release_cb(master->cb_data);
       
  1117 
       
  1118         // actual EoE processing
       
  1119         sth_to_send = 0;
       
  1120         list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
  1121             ec_eoe_run(eoe);
       
  1122             if (eoe->queue_datagram) {
       
  1123                 sth_to_send = 1;
       
  1124             }
       
  1125             if (!ec_eoe_is_idle(eoe)) {
       
  1126                 all_idle = 0;
       
  1127             }
       
  1128         }
       
  1129 
       
  1130         if (sth_to_send) {
       
  1131             // send datagrams
       
  1132             if (master->request_cb(master->cb_data)) {
       
  1133                 goto schedule;
       
  1134             }
       
  1135             list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
  1136                 ec_eoe_queue(eoe);
       
  1137             }
       
  1138             ecrt_master_send(master);
       
  1139             master->release_cb(master->cb_data);
       
  1140         }
       
  1141 
       
  1142 schedule:
       
  1143         if (all_idle) {
       
  1144             set_current_state(TASK_INTERRUPTIBLE);
       
  1145             schedule_timeout(1);
       
  1146         } else {
       
  1147             schedule();
       
  1148         }
       
  1149     }
  1100     
  1150     
  1101     ecrt_master_receive(master);
  1151     if (master->debug_level)
  1102     master->release_cb(master->cb_data);
  1152         EC_DBG("EoE thread exiting...\n");
  1103 
  1153     return 0;
  1104     // actual EoE processing
       
  1105     list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
  1106         ec_eoe_run(eoe);
       
  1107     }
       
  1108 
       
  1109     // send datagrams
       
  1110     if (master->request_cb(master->cb_data)) {
       
  1111         goto queue_timer;
       
  1112     }
       
  1113     list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
  1114         ec_eoe_queue(eoe);
       
  1115     }
       
  1116     ecrt_master_send(master);
       
  1117     master->release_cb(master->cb_data);
       
  1118 
       
  1119  queue_timer:
       
  1120     restart_jiffies = HZ / EC_EOE_FREQUENCY;
       
  1121     if (!restart_jiffies) restart_jiffies = 1;
       
  1122     master->eoe_timer.expires = jiffies + restart_jiffies;
       
  1123     add_timer(&master->eoe_timer);
       
  1124 }
  1154 }
  1125 #endif
  1155 #endif
  1126 
  1156 
  1127 /*****************************************************************************/
  1157 /*****************************************************************************/
  1128 
  1158