master/master.c
changeset 251 c1d0b63a9302
parent 246 0bf7c769de06
child 252 111a5c195b8d
equal deleted inserted replaced
250:440ae5f6d2c3 251:c1d0b63a9302
    54 #include "ethernet.h"
    54 #include "ethernet.h"
    55 
    55 
    56 /*****************************************************************************/
    56 /*****************************************************************************/
    57 
    57 
    58 void ec_master_freerun(void *);
    58 void ec_master_freerun(void *);
    59 void ec_master_run_eoe(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 void ec_master_process_watch_command(ec_master_t *);
    61 void ec_master_process_watch_command(ec_master_t *);
    62 
    62 
    63 /*****************************************************************************/
    63 /*****************************************************************************/
    64 
    64 
    92    Master constructor.
    92    Master constructor.
    93    \return 0 in case of success, else < 0
    93    \return 0 in case of success, else < 0
    94 */
    94 */
    95 
    95 
    96 int ec_master_init(ec_master_t *master, /**< EtherCAT master */
    96 int ec_master_init(ec_master_t *master, /**< EtherCAT master */
    97                    unsigned int index /**< master index */
    97                    unsigned int index, /**< master index */
       
    98                    unsigned int eoe_devices /**< number of EoE devices */
    98                    )
    99                    )
    99 {
   100 {
       
   101     ec_eoe_t *eoe, *next_eoe;
       
   102     unsigned int i;
       
   103 
   100     EC_INFO("Initializing master %i.\n", index);
   104     EC_INFO("Initializing master %i.\n", index);
   101 
       
   102     if (!(master->workqueue = create_singlethread_workqueue("EoE"))) {
       
   103         EC_ERR("Failed to create master workqueue.\n");
       
   104         goto out_return;
       
   105     }
       
   106 
       
   107     if (ec_fsm_init(&master->fsm, master)) goto out_free_wq;
       
   108 
   105 
   109     master->index = index;
   106     master->index = index;
   110     master->device = NULL;
   107     master->device = NULL;
   111     master->reserved = 0;
   108     master->reserved = 0;
   112     INIT_LIST_HEAD(&master->slaves);
   109     INIT_LIST_HEAD(&master->slaves);
   113     INIT_LIST_HEAD(&master->command_queue);
   110     INIT_LIST_HEAD(&master->command_queue);
   114     INIT_LIST_HEAD(&master->domains);
   111     INIT_LIST_HEAD(&master->domains);
   115     INIT_LIST_HEAD(&master->eoe_slaves);
   112     INIT_LIST_HEAD(&master->eoe_handlers);
   116     ec_command_init(&master->simple_command);
   113     ec_command_init(&master->simple_command);
   117     INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master);
   114     INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master);
   118     init_timer(&master->eoe_timer);
   115     init_timer(&master->eoe_timer);
   119     master->eoe_timer.function = ec_master_run_eoe;
   116     master->eoe_timer.function = ec_master_eoe_run;
   120     master->eoe_timer.data = (unsigned long) master;
   117     master->eoe_timer.data = (unsigned long) master;
       
   118     master->internal_lock = SPIN_LOCK_UNLOCKED;
       
   119     master->eoe_running = 0;
       
   120 
       
   121     // create workqueue
       
   122     if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) {
       
   123         EC_ERR("Failed to create master workqueue.\n");
       
   124         goto out_return;
       
   125     }
       
   126 
       
   127     // create EoE handlers
       
   128     for (i = 0; i < eoe_devices; i++) {
       
   129         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
       
   130             EC_ERR("Failed to allocate EoE-Object.\n");
       
   131             goto out_clear_eoe;
       
   132         }
       
   133         if (ec_eoe_init(eoe)) {
       
   134             kfree(eoe);
       
   135             goto out_clear_eoe;
       
   136         }
       
   137         list_add_tail(&eoe->list, &master->eoe_handlers);
       
   138     }
       
   139 
       
   140     // create state machine object
       
   141     if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe;
   121 
   142 
   122     // init kobject and add it to the hierarchy
   143     // init kobject and add it to the hierarchy
   123     memset(&master->kobj, 0x00, sizeof(struct kobject));
   144     memset(&master->kobj, 0x00, sizeof(struct kobject));
   124     kobject_init(&master->kobj);
   145     kobject_init(&master->kobj);
   125     master->kobj.ktype = &ktype_ec_master;
   146     master->kobj.ktype = &ktype_ec_master;
   130     }
   151     }
   131 
   152 
   132     ec_master_reset(master);
   153     ec_master_reset(master);
   133     return 0;
   154     return 0;
   134 
   155 
   135  out_free_wq:
   156  out_clear_eoe:
       
   157     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
       
   158         list_del(&eoe->list);
       
   159         ec_eoe_clear(eoe);
       
   160         kfree(eoe);
       
   161     }
   136     destroy_workqueue(master->workqueue);
   162     destroy_workqueue(master->workqueue);
   137  out_return:
   163  out_return:
   138     return -1;
   164     return -1;
   139 }
   165 }
   140 
   166 
   147 */
   173 */
   148 
   174 
   149 void ec_master_clear(struct kobject *kobj /**< kobject of the master */)
   175 void ec_master_clear(struct kobject *kobj /**< kobject of the master */)
   150 {
   176 {
   151     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
   177     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
       
   178     ec_eoe_t *eoe, *next_eoe;
   152 
   179 
   153     EC_INFO("Clearing master %i...\n", master->index);
   180     EC_INFO("Clearing master %i...\n", master->index);
   154 
   181 
   155     ec_master_reset(master);
   182     ec_master_reset(master);
   156     ec_fsm_clear(&master->fsm);
   183     ec_fsm_clear(&master->fsm);
   157     ec_command_clear(&master->simple_command);
   184     ec_command_clear(&master->simple_command);
   158     destroy_workqueue(master->workqueue);
   185     destroy_workqueue(master->workqueue);
   159 
   186 
       
   187     // clear EoE objects
       
   188     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
       
   189         list_del(&eoe->list);
       
   190         ec_eoe_clear(eoe);
       
   191         kfree(eoe);
       
   192     }
       
   193 
   160     if (master->device) {
   194     if (master->device) {
   161         ec_device_clear(master->device);
   195         ec_device_clear(master->device);
   162         kfree(master->device);
   196         kfree(master->device);
   163     }
   197     }
   164 
   198 
   175 
   209 
   176 void ec_master_reset(ec_master_t *master /**< EtherCAT master */)
   210 void ec_master_reset(ec_master_t *master /**< EtherCAT master */)
   177 {
   211 {
   178     ec_command_t *command, *next_c;
   212     ec_command_t *command, *next_c;
   179     ec_domain_t *domain, *next_d;
   213     ec_domain_t *domain, *next_d;
   180     ec_eoe_t *eoe, *next_eoe;
   214 
   181 
   215     ec_master_eoe_stop(master);
   182     // stop EoE processing
       
   183     del_timer_sync(&master->eoe_timer);
       
   184 
       
   185     // stop free-run mode
       
   186     ec_master_freerun_stop(master);
   216     ec_master_freerun_stop(master);
   187 
       
   188     ec_master_clear_slaves(master);
   217     ec_master_clear_slaves(master);
   189 
   218 
   190     // empty command queue
   219     // empty command queue
   191     list_for_each_entry_safe(command, next_c, &master->command_queue, queue) {
   220     list_for_each_entry_safe(command, next_c, &master->command_queue, queue) {
   192         list_del_init(&command->queue);
   221         list_del_init(&command->queue);
   196     // clear domains
   225     // clear domains
   197     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
   226     list_for_each_entry_safe(domain, next_d, &master->domains, list) {
   198         list_del(&domain->list);
   227         list_del(&domain->list);
   199         kobject_del(&domain->kobj);
   228         kobject_del(&domain->kobj);
   200         kobject_put(&domain->kobj);
   229         kobject_put(&domain->kobj);
   201     }
       
   202 
       
   203     // clear EoE objects
       
   204     list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) {
       
   205         list_del(&eoe->list);
       
   206         ec_eoe_clear(eoe);
       
   207         kfree(eoe);
       
   208     }
   230     }
   209 
   231 
   210     master->command_index = 0;
   232     master->command_index = 0;
   211     master->debug_level = 0;
   233     master->debug_level = 0;
   212     master->timeout = 500; // 500us
   234     master->timeout = 500; // 500us
   672 
   694 
   673 void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
   695 void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */)
   674 {
   696 {
   675     if (master->mode != EC_MASTER_MODE_FREERUN) return;
   697     if (master->mode != EC_MASTER_MODE_FREERUN) return;
   676 
   698 
       
   699     ec_master_eoe_stop(master);
       
   700 
   677     EC_INFO("Stopping Free-Run mode.\n");
   701     EC_INFO("Stopping Free-Run mode.\n");
   678 
   702 
   679     if (!cancel_delayed_work(&master->freerun_work)) {
   703     if (!cancel_delayed_work(&master->freerun_work)) {
   680         flush_workqueue(master->workqueue);
   704         flush_workqueue(master->workqueue);
   681     }
   705     }
   691 */
   715 */
   692 
   716 
   693 void ec_master_freerun(void *data /**< master pointer */)
   717 void ec_master_freerun(void *data /**< master pointer */)
   694 {
   718 {
   695     ec_master_t *master = (ec_master_t *) data;
   719     ec_master_t *master = (ec_master_t *) data;
   696     unsigned long delay;
   720 
       
   721     // aquire master lock
       
   722     spin_lock_bh(&master->internal_lock);
   697 
   723 
   698     ecrt_master_async_receive(master);
   724     ecrt_master_async_receive(master);
   699 
   725 
   700     // execute freerun state machine
   726     // execute master state machine
   701     ec_fsm_execute(&master->fsm);
   727     ec_fsm_execute(&master->fsm);
   702 
   728 
   703     ecrt_master_async_send(master);
   729     ecrt_master_async_send(master);
   704 
   730 
   705     delay = HZ / 100;
   731     // release master lock
   706     if (ec_fsm_idle(&master->fsm)) delay = HZ;
   732     spin_unlock_bh(&master->internal_lock);
   707     queue_delayed_work(master->workqueue, &master->freerun_work, delay);
   733 
       
   734     queue_delayed_work(master->workqueue, &master->freerun_work, HZ / 100);
   708 }
   735 }
   709 
   736 
   710 /*****************************************************************************/
   737 /*****************************************************************************/
   711 
   738 
   712 /**
   739 /**
   797 }
   824 }
   798 
   825 
   799 /*****************************************************************************/
   826 /*****************************************************************************/
   800 
   827 
   801 /**
   828 /**
       
   829    Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves.
       
   830 */
       
   831 
       
   832 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
       
   833 {
       
   834     ec_eoe_t *eoe;
       
   835     ec_slave_t *slave;
       
   836     unsigned int coupled, found;
       
   837 
       
   838     if (master->eoe_running) return;
       
   839 
       
   840     // decouple all EoE handlers
       
   841     list_for_each_entry(eoe, &master->eoe_handlers, list)
       
   842         eoe->slave = NULL;
       
   843     coupled = 0;
       
   844 
       
   845     // couple a free EoE handler to every EoE-capable slave
       
   846     list_for_each_entry(slave, &master->slaves, list) {
       
   847         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
       
   848 
       
   849         found = 0;
       
   850         list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
   851             if (eoe->slave) continue;
       
   852             eoe->slave = slave;
       
   853             found = 1;
       
   854             coupled++;
       
   855             EC_INFO("Coupling device %s to slave %i.\n",
       
   856                     eoe->dev->name, slave->ring_position);
       
   857             if (eoe->opened)
       
   858                 slave->requested_state = EC_SLAVE_STATE_OP;
       
   859         }
       
   860 
       
   861         if (!found) {
       
   862             EC_WARN("No EoE handler for slave %i!\n", slave->ring_position);
       
   863             slave->requested_state = EC_SLAVE_STATE_INIT;
       
   864         }
       
   865     }
       
   866 
       
   867     if (!coupled) {
       
   868         EC_INFO("No EoE handlers coupled.\n");
       
   869         return;
       
   870     }
       
   871 
       
   872     EC_INFO("Starting EoE processing.\n");
       
   873     master->eoe_running = 1;
       
   874 
       
   875     // start EoE processing
       
   876     master->eoe_timer.expires = jiffies + 10;
       
   877     add_timer(&master->eoe_timer);
       
   878     return;
       
   879 }
       
   880 
       
   881 /*****************************************************************************/
       
   882 
       
   883 /**
       
   884    Stops the Ethernet-over-EtherCAT processing.
       
   885 */
       
   886 
       
   887 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */)
       
   888 {
       
   889     ec_eoe_t *eoe;
       
   890 
       
   891     if (!master->eoe_running) return;
       
   892 
       
   893     EC_INFO("Stopping EoE processing.\n");
       
   894 
       
   895     del_timer_sync(&master->eoe_timer);
       
   896 
       
   897     // decouple all EoE handlers
       
   898     list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
   899         if (eoe->slave) {
       
   900             eoe->slave->requested_state = EC_SLAVE_STATE_INIT;
       
   901             eoe->slave = NULL;
       
   902         }
       
   903     }
       
   904 
       
   905     master->eoe_running = 0;
       
   906 }
       
   907 
       
   908 /*****************************************************************************/
       
   909 
       
   910 /**
   802    Does the Ethernet-over-EtherCAT processing.
   911    Does the Ethernet-over-EtherCAT processing.
   803 */
   912 */
   804 
   913 
   805 void ec_master_run_eoe(unsigned long data /**< master pointer */)
   914 void ec_master_eoe_run(unsigned long data /**< master pointer */)
   806 {
   915 {
   807     ec_master_t *master = (ec_master_t *) data;
   916     ec_master_t *master = (ec_master_t *) data;
   808     ec_eoe_t *eoe;
   917     ec_eoe_t *eoe;
   809     unsigned int active = 0;
   918     unsigned int active = 0;
   810 
   919 
   811     list_for_each_entry(eoe, &master->eoe_slaves, list) {
   920     list_for_each_entry(eoe, &master->eoe_handlers, list) {
   812         if (ec_eoe_active(eoe)) active++;
   921         if (ec_eoe_active(eoe)) active++;
   813     }
   922     }
   814 
   923     if (!active) goto queue_timer;
   815     // request_cb must return 0, if the lock has been aquired!
   924 
   816     if (active && !master->request_cb(master->cb_data))
   925     // aquire master lock...
   817     {
   926     if (master->mode == EC_MASTER_MODE_RUNNING) {
   818         ecrt_master_async_receive(master);
   927         // request_cb must return 0, if the lock has been aquired!
   819         list_for_each_entry(eoe, &master->eoe_slaves, list) {
   928         if (master->request_cb(master->cb_data))
   820             ec_eoe_run(eoe);
   929             goto queue_timer;
   821         }
   930     }
   822         ecrt_master_async_send(master);
   931     else if (master->mode == EC_MASTER_MODE_FREERUN) {
   823 
   932         spin_lock(&master->internal_lock);
       
   933     }
       
   934     else
       
   935         goto queue_timer;
       
   936 
       
   937     // actual EoE stuff
       
   938     ecrt_master_async_receive(master);
       
   939     list_for_each_entry(eoe, &master->eoe_handlers, list) {
       
   940         ec_eoe_run(eoe);
       
   941     }
       
   942     ecrt_master_async_send(master);
       
   943 
       
   944     // release lock...
       
   945     if (master->mode == EC_MASTER_MODE_RUNNING) {
   824         master->release_cb(master->cb_data);
   946         master->release_cb(master->cb_data);
   825     }
   947     }
   826 
   948     else if (master->mode == EC_MASTER_MODE_FREERUN) {
       
   949         spin_unlock(&master->internal_lock);
       
   950     }
       
   951 
       
   952  queue_timer:
   827     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
   953     master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY;
   828     add_timer(&master->eoe_timer);
   954     add_timer(&master->eoe_timer);
   829 }
   955 }
   830 
   956 
   831 /******************************************************************************
   957 /******************************************************************************
  1402    \ingroup RealtimeInterface
  1528    \ingroup RealtimeInterface
  1403 */
  1529 */
  1404 
  1530 
  1405 int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */)
  1531 int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */)
  1406 {
  1532 {
  1407     ec_eoe_t *eoe;
       
  1408     ec_slave_t *slave;
       
  1409 
       
  1410     if (!master->request_cb || !master->release_cb) {
  1533     if (!master->request_cb || !master->release_cb) {
  1411         EC_ERR("EoE requires master callbacks to be set!\n");
  1534         EC_ERR("EoE requires master callbacks to be set!\n");
  1412         return -1;
  1535         return -1;
  1413     }
  1536     }
  1414 
  1537 
  1415     list_for_each_entry(slave, &master->slaves, list) {
  1538     ec_master_eoe_start(master);
  1416         // does the slave support EoE?
       
  1417         if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
       
  1418 
       
  1419         if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
       
  1420             EC_ERR("Failed to allocate EoE-Object.\n");
       
  1421             return -1;
       
  1422         }
       
  1423         if (ec_eoe_init(eoe, slave)) {
       
  1424             kfree(eoe);
       
  1425             return -1;
       
  1426         }
       
  1427         list_add_tail(&eoe->list, &master->eoe_slaves);
       
  1428     }
       
  1429 
       
  1430     if (list_empty(&master->eoe_slaves)) {
       
  1431         EC_WARN("start_eoe: no EoE-capable slaves present.\n");
       
  1432         return 0;
       
  1433     }
       
  1434 
       
  1435     // start EoE processing
       
  1436     master->eoe_timer.expires = jiffies + 10;
       
  1437     add_timer(&master->eoe_timer);
       
  1438     return 0;
  1539     return 0;
  1439 }
  1540 }
  1440 
  1541 
  1441 /*****************************************************************************/
  1542 /*****************************************************************************/
  1442 
  1543 
  1480     if (master->slave_count) {
  1581     if (master->slave_count) {
  1481         EC_INFO("Slave list:\n");
  1582         EC_INFO("Slave list:\n");
  1482         list_for_each_entry(slave, &master->slaves, list)
  1583         list_for_each_entry(slave, &master->slaves, list)
  1483             ec_slave_print(slave, verbosity);
  1584             ec_slave_print(slave, verbosity);
  1484     }
  1585     }
  1485     if (!list_empty(&master->eoe_slaves)) {
  1586     if (!list_empty(&master->eoe_handlers)) {
  1486         EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n");
  1587         EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n");
  1487         list_for_each_entry(eoe, &master->eoe_slaves, list) {
  1588         list_for_each_entry(eoe, &master->eoe_handlers, list) {
  1488             ec_eoe_print(eoe);
  1589             ec_eoe_print(eoe);
  1489         }
  1590         }
  1490     }
  1591     }
  1491     EC_INFO("*** End master information ***\n");
  1592     EC_INFO("*** End master information ***\n");
  1492 }
  1593 }