master/master.c
changeset 306 45886de3db87
parent 305 03aab3068f08
child 313 ba324d82dfd3
equal deleted inserted replaced
305:03aab3068f08 306:45886de3db87
    53 #include "datagram.h"
    53 #include "datagram.h"
    54 #include "ethernet.h"
    54 #include "ethernet.h"
    55 
    55 
    56 /*****************************************************************************/
    56 /*****************************************************************************/
    57 
    57 
    58 void ec_master_freerun(void *);
    58 void ec_master_idle(void *);
    59 void ec_master_eoe_run(unsigned long);
    59 void ec_master_eoe_run(unsigned long);
    60 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
    60 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
    61 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
    61 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *,
    62                                   const char *, size_t);
    62                                   const char *, size_t);
    63 
    63 
   114     INIT_LIST_HEAD(&master->slaves);
   114     INIT_LIST_HEAD(&master->slaves);
   115     INIT_LIST_HEAD(&master->datagram_queue);
   115     INIT_LIST_HEAD(&master->datagram_queue);
   116     INIT_LIST_HEAD(&master->domains);
   116     INIT_LIST_HEAD(&master->domains);
   117     INIT_LIST_HEAD(&master->eoe_handlers);
   117     INIT_LIST_HEAD(&master->eoe_handlers);
   118     ec_datagram_init(&master->simple_datagram);
   118     ec_datagram_init(&master->simple_datagram);
   119     INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master);
   119     INIT_WORK(&master->idle_work, ec_master_idle, (void *) master);
   120     init_timer(&master->eoe_timer);
   120     init_timer(&master->eoe_timer);
   121     master->eoe_timer.function = ec_master_eoe_run;
   121     master->eoe_timer.function = ec_master_eoe_run;
   122     master->eoe_timer.data = (unsigned long) master;
   122     master->eoe_timer.data = (unsigned long) master;
   123     master->internal_lock = SPIN_LOCK_UNLOCKED;
   123     master->internal_lock = SPIN_LOCK_UNLOCKED;
   124     master->eoe_running = 0;
   124     master->eoe_running = 0;
   216 {
   216 {
   217     ec_datagram_t *datagram, *next_c;
   217     ec_datagram_t *datagram, *next_c;
   218     ec_domain_t *domain, *next_d;
   218     ec_domain_t *domain, *next_d;
   219 
   219 
   220     ec_master_eoe_stop(master);
   220     ec_master_eoe_stop(master);
   221     ec_master_freerun_stop(master);
   221     ec_master_idle_stop(master);
   222     ec_master_clear_slaves(master);
   222     ec_master_clear_slaves(master);
   223 
   223 
   224     // empty datagram queue
   224     // empty datagram queue
   225     list_for_each_entry_safe(datagram, next_c,
   225     list_for_each_entry_safe(datagram, next_c,
   226                              &master->datagram_queue, queue) {
   226                              &master->datagram_queue, queue) {
   673 }
   673 }
   674 
   674 
   675 /*****************************************************************************/
   675 /*****************************************************************************/
   676 
   676 
   677 /**
   677 /**
   678    Starts the Free-Run mode.
   678    Starts the Idle mode.
   679 */
   679 */
   680 
   680 
   681 void ec_master_freerun_start(ec_master_t *master /**< EtherCAT master */)
   681 void ec_master_idle_start(ec_master_t *master /**< EtherCAT master */)
   682 {
   682 {
   683     if (master->mode == EC_MASTER_MODE_FREERUN) return;
   683     if (master->mode == EC_MASTER_MODE_IDLE) return;
   684 
   684 
   685     if (master->mode == EC_MASTER_MODE_RUNNING) {
   685     if (master->mode == EC_MASTER_MODE_RUNNING) {
   686         EC_ERR("ec_master_freerun_start: Master already running!\n");
   686         EC_ERR("ec_master_idle_start: Master already running!\n");
   687         return;
   687         return;
   688     }
   688     }
   689 
   689 
   690     EC_INFO("Starting Free-Run mode.\n");
   690     EC_INFO("Starting Idle mode.\n");
   691 
   691 
   692     master->mode = EC_MASTER_MODE_FREERUN;
   692     master->mode = EC_MASTER_MODE_IDLE;
   693     ec_fsm_reset(&master->fsm);
   693     ec_fsm_reset(&master->fsm);
   694     queue_delayed_work(master->workqueue, &master->freerun_work, 1);
   694     queue_delayed_work(master->workqueue, &master->idle_work, 1);
   695 }
   695 }
   696 
   696 
   697 /*****************************************************************************/
   697 /*****************************************************************************/
   698 
   698 
   699 /**
   699 /**
   700    Stops the Free-Run mode.
   700    Stops the Idle mode.
   701 */
   701 */
   702 
   702 
   703 void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
   703 void ec_master_idle_stop(ec_master_t *master /**< EtherCAT master */)
   704 {
   704 {
   705     if (master->mode != EC_MASTER_MODE_FREERUN) return;
   705     if (master->mode != EC_MASTER_MODE_IDLE) return;
   706 
   706 
   707     ec_master_eoe_stop(master);
   707     ec_master_eoe_stop(master);
   708 
   708 
   709     EC_INFO("Stopping Free-Run mode.\n");
   709     EC_INFO("Stopping Idle mode.\n");
   710     master->mode = EC_MASTER_MODE_ORPHANED;
   710     master->mode = EC_MASTER_MODE_ORPHANED; // this is important for the
   711 
   711                                             // IDLE work function to not
   712     if (!cancel_delayed_work(&master->freerun_work)) {
   712                                             // queue itself again
       
   713 
       
   714     if (!cancel_delayed_work(&master->idle_work)) {
   713         flush_workqueue(master->workqueue);
   715         flush_workqueue(master->workqueue);
   714     }
   716     }
   715 
   717 
   716     ec_master_clear_slaves(master);
   718     ec_master_clear_slaves(master);
   717 }
   719 }
   718 
   720 
   719 /*****************************************************************************/
   721 /*****************************************************************************/
   720 
   722 
   721 /**
   723 /**
   722    Free-Run mode function.
   724    Idle mode function.
   723 */
   725 */
   724 
   726 
   725 void ec_master_freerun(void *data /**< master pointer */)
   727 void ec_master_idle(void *data /**< master pointer */)
   726 {
   728 {
   727     ec_master_t *master = (ec_master_t *) data;
   729     ec_master_t *master = (ec_master_t *) data;
   728 
   730 
   729     // aquire master lock
   731     // aquire master lock
   730     spin_lock_bh(&master->internal_lock);
   732     spin_lock_bh(&master->internal_lock);
   737     ecrt_master_async_send(master);
   739     ecrt_master_async_send(master);
   738 
   740 
   739     // release master lock
   741     // release master lock
   740     spin_unlock_bh(&master->internal_lock);
   742     spin_unlock_bh(&master->internal_lock);
   741 
   743 
   742     if (master->mode == EC_MASTER_MODE_FREERUN)
   744     if (master->mode == EC_MASTER_MODE_IDLE)
   743         queue_delayed_work(master->workqueue, &master->freerun_work, 1);
   745         queue_delayed_work(master->workqueue, &master->idle_work, 1);
   744 }
   746 }
   745 
   747 
   746 /*****************************************************************************/
   748 /*****************************************************************************/
   747 
   749 
   748 /**
   750 /**
   843     }
   845     }
   844     else if (attr == &attr_mode) {
   846     else if (attr == &attr_mode) {
   845         switch (master->mode) {
   847         switch (master->mode) {
   846             case EC_MASTER_MODE_ORPHANED:
   848             case EC_MASTER_MODE_ORPHANED:
   847                 return sprintf(buffer, "ORPHANED\n");
   849                 return sprintf(buffer, "ORPHANED\n");
   848             case EC_MASTER_MODE_FREERUN:
   850             case EC_MASTER_MODE_IDLE:
   849                 return sprintf(buffer, "FREERUN\n");
   851                 return sprintf(buffer, "IDLE\n");
   850             case EC_MASTER_MODE_RUNNING:
   852             case EC_MASTER_MODE_RUNNING:
   851                 return sprintf(buffer, "RUNNING\n");
   853                 return sprintf(buffer, "RUNNING\n");
   852         }
   854         }
   853     }
   855     }
   854     else if (attr == &attr_debug_level) {
   856     else if (attr == &attr_debug_level) {
  1024     if (master->mode == EC_MASTER_MODE_RUNNING) {
  1026     if (master->mode == EC_MASTER_MODE_RUNNING) {
  1025         // request_cb must return 0, if the lock has been aquired!
  1027         // request_cb must return 0, if the lock has been aquired!
  1026         if (master->request_cb(master->cb_data))
  1028         if (master->request_cb(master->cb_data))
  1027             goto queue_timer;
  1029             goto queue_timer;
  1028     }
  1030     }
  1029     else if (master->mode == EC_MASTER_MODE_FREERUN) {
  1031     else if (master->mode == EC_MASTER_MODE_IDLE) {
  1030         spin_lock(&master->internal_lock);
  1032         spin_lock(&master->internal_lock);
  1031     }
  1033     }
  1032     else
  1034     else
  1033         goto queue_timer;
  1035         goto queue_timer;
  1034 
  1036 
  1041 
  1043 
  1042     // release lock...
  1044     // release lock...
  1043     if (master->mode == EC_MASTER_MODE_RUNNING) {
  1045     if (master->mode == EC_MASTER_MODE_RUNNING) {
  1044         master->release_cb(master->cb_data);
  1046         master->release_cb(master->cb_data);
  1045     }
  1047     }
  1046     else if (master->mode == EC_MASTER_MODE_FREERUN) {
  1048     else if (master->mode == EC_MASTER_MODE_IDLE) {
  1047         spin_unlock(&master->internal_lock);
  1049         spin_unlock(&master->internal_lock);
  1048     }
  1050     }
  1049 
  1051 
  1050  queue_timer:
  1052  queue_timer:
  1051     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
  1053     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;