master/master.c
branchstable-1.5
changeset 2498 9cdd7669dc0b
parent 2485 5535603c34a0
child 2522 ec403cf308eb
equal deleted inserted replaced
2497:505cf41488a4 2498:9cdd7669dc0b
   134         struct class *class, /**< Device class. */
   134         struct class *class, /**< Device class. */
   135         unsigned int debug_level /**< Debug level (module parameter). */
   135         unsigned int debug_level /**< Debug level (module parameter). */
   136         )
   136         )
   137 {
   137 {
   138     int ret;
   138     int ret;
   139     unsigned int dev_idx;
   139     unsigned int dev_idx, i;
   140 
   140 
   141     master->index = index;
   141     master->index = index;
   142     master->reserved = 0;
   142     master->reserved = 0;
   143 
   143 
   144     sema_init(&master->master_sem, 1);
   144     sema_init(&master->master_sem, 1);
   191     master->datagram_index = 0;
   191     master->datagram_index = 0;
   192 
   192 
   193     INIT_LIST_HEAD(&master->ext_datagram_queue);
   193     INIT_LIST_HEAD(&master->ext_datagram_queue);
   194     sema_init(&master->ext_queue_sem, 1);
   194     sema_init(&master->ext_queue_sem, 1);
   195 
   195 
   196     INIT_LIST_HEAD(&master->external_datagram_queue);
   196     master->ext_ring_idx_rt = 0;
       
   197     master->ext_ring_idx_fsm = 0;
       
   198 
       
   199     // init external datagram ring
       
   200     for (i = 0; i < EC_EXT_RING_SIZE; i++) {
       
   201         ec_datagram_t *datagram = &master->ext_datagram_ring[i];
       
   202         ec_datagram_init(datagram);
       
   203         snprintf(datagram->name, EC_DATAGRAM_NAME_SIZE, "ext-%u", i);
       
   204     }
   197 
   205 
   198     // send interval in IDLE phase
   206     // send interval in IDLE phase
   199     ec_master_set_send_interval(master, 1000000 / HZ);
   207     ec_master_set_send_interval(master, 1000000 / HZ);
       
   208 
       
   209     master->fsm_slave = NULL;
       
   210     INIT_LIST_HEAD(&master->fsm_exec_list);
       
   211     master->fsm_exec_count = 0U;
   200 
   212 
   201     master->debug_level = debug_level;
   213     master->debug_level = debug_level;
   202     master->stats.timeouts = 0;
   214     master->stats.timeouts = 0;
   203     master->stats.corrupted = 0;
   215     master->stats.corrupted = 0;
   204     master->stats.unmatched = 0;
   216     master->stats.unmatched = 0;
   242         goto out_clear_devices;
   254         goto out_clear_devices;
   243     }
   255     }
   244 
   256 
   245     // create state machine object
   257     // create state machine object
   246     ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
   258     ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
       
   259 
       
   260     // alloc external datagram ring
       
   261     for (i = 0; i < EC_EXT_RING_SIZE; i++) {
       
   262         ec_datagram_t *datagram = &master->ext_datagram_ring[i];
       
   263         ret = ec_datagram_prealloc(datagram, EC_MAX_DATA_SIZE);
       
   264         if (ret) {
       
   265             EC_MASTER_ERR(master, "Failed to allocate external"
       
   266                     " datagram %u.\n", i);
       
   267             goto out_clear_ext_datagrams;
       
   268         }
       
   269     }
   247 
   270 
   248     // init reference sync datagram
   271     // init reference sync datagram
   249     ec_datagram_init(&master->ref_sync_datagram);
   272     ec_datagram_init(&master->ref_sync_datagram);
   250     snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE,
   273     snprintf(master->ref_sync_datagram.name, EC_DATAGRAM_NAME_SIZE,
   251             "refsync");
   274             "refsync");
   252     ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4);
   275     ret = ec_datagram_prealloc(&master->ref_sync_datagram, 4);
   253     if (ret < 0) {
   276     if (ret < 0) {
   254         ec_datagram_clear(&master->ref_sync_datagram);
   277         ec_datagram_clear(&master->ref_sync_datagram);
   255         EC_MASTER_ERR(master, "Failed to allocate reference"
   278         EC_MASTER_ERR(master, "Failed to allocate reference"
   256                 " synchronisation datagram.\n");
   279                 " synchronisation datagram.\n");
   257         goto out_clear_fsm;
   280         goto out_clear_ext_datagrams;
   258     }
   281     }
   259 
   282 
   260     // init sync datagram
   283     // init sync datagram
   261     ec_datagram_init(&master->sync_datagram);
   284     ec_datagram_init(&master->sync_datagram);
   262     snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync");
   285     snprintf(master->sync_datagram.name, EC_DATAGRAM_NAME_SIZE, "sync");
   335     ec_datagram_clear(&master->sync_mon_datagram);
   358     ec_datagram_clear(&master->sync_mon_datagram);
   336 out_clear_sync:
   359 out_clear_sync:
   337     ec_datagram_clear(&master->sync_datagram);
   360     ec_datagram_clear(&master->sync_datagram);
   338 out_clear_ref_sync:
   361 out_clear_ref_sync:
   339     ec_datagram_clear(&master->ref_sync_datagram);
   362     ec_datagram_clear(&master->ref_sync_datagram);
   340 out_clear_fsm:
   363 out_clear_ext_datagrams:
       
   364     for (i = 0; i < EC_EXT_RING_SIZE; i++) {
       
   365         ec_datagram_clear(&master->ext_datagram_ring[i]);
       
   366     }
   341     ec_fsm_master_clear(&master->fsm);
   367     ec_fsm_master_clear(&master->fsm);
   342     ec_datagram_clear(&master->fsm_datagram);
   368     ec_datagram_clear(&master->fsm_datagram);
   343 out_clear_devices:
   369 out_clear_devices:
   344     for (; dev_idx > 0; dev_idx--) {
   370     for (; dev_idx > 0; dev_idx--) {
   345         ec_device_clear(&master->devices[dev_idx - 1]);
   371         ec_device_clear(&master->devices[dev_idx - 1]);
   353 */
   379 */
   354 void ec_master_clear(
   380 void ec_master_clear(
   355         ec_master_t *master /**< EtherCAT master */
   381         ec_master_t *master /**< EtherCAT master */
   356         )
   382         )
   357 {
   383 {
   358     unsigned int dev_idx;
   384     unsigned int dev_idx, i;
   359 
   385 
   360 #ifdef EC_RTDM
   386 #ifdef EC_RTDM
   361     ec_rtdm_dev_clear(&master->rtdm_dev);
   387     ec_rtdm_dev_clear(&master->rtdm_dev);
   362 #endif
   388 #endif
   363 
   389 
   377     ec_master_clear_slaves(master);
   403     ec_master_clear_slaves(master);
   378 
   404 
   379     ec_datagram_clear(&master->sync_mon_datagram);
   405     ec_datagram_clear(&master->sync_mon_datagram);
   380     ec_datagram_clear(&master->sync_datagram);
   406     ec_datagram_clear(&master->sync_datagram);
   381     ec_datagram_clear(&master->ref_sync_datagram);
   407     ec_datagram_clear(&master->ref_sync_datagram);
       
   408 
       
   409     for (i = 0; i < EC_EXT_RING_SIZE; i++) {
       
   410         ec_datagram_clear(&master->ext_datagram_ring[i]);
       
   411     }
       
   412 
   382     ec_fsm_master_clear(&master->fsm);
   413     ec_fsm_master_clear(&master->fsm);
   383     ec_datagram_clear(&master->fsm_datagram);
   414     ec_datagram_clear(&master->fsm_datagram);
   384 
   415 
   385     for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
   416     for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master);
   386             dev_idx++) {
   417             dev_idx++) {
   444                     ec_sii_write_request_t, list);
   475                     ec_sii_write_request_t, list);
   445         list_del_init(&request->list); // dequeue
   476         list_del_init(&request->list); // dequeue
   446         EC_MASTER_WARN(master, "Discarding SII request, slave %u about"
   477         EC_MASTER_WARN(master, "Discarding SII request, slave %u about"
   447                 " to be deleted.\n", request->slave->ring_position);
   478                 " to be deleted.\n", request->slave->ring_position);
   448         request->state = EC_INT_REQUEST_FAILURE;
   479         request->state = EC_INT_REQUEST_FAILURE;
   449         wake_up(&master->request_queue);
   480         wake_up_all(&master->request_queue);
   450     }
   481     }
       
   482 
       
   483     master->fsm_slave = NULL;
       
   484     INIT_LIST_HEAD(&master->fsm_exec_list);
       
   485     master->fsm_exec_count = 0;
   451 
   486 
   452     for (slave = master->slaves;
   487     for (slave = master->slaves;
   453             slave < master->slaves + master->slave_count;
   488             slave < master->slaves + master->slave_count;
   454             slave++) {
   489             slave++) {
   455         ec_slave_clear(slave);
   490         ec_slave_clear(slave);
   741  */
   776  */
   742 void ec_master_inject_external_datagrams(
   777 void ec_master_inject_external_datagrams(
   743         ec_master_t *master /**< EtherCAT master */
   778         ec_master_t *master /**< EtherCAT master */
   744         )
   779         )
   745 {
   780 {
   746     ec_datagram_t *datagram, *n;
   781     ec_datagram_t *datagram;
   747     size_t queue_size = 0;
   782     size_t queue_size = 0, new_queue_size = 0;
       
   783 #if DEBUG_INJECT
       
   784     unsigned int datagram_count = 0;
       
   785 #endif
       
   786 
       
   787     if (master->ext_ring_idx_rt == master->ext_ring_idx_fsm) {
       
   788         // nothing to inject
       
   789         return;
       
   790     }
   748 
   791 
   749     list_for_each_entry(datagram, &master->datagram_queue, queue) {
   792     list_for_each_entry(datagram, &master->datagram_queue, queue) {
   750         queue_size += datagram->data_size;
   793         if (datagram->state == EC_DATAGRAM_QUEUED) {
   751     }
   794             queue_size += datagram->data_size;
   752 
   795         }
   753     list_for_each_entry_safe(datagram, n, &master->external_datagram_queue,
   796     }
   754             queue) {
   797 
   755         queue_size += datagram->data_size;
       
   756         if (queue_size <= master->max_queue_size) {
       
   757             list_del_init(&datagram->queue);
       
   758 #if DEBUG_INJECT
   798 #if DEBUG_INJECT
   759             EC_MASTER_DBG(master, 0, "Injecting external datagram %08x"
   799     EC_MASTER_DBG(master, 1, "Injecting datagrams, queue_size=%zu\n",
   760                     " size=%u, queue_size=%u\n", (unsigned int) datagram,
   800             queue_size);
   761                     datagram->data_size, queue_size);
   801 #endif
       
   802 
       
   803     while (master->ext_ring_idx_rt != master->ext_ring_idx_fsm) {
       
   804         datagram = &master->ext_datagram_ring[master->ext_ring_idx_rt];
       
   805 
       
   806         if (datagram->state != EC_DATAGRAM_INIT) {
       
   807             // skip datagram
       
   808             master->ext_ring_idx_rt =
       
   809                 (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
       
   810             continue;
       
   811         }
       
   812 
       
   813         new_queue_size = queue_size + datagram->data_size;
       
   814         if (new_queue_size <= master->max_queue_size) {
       
   815 #if DEBUG_INJECT
       
   816             EC_MASTER_DBG(master, 1, "Injecting datagram %s"
       
   817                     " size=%zu, queue_size=%zu\n", datagram->name,
       
   818                     datagram->data_size, new_queue_size);
       
   819             datagram_count++;
   762 #endif
   820 #endif
   763 #ifdef EC_HAVE_CYCLES
   821 #ifdef EC_HAVE_CYCLES
   764             datagram->cycles_sent = 0;
   822             datagram->cycles_sent = 0;
   765 #endif
   823 #endif
   766             datagram->jiffies_sent = 0;
   824             datagram->jiffies_sent = 0;
   767             ec_master_queue_datagram(master, datagram);
   825             ec_master_queue_datagram(master, datagram);
   768         } else {
   826             queue_size = new_queue_size;
   769             if (datagram->data_size > master->max_queue_size) {
   827         }
   770                 list_del_init(&datagram->queue);
   828         else if (datagram->data_size > master->max_queue_size) {
       
   829             datagram->state = EC_DATAGRAM_ERROR;
       
   830             EC_MASTER_ERR(master, "External datagram %s is too large,"
       
   831                     " size=%zu, max_queue_size=%zu\n",
       
   832                     datagram->name, datagram->data_size,
       
   833                     master->max_queue_size);
       
   834         }
       
   835         else { // datagram does not fit in the current cycle
       
   836 #ifdef EC_HAVE_CYCLES
       
   837             cycles_t cycles_now = get_cycles();
       
   838 
       
   839             if (cycles_now - datagram->cycles_sent
       
   840                     > ext_injection_timeout_cycles)
       
   841 #else
       
   842             if (jiffies - datagram->jiffies_sent
       
   843                     > ext_injection_timeout_jiffies)
       
   844 #endif
       
   845             {
       
   846                 unsigned int time_us;
       
   847 
   771                 datagram->state = EC_DATAGRAM_ERROR;
   848                 datagram->state = EC_DATAGRAM_ERROR;
   772                 EC_MASTER_ERR(master, "External datagram %p is too large,"
       
   773                         " size=%zu, max_queue_size=%zu\n",
       
   774                         datagram, datagram->data_size,
       
   775                         master->max_queue_size);
       
   776             } else {
       
   777 #ifdef EC_HAVE_CYCLES
   849 #ifdef EC_HAVE_CYCLES
   778                 cycles_t cycles_now = get_cycles();
   850                 time_us = (unsigned int)
   779 
   851                     ((cycles_now - datagram->cycles_sent) * 1000LL)
   780                 if (cycles_now - datagram->cycles_sent
   852                     / cpu_khz;
   781                         > ext_injection_timeout_cycles)
       
   782 #else
   853 #else
   783                 if (jiffies - datagram->jiffies_sent
   854                 time_us = (unsigned int)
   784                         > ext_injection_timeout_jiffies)
   855                     ((jiffies - datagram->jiffies_sent) * 1000000 / HZ);
   785 #endif
   856 #endif
   786                 {
   857                 EC_MASTER_ERR(master, "Timeout %u us: Injecting"
   787                     unsigned int time_us;
   858                         " external datagram %s size=%zu,"
   788 
   859                         " max_queue_size=%zu\n", time_us, datagram->name,
   789                     list_del_init(&datagram->queue);
   860                         datagram->data_size, master->max_queue_size);
   790                     datagram->state = EC_DATAGRAM_ERROR;
   861             }
   791 #ifdef EC_HAVE_CYCLES
   862             else {
   792                     time_us = (unsigned int)
       
   793                         ((cycles_now - datagram->cycles_sent) * 1000LL)
       
   794                         / cpu_khz;
       
   795 #else
       
   796                     time_us = (unsigned int)
       
   797                         ((jiffies - datagram->jiffies_sent) * 1000000 / HZ);
       
   798 #endif
       
   799                     EC_MASTER_ERR(master, "Timeout %u us: Injecting"
       
   800                             " external datagram %p size=%zu,"
       
   801                             " max_queue_size=%zu\n", time_us, datagram,
       
   802                             datagram->data_size, master->max_queue_size);
       
   803                 }
       
   804 #if DEBUG_INJECT
   863 #if DEBUG_INJECT
   805                 else {
   864                 EC_MASTER_DBG(master, 1, "Deferred injecting"
   806                     EC_MASTER_DBG(master, 0, "Deferred injecting"
   865                         " external datagram %s size=%u, queue_size=%u\n",
   807                             " of external datagram %p"
   866                         datagram->name, datagram->data_size, queue_size);
   808                             " size=%u, queue_size=%u\n",
   867 #endif
   809                             datagram, datagram->data_size, queue_size);
   868                 break;
   810                 }
       
   811 #endif
       
   812             }
   869             }
   813         }
   870         }
   814     }
   871 
       
   872         master->ext_ring_idx_rt =
       
   873             (master->ext_ring_idx_rt + 1) % EC_EXT_RING_SIZE;
       
   874     }
       
   875 
       
   876 #if DEBUG_INJECT
       
   877     EC_MASTER_DBG(master, 1, "Injected %u datagrams.\n", datagram_count);
       
   878 #endif
   815 }
   879 }
   816 
   880 
   817 /*****************************************************************************/
   881 /*****************************************************************************/
   818 
   882 
   819 /** Sets the expected interval between calls to ecrt_master_send
   883 /** Sets the expected interval between calls to ecrt_master_send
   830     master->max_queue_size -= master->max_queue_size / 10;
   894     master->max_queue_size -= master->max_queue_size / 10;
   831 }
   895 }
   832 
   896 
   833 /*****************************************************************************/
   897 /*****************************************************************************/
   834 
   898 
   835 /** Places an external datagram in the sdo datagram queue.
   899 /** Searches for a free datagram in the external datagram ring.
   836  */
   900  */
   837 void ec_master_queue_external_datagram(
   901 ec_datagram_t *ec_master_get_external_datagram(
   838         ec_master_t *master, /**< EtherCAT master */
   902         ec_master_t *master /**< EtherCAT master */
   839         ec_datagram_t *datagram /**< datagram */
   903         )
   840         )
   904 {
   841 {
   905     if ((master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE !=
   842     ec_datagram_t *queued_datagram;
   906             master->ext_ring_idx_rt) {
   843 
   907         ec_datagram_t *datagram =
   844     down(&master->io_sem);
   908             &master->ext_datagram_ring[master->ext_ring_idx_fsm];
   845 
   909         return datagram;
   846     // check, if the datagram is already queued
   910     }
   847     list_for_each_entry(queued_datagram, &master->external_datagram_queue,
   911     else {
   848             queue) {
   912         return NULL;
   849         if (queued_datagram == datagram) {
   913     }
   850             up(&master->io_sem);
       
   851             datagram->state = EC_DATAGRAM_QUEUED;
       
   852             return;
       
   853         }
       
   854     }
       
   855 
       
   856 #if DEBUG_INJECT
       
   857     EC_MASTER_DBG(master, 0, "Requesting external datagram %p size=%u\n",
       
   858             datagram, datagram->data_size);
       
   859 #endif
       
   860 
       
   861     list_add_tail(&datagram->queue, &master->external_datagram_queue);
       
   862     datagram->state = EC_DATAGRAM_QUEUED;
       
   863 #ifdef EC_HAVE_CYCLES
       
   864     datagram->cycles_sent = get_cycles();
       
   865 #endif
       
   866     datagram->jiffies_sent = jiffies;
       
   867 
       
   868     up(&master->io_sem);
       
   869 
       
   870     master->fsm.idle = 0;
       
   871 }
   914 }
   872 
   915 
   873 /*****************************************************************************/
   916 /*****************************************************************************/
   874 
   917 
   875 /** Places a datagram in the datagram queue.
   918 /** Places a datagram in the datagram queue.
  1364 
  1407 
  1365 #endif // EC_USE_HRTIMER
  1408 #endif // EC_USE_HRTIMER
  1366 
  1409 
  1367 /*****************************************************************************/
  1410 /*****************************************************************************/
  1368 
  1411 
       
  1412 /** Execute slave FSMs.
       
  1413  */
       
  1414 void ec_master_exec_slave_fsms(
       
  1415         ec_master_t *master /**< EtherCAT master. */
       
  1416         )
       
  1417 {
       
  1418     ec_datagram_t *datagram;
       
  1419     ec_fsm_slave_t *fsm, *next;
       
  1420     unsigned int count = 0;
       
  1421 
       
  1422     list_for_each_entry_safe(fsm, next, &master->fsm_exec_list, list) {
       
  1423         if (!fsm->datagram) {
       
  1424             EC_MASTER_WARN(master, "Slave %u FSM has zero datagram."
       
  1425                     "This is a bug!\n", fsm->slave->ring_position);
       
  1426             list_del_init(&fsm->list);
       
  1427             master->fsm_exec_count--;
       
  1428             return;
       
  1429         }
       
  1430 
       
  1431         if (fsm->datagram->state == EC_DATAGRAM_INIT ||
       
  1432                 fsm->datagram->state == EC_DATAGRAM_QUEUED ||
       
  1433                 fsm->datagram->state == EC_DATAGRAM_SENT) {
       
  1434             // previous datagram was not sent or received yet.
       
  1435             // wait until next thread execution
       
  1436             return;
       
  1437         }
       
  1438 
       
  1439         datagram = ec_master_get_external_datagram(master);
       
  1440         if (!datagram) {
       
  1441             // no free datagrams at the moment
       
  1442             EC_MASTER_WARN(master, "No free datagram during"
       
  1443                     " slave FSM execution. This is a bug!\n");
       
  1444             continue;
       
  1445         }
       
  1446 
       
  1447 #if DEBUG_INJECT
       
  1448         EC_MASTER_DBG(master, 1, "Executing slave %u FSM.\n",
       
  1449                 fsm->slave->ring_position);
       
  1450 #endif
       
  1451         if (ec_fsm_slave_exec(fsm, datagram)) {
       
  1452             // FSM consumed datagram
       
  1453 #if DEBUG_INJECT
       
  1454             EC_MASTER_DBG(master, 1, "FSM consumed datagram %s\n",
       
  1455                     datagram->name);
       
  1456 #endif
       
  1457             master->ext_ring_idx_fsm =
       
  1458                 (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
       
  1459         }
       
  1460         else {
       
  1461             // FSM finished
       
  1462             list_del_init(&fsm->list);
       
  1463             master->fsm_exec_count--;
       
  1464 #if DEBUG_INJECT
       
  1465             EC_MASTER_DBG(master, 1, "FSM finished. %u remaining.\n",
       
  1466                     master->fsm_exec_count);
       
  1467 #endif
       
  1468         }
       
  1469     }
       
  1470 
       
  1471     while (master->fsm_exec_count < EC_EXT_RING_SIZE / 2
       
  1472             && count < master->slave_count) {
       
  1473 
       
  1474         if (ec_fsm_slave_is_ready(&master->fsm_slave->fsm)) {
       
  1475             datagram = ec_master_get_external_datagram(master);
       
  1476 
       
  1477             if (ec_fsm_slave_exec(&master->fsm_slave->fsm, datagram)) {
       
  1478                 master->ext_ring_idx_fsm =
       
  1479                     (master->ext_ring_idx_fsm + 1) % EC_EXT_RING_SIZE;
       
  1480                 list_add_tail(&master->fsm_slave->fsm.list,
       
  1481                         &master->fsm_exec_list);
       
  1482                 master->fsm_exec_count++;
       
  1483 #if DEBUG_INJECT
       
  1484                 EC_MASTER_DBG(master, 1, "New slave %u FSM"
       
  1485                         " consumed datagram %s, now %u FSMs in list.\n",
       
  1486                         master->fsm_slave->ring_position, datagram->name,
       
  1487                         master->fsm_exec_count);
       
  1488 #endif
       
  1489             }
       
  1490         }
       
  1491 
       
  1492         master->fsm_slave++;
       
  1493         if (master->fsm_slave >= master->slaves + master->slave_count) {
       
  1494             master->fsm_slave = master->slaves;
       
  1495         }
       
  1496         count++;
       
  1497     }
       
  1498 }
       
  1499 
       
  1500 /*****************************************************************************/
       
  1501 
  1369 /** Master kernel thread function for IDLE phase.
  1502 /** Master kernel thread function for IDLE phase.
  1370  */
  1503  */
  1371 static int ec_master_idle_thread(void *priv_data)
  1504 static int ec_master_idle_thread(void *priv_data)
  1372 {
  1505 {
  1373     ec_master_t *master = (ec_master_t *) priv_data;
  1506     ec_master_t *master = (ec_master_t *) priv_data;
  1374     ec_slave_t *slave = NULL;
       
  1375     int fsm_exec;
  1507     int fsm_exec;
  1376 #ifdef EC_USE_HRTIMER
  1508 #ifdef EC_USE_HRTIMER
  1377     size_t sent_bytes;
  1509     size_t sent_bytes;
  1378 #endif
  1510 #endif
  1379 
  1511 
  1390         // receive
  1522         // receive
  1391         down(&master->io_sem);
  1523         down(&master->io_sem);
  1392         ecrt_master_receive(master);
  1524         ecrt_master_receive(master);
  1393         up(&master->io_sem);
  1525         up(&master->io_sem);
  1394 
  1526 
  1395         fsm_exec = 0;
       
  1396 
       
  1397         // execute master & slave state machines
  1527         // execute master & slave state machines
  1398         if (down_interruptible(&master->master_sem)) {
  1528         if (down_interruptible(&master->master_sem)) {
  1399             break;
  1529             break;
  1400         }
  1530         }
  1401 
  1531 
  1402         fsm_exec = ec_fsm_master_exec(&master->fsm);
  1532         fsm_exec = ec_fsm_master_exec(&master->fsm);
  1403 
  1533 
  1404         for (slave = master->slaves;
  1534         ec_master_exec_slave_fsms(master);
  1405                 slave < master->slaves + master->slave_count;
       
  1406                 slave++) {
       
  1407             ec_fsm_slave_exec(&slave->fsm);
       
  1408         }
       
  1409 
  1535 
  1410         up(&master->master_sem);
  1536         up(&master->master_sem);
  1411 
  1537 
  1412         // queue and send
  1538         // queue and send
  1413         down(&master->io_sem);
  1539         down(&master->io_sem);
  1447 /** Master kernel thread function for OPERATION phase.
  1573 /** Master kernel thread function for OPERATION phase.
  1448  */
  1574  */
  1449 static int ec_master_operation_thread(void *priv_data)
  1575 static int ec_master_operation_thread(void *priv_data)
  1450 {
  1576 {
  1451     ec_master_t *master = (ec_master_t *) priv_data;
  1577     ec_master_t *master = (ec_master_t *) priv_data;
  1452     ec_slave_t *slave = NULL;
       
  1453     int fsm_exec;
       
  1454 
  1578 
  1455     EC_MASTER_DBG(master, 1, "Operation thread running"
  1579     EC_MASTER_DBG(master, 1, "Operation thread running"
  1456             " with fsm interval = %u us, max data size=%zu\n",
  1580             " with fsm interval = %u us, max data size=%zu\n",
  1457             master->send_interval, master->max_queue_size);
  1581             master->send_interval, master->max_queue_size);
  1458 
  1582 
  1460         ec_datagram_output_stats(&master->fsm_datagram);
  1584         ec_datagram_output_stats(&master->fsm_datagram);
  1461 
  1585 
  1462         if (master->injection_seq_rt == master->injection_seq_fsm) {
  1586         if (master->injection_seq_rt == master->injection_seq_fsm) {
  1463             // output statistics
  1587             // output statistics
  1464             ec_master_output_stats(master);
  1588             ec_master_output_stats(master);
  1465 
       
  1466             fsm_exec = 0;
       
  1467 
  1589 
  1468             // execute master & slave state machines
  1590             // execute master & slave state machines
  1469             if (down_interruptible(&master->master_sem)) {
  1591             if (down_interruptible(&master->master_sem)) {
  1470                 break;
  1592                 break;
  1471             }
  1593             }
  1472 
  1594 
  1473             fsm_exec += ec_fsm_master_exec(&master->fsm);
  1595             if (ec_fsm_master_exec(&master->fsm)) {
  1474 
  1596                 // Inject datagrams (let the RT thread queue them, see
  1475             for (slave = master->slaves;
  1597                 // ecrt_master_send())
  1476                     slave < master->slaves + master->slave_count;
       
  1477                     slave++) {
       
  1478                 ec_fsm_slave_exec(&slave->fsm);
       
  1479             }
       
  1480 
       
  1481             up(&master->master_sem);
       
  1482 
       
  1483             // Inject datagrams (let the RT thread queue them, see
       
  1484             // ecrt_master_send())
       
  1485             if (fsm_exec) {
       
  1486                 master->injection_seq_fsm++;
  1598                 master->injection_seq_fsm++;
  1487             }
  1599             }
       
  1600 
       
  1601             ec_master_exec_slave_fsms(master);
       
  1602 
       
  1603             up(&master->master_sem);
  1488         }
  1604         }
  1489 
  1605 
  1490 #ifdef EC_USE_HRTIMER
  1606 #ifdef EC_USE_HRTIMER
  1491         // the op thread should not work faster than the sending RT thread
  1607         // the op thread should not work faster than the sending RT thread
  1492         ec_master_nanosleep(master->send_interval * 1000);
  1608         ec_master_nanosleep(master->send_interval * 1000);
  2280 {
  2396 {
  2281     ec_datagram_t *datagram, *n;
  2397     ec_datagram_t *datagram, *n;
  2282     ec_device_index_t dev_idx;
  2398     ec_device_index_t dev_idx;
  2283 
  2399 
  2284     if (master->injection_seq_rt != master->injection_seq_fsm) {
  2400     if (master->injection_seq_rt != master->injection_seq_fsm) {
  2285         // inject datagrams produced by master FSM
  2401         // inject datagram produced by master FSM
  2286         ec_master_queue_datagram(master, &master->fsm_datagram);
  2402         ec_master_queue_datagram(master, &master->fsm_datagram);
  2287         master->injection_seq_rt = master->injection_seq_fsm;
  2403         master->injection_seq_rt = master->injection_seq_fsm;
  2288     }
  2404     }
  2289 
  2405 
  2290     ec_master_inject_external_datagrams(master);
  2406     ec_master_inject_external_datagrams(master);