master/master.c
changeset 2094 83e9160319ec
parent 2084 eefccfa312ef
child 2095 53b5128e1313
equal deleted inserted replaced
2093:c7e7d80e49ea 2094:83e9160319ec
   672         )
   672         )
   673 {
   673 {
   674     ec_datagram_t *datagram, *next;
   674     ec_datagram_t *datagram, *next;
   675     size_t queue_size = 0;
   675     size_t queue_size = 0;
   676 
   676 
   677     if (master->fsm_queue_lock_cb)
   677     if (master->fsm_queue_lock_cb) {
   678         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
   678         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
       
   679     }
       
   680 
   679     if (ec_mutex_trylock(&master->fsm_queue_mutex) == 0) {
   681     if (ec_mutex_trylock(&master->fsm_queue_mutex) == 0) {
   680            if (master->fsm_queue_unlock_cb)
   682         goto unlock_cb;
   681                master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
   683     }
   682            return;
   684 
   683     }
       
   684     if (list_empty(&master->fsm_datagram_queue)) {
   685     if (list_empty(&master->fsm_datagram_queue)) {
   685         ec_mutex_unlock(&master->fsm_queue_mutex);
   686         goto unlock;
   686         if (master->fsm_queue_unlock_cb)
   687     }
   687             master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
   688 
   688         return;
       
   689     }
       
   690     list_for_each_entry(datagram, &master->datagram_queue, queue) {
   689     list_for_each_entry(datagram, &master->datagram_queue, queue) {
   691         queue_size += datagram->data_size;
   690         queue_size += datagram->data_size;
   692     }
   691     }
   693 
   692 
   694     list_for_each_entry_safe(datagram, next, &master->fsm_datagram_queue,
   693     list_for_each_entry_safe(datagram, next, &master->fsm_datagram_queue,
   702                     datagram->data_size, queue_size);
   701                     datagram->data_size, queue_size);
   703 #endif
   702 #endif
   704 #ifdef EC_HAVE_CYCLES
   703 #ifdef EC_HAVE_CYCLES
   705             datagram->cycles_sent = 0;
   704             datagram->cycles_sent = 0;
   706 #endif
   705 #endif
   707             datagram->jiffies_sent = 0;
   706             datagram->jiffies_sent = 0; // FIXME why?
   708             ec_master_queue_datagram(master, datagram);
   707             ec_master_queue_datagram(master, datagram);
   709         }
   708         } else {
   710         else {
       
   711             if (datagram->data_size > master->max_queue_size) {
   709             if (datagram->data_size > master->max_queue_size) {
   712                 list_del_init(&datagram->fsm_queue);
   710                 list_del_init(&datagram->fsm_queue);
   713                 datagram->state = EC_DATAGRAM_ERROR;
   711                 datagram->state = EC_DATAGRAM_ERROR;
   714                 EC_MASTER_ERR(master, "Fsm datagram %p is too large,"
   712                 EC_MASTER_ERR(master, "Fsm datagram %p is too large,"
   715                         " size=%zu, max_queue_size=%zu\n",
   713                         " size=%zu, max_queue_size=%zu\n",
   752                 }
   750                 }
   753 #endif
   751 #endif
   754             }
   752             }
   755         }
   753         }
   756     }
   754     }
       
   755 
       
   756 unlock:
   757     ec_mutex_unlock(&master->fsm_queue_mutex);
   757     ec_mutex_unlock(&master->fsm_queue_mutex);
   758     if (master->fsm_queue_unlock_cb)
   758 unlock_cb:
       
   759     if (master->fsm_queue_unlock_cb) {
   759         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
   760         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
       
   761     }
   760 }
   762 }
   761 
   763 
   762 /*****************************************************************************/
   764 /*****************************************************************************/
   763 
   765 
   764 /** Sets the expected interval between calls to ecrt_master_send
   766 /** Sets the expected interval between calls to ecrt_master_send
   775     master->max_queue_size -= master->max_queue_size / 10;
   777     master->max_queue_size -= master->max_queue_size / 10;
   776 }
   778 }
   777 
   779 
   778 /*****************************************************************************/
   780 /*****************************************************************************/
   779 
   781 
   780 /** Places an request (SDO/FoE/SoE/EoE) fsm datagram in the sdo datagram queue.
   782 /** Places an request (SDO/FoE/SoE/EoE) fsm datagram in the sdo datagram
       
   783  * queue.
   781  */
   784  */
   782 void ec_master_queue_request_fsm_datagram(
   785 void ec_master_queue_request_fsm_datagram(
   783         ec_master_t *master, /**< EtherCAT master */
   786         ec_master_t *master, /**< EtherCAT master */
   784         ec_datagram_t *datagram /**< datagram */
   787         ec_datagram_t *datagram /**< datagram */
   785         )
   788         )
   786 {
   789 {
   787     ec_master_queue_fsm_datagram(master,datagram);
   790     ec_master_queue_fsm_datagram(master, datagram);
   788     master->fsm.idle = 0;   // pump the bus as fast as possible
   791     master->fsm.idle = 0; // pump the bus as fast as possible
   789 }
   792 }
   790 
   793 
   791 /*****************************************************************************/
   794 /*****************************************************************************/
   792 
   795 
   793 /** Places an fsm datagram in the sdo datagram queue.
   796 /** Places an fsm datagram in the sdo datagram queue.
   797         ec_datagram_t *datagram /**< datagram */
   800         ec_datagram_t *datagram /**< datagram */
   798         )
   801         )
   799 {
   802 {
   800     ec_datagram_t *queued_datagram;
   803     ec_datagram_t *queued_datagram;
   801 
   804 
   802     if (master->fsm_queue_lock_cb)
   805     if (master->fsm_queue_lock_cb) {
   803         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
   806         master->fsm_queue_lock_cb(master->fsm_queue_locking_data);
       
   807     }
   804     ec_mutex_lock(&master->fsm_queue_mutex);
   808     ec_mutex_lock(&master->fsm_queue_mutex);
   805 
   809 
   806     // check, if the datagram is already queued
   810     // check, if the datagram is already queued
   807     list_for_each_entry(queued_datagram, &master->fsm_datagram_queue,
   811     list_for_each_entry(queued_datagram, &master->fsm_datagram_queue,
   808             fsm_queue) {
   812             fsm_queue) {
   809         if (queued_datagram == datagram) {
   813         if (queued_datagram == datagram) {
   810             datagram->state = EC_DATAGRAM_QUEUED;
   814             datagram->state = EC_DATAGRAM_QUEUED;
   811             ec_mutex_unlock(&master->fsm_queue_mutex);
   815             goto unlock;
   812             if (master->fsm_queue_unlock_cb)
       
   813                 master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
       
   814             return;
       
   815         }
   816         }
   816     }
   817     }
   817 
   818 
   818 #if DEBUG_INJECT
   819 #if DEBUG_INJECT
   819     EC_MASTER_DBG(master, 2, "Requesting fsm datagram %p size=%zu\n",
   820     EC_MASTER_DBG(master, 2, "Requesting fsm datagram %p size=%zu\n",
   823     list_add_tail(&datagram->fsm_queue, &master->fsm_datagram_queue);
   824     list_add_tail(&datagram->fsm_queue, &master->fsm_datagram_queue);
   824     datagram->state = EC_DATAGRAM_QUEUED;
   825     datagram->state = EC_DATAGRAM_QUEUED;
   825 #ifdef EC_HAVE_CYCLES
   826 #ifdef EC_HAVE_CYCLES
   826     datagram->cycles_sent = get_cycles();
   827     datagram->cycles_sent = get_cycles();
   827 #endif
   828 #endif
   828     datagram->jiffies_sent = jiffies;
   829     datagram->jiffies_sent = jiffies; // FIXME why?
   829 
   830 
       
   831 unlock:
   830     ec_mutex_unlock(&master->fsm_queue_mutex);
   832     ec_mutex_unlock(&master->fsm_queue_mutex);
   831     if (master->fsm_queue_unlock_cb)
   833     if (master->fsm_queue_unlock_cb) {
   832         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
   834         master->fsm_queue_unlock_cb(master->fsm_queue_locking_data);
       
   835     }
   833 }
   836 }
   834 
   837 
   835 /*****************************************************************************/
   838 /*****************************************************************************/
   836 
   839 
   837 /** Places a datagram in the datagram queue.
   840 /** Places a datagram in the datagram queue.
   927             }
   930             }
   928 
   931 
   929             list_add_tail(&datagram->sent, &sent_datagrams);
   932             list_add_tail(&datagram->sent, &sent_datagrams);
   930             datagram->index = master->datagram_index++;
   933             datagram->index = master->datagram_index++;
   931 
   934 
   932             EC_MASTER_DBG(master, 2, "adding datagram %p i=0x%02X size=%zu\n",datagram,
   935             EC_MASTER_DBG(master, 2, "Adding datagram %p i=0x%02X size=%zu\n",
   933                     datagram->index,datagram_size);
   936                     datagram, datagram->index,datagram_size);
   934 
   937 
   935             // set "datagram following" flag in previous frame
   938             // set "datagram following" flag in previous frame
   936             if (follows_word)
   939             if (follows_word) {
   937                 EC_WRITE_U16(follows_word, EC_READ_U16(follows_word) | 0x8000);
   940                 EC_WRITE_U16(follows_word,
       
   941                         EC_READ_U16(follows_word) | 0x8000);
       
   942             }
   938 
   943 
   939             // EtherCAT datagram header
   944             // EtherCAT datagram header
   940             EC_WRITE_U8 (cur_data,     datagram->type);
   945             EC_WRITE_U8 (cur_data,     datagram->type);
   941             EC_WRITE_U8 (cur_data + 1, datagram->index);
   946             EC_WRITE_U8 (cur_data + 1, datagram->index);
   942             memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
   947             memcpy(cur_data + 2, datagram->address, EC_ADDR_LEN);
   946             cur_data += EC_DATAGRAM_HEADER_SIZE;
   951             cur_data += EC_DATAGRAM_HEADER_SIZE;
   947 
   952 
   948             // EtherCAT datagram data
   953             // EtherCAT datagram data
   949             frame_datagram_data = cur_data;
   954             frame_datagram_data = cur_data;
   950             if (datagram->domain) {
   955             if (datagram->domain) {
   951                 unsigned int datagram_address = EC_READ_U32(datagram->address);
   956                 unsigned int datagram_address =
       
   957                     EC_READ_U32(datagram->address);
   952                 int i = 0;
   958                 int i = 0;
   953                 uint8_t *domain_data = datagram->data;
   959                 uint8_t *domain_data = datagram->data;
   954                 list_for_each_entry(domain_fmmu, &datagram->domain->fmmu_configs, list) {
   960                 list_for_each_entry(domain_fmmu,
       
   961                         &datagram->domain->fmmu_configs, list) {
   955                     if (domain_fmmu->dir == EC_DIR_OUTPUT ) {
   962                     if (domain_fmmu->dir == EC_DIR_OUTPUT ) {
   956                         unsigned int frame_offset = domain_fmmu->logical_start_address-datagram_address;
   963                         unsigned int frame_offset =
   957                         memcpy(frame_datagram_data+frame_offset, domain_data, domain_fmmu->data_size);
   964                             domain_fmmu->logical_start_address
       
   965                             - datagram_address;
       
   966                         memcpy(frame_datagram_data+frame_offset, domain_data,
       
   967                                 domain_fmmu->data_size);
   958                         if (unlikely(master->debug_level > 1)) {
   968                         if (unlikely(master->debug_level > 1)) {
   959                             EC_DBG("sending dg %p i=0x%02X fmmu %u fp=%u dp=%zu size=%u\n",
   969                             EC_DBG("sending dg %p i=0x%02X fmmu %u fp=%u"
   960                                    datagram,datagram->index, i,frame_offset,domain_data-datagram->data,domain_fmmu->data_size);
   970                                     " dp=%zu size=%u\n",
   961                             ec_print_data(domain_data, domain_fmmu->data_size);
   971                                    datagram, datagram->index, i,
       
   972                                    frame_offset,
       
   973                                    domain_data - datagram->data,
       
   974                                    domain_fmmu->data_size);
       
   975                             ec_print_data(domain_data,
       
   976                                     domain_fmmu->data_size);
   962                         }
   977                         }
   963                     }
   978                     }
   964                     domain_data += domain_fmmu->data_size;
   979                     domain_data += domain_fmmu->data_size;
   965                     ++i;
   980                     ++i;
   966                 }
   981                 }
   967             }
   982             } else {
   968             else {
   983                 memcpy(frame_datagram_data, datagram->data,
   969                 memcpy(frame_datagram_data, datagram->data, datagram->data_size);
   984                         datagram->data_size);
   970             }
   985             }
   971             cur_data += datagram->data_size;
   986             cur_data += datagram->data_size;
   972 
   987 
   973             // EtherCAT datagram footer
   988             // EtherCAT datagram footer
   974             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
   989             EC_WRITE_U16(cur_data, 0x0000); // reset working counter
  1121 
  1136 
  1122             cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
  1137             cur_data += data_size + EC_DATAGRAM_FOOTER_SIZE;
  1123             continue;
  1138             continue;
  1124         }
  1139         }
  1125         frame_datagram_data = cur_data;
  1140         frame_datagram_data = cur_data;
       
  1141 
  1126         if (datagram->domain) {
  1142         if (datagram->domain) {
  1127             size_t datagram_address = EC_READ_U32(datagram->address);
  1143             size_t datagram_address = EC_READ_U32(datagram->address);
  1128             int i = 0;
  1144             int i = 0;
  1129             uint8_t *domain_data = datagram->data;
  1145             uint8_t *domain_data = datagram->data;
  1130             list_for_each_entry(domain_fmmu, &datagram->domain->fmmu_configs, list) {
  1146 
  1131                 if (domain_fmmu->dir == EC_DIR_INPUT ) {
  1147             list_for_each_entry(domain_fmmu, &datagram->domain->fmmu_configs,
  1132                     unsigned int frame_offset = domain_fmmu->logical_start_address-datagram_address;
  1148                     list) {
  1133                     memcpy(domain_data, frame_datagram_data+frame_offset, domain_fmmu->data_size);
  1149                 if (domain_fmmu->dir == EC_DIR_INPUT) {
       
  1150                     unsigned int frame_offset =
       
  1151                         domain_fmmu->logical_start_address - datagram_address;
       
  1152                     memcpy(domain_data, frame_datagram_data + frame_offset,
       
  1153                             domain_fmmu->data_size);
  1134                     if (unlikely(master->debug_level > 1)) {
  1154                     if (unlikely(master->debug_level > 1)) {
  1135                         EC_DBG("receiving dg %p i=0x%02X fmmu %u fp=%u dp=%zu size=%u\n",
  1155                         EC_DBG("receiving dg %p i=0x%02X fmmu %u fp=%u"
  1136                                datagram,datagram->index, i,
  1156                                 " dp=%zu size=%u\n",
  1137                                frame_offset,domain_data-datagram->data,domain_fmmu->data_size);
  1157                                datagram, datagram->index, i,
       
  1158                                frame_offset, domain_data - datagram->data,
       
  1159                                domain_fmmu->data_size);
  1138                         ec_print_data(domain_data, domain_fmmu->data_size);
  1160                         ec_print_data(domain_data, domain_fmmu->data_size);
  1139                     }
  1161                     }
  1140                 }
  1162                 }
  1141                 domain_data += domain_fmmu->data_size;
  1163                 domain_data += domain_fmmu->data_size;
  1142                 ++i;
  1164                 ++i;
  1143             }
  1165             }
  1144         }
  1166         } else {
  1145         else {
       
  1146             // copy received data into the datagram memory
  1167             // copy received data into the datagram memory
  1147             memcpy(datagram->data, frame_datagram_data, data_size);
  1168             memcpy(datagram->data, frame_datagram_data, data_size);
  1148         }
  1169         }
  1149         cur_data += data_size;
  1170         cur_data += data_size;
  1150 
  1171 
  1280 static int ec_master_idle_thread(void *priv_data)
  1301 static int ec_master_idle_thread(void *priv_data)
  1281 {
  1302 {
  1282     ec_master_t *master = (ec_master_t *) priv_data;
  1303     ec_master_t *master = (ec_master_t *) priv_data;
  1283     ec_slave_t *slave = NULL;
  1304     ec_slave_t *slave = NULL;
  1284     size_t sent_bytes;
  1305     size_t sent_bytes;
       
  1306 
  1285     // send interval in IDLE phase
  1307     // send interval in IDLE phase
  1286     ec_master_set_send_interval(master, 1000000 / HZ); 
  1308     ec_master_set_send_interval(master, 1000000 / HZ); 
  1287 
  1309 
  1288     EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
  1310     EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
  1289             " max data size=%zu\n", master->send_interval,
  1311             " max data size=%zu\n", master->send_interval,
  1296         ec_mutex_lock(&master->io_mutex);
  1318         ec_mutex_lock(&master->io_mutex);
  1297         ecrt_master_receive(master);
  1319         ecrt_master_receive(master);
  1298         ec_mutex_unlock(&master->io_mutex);
  1320         ec_mutex_unlock(&master->io_mutex);
  1299 
  1321 
  1300         // execute master & slave state machines
  1322         // execute master & slave state machines
  1301         if (ec_mutex_lock_interruptible(&master->master_mutex))
  1323         if (ec_mutex_lock_interruptible(&master->master_mutex)) {
  1302             break;
  1324             break;
       
  1325         }
  1303         if (ec_fsm_master_exec(&master->fsm)) {
  1326         if (ec_fsm_master_exec(&master->fsm)) {
  1304             ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
  1327             ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
  1305         }
  1328         }
  1306         for (slave = master->slaves;
  1329         for (slave = master->slaves;
  1307                 slave < master->slaves + master->slave_count;
  1330                 slave < master->slaves + master->slave_count;
  1308                 slave++) {
  1331                 slave++) {
  1309             ec_fsm_slave_exec(&slave->fsm); // may queue datagram in fsm queue
  1332             ec_fsm_slave_exec(&slave->fsm); // may queue datagram in fsm queue
  1310         }
  1333         }
  1311 #if defined(EC_EOE)
  1334 #if defined(EC_EOE)
  1312         if (!ec_master_eoe_processing(master))
  1335         if (!ec_master_eoe_processing(master)) {
  1313             master->fsm.idle = 0;  // pump the bus as fast as possible
  1336             master->fsm.idle = 0; // pump the bus as fast as possible
       
  1337         }
  1314 #endif
  1338 #endif
  1315         ec_mutex_unlock(&master->master_mutex);
  1339         ec_mutex_unlock(&master->master_mutex);
  1316 
  1340 
  1317         // queue and send
  1341         // queue and send
  1318         ec_mutex_lock(&master->io_mutex);
  1342         ec_mutex_lock(&master->io_mutex);
  1360 
  1384 
  1361         // output statistics
  1385         // output statistics
  1362         ec_master_output_stats(master);
  1386         ec_master_output_stats(master);
  1363 
  1387 
  1364         // execute master & slave state machines
  1388         // execute master & slave state machines
  1365         if (ec_mutex_lock_interruptible(&master->master_mutex))
  1389         if (ec_mutex_lock_interruptible(&master->master_mutex)) {
  1366             break;
  1390             break;
  1367         if (ec_fsm_master_exec(&master->fsm))
  1391         }
       
  1392         if (ec_fsm_master_exec(&master->fsm)) {
  1368             ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
  1393             ec_master_mbox_queue_datagrams(master, &master->fsm_mbox);
       
  1394         }
  1369         for (slave = master->slaves;
  1395         for (slave = master->slaves;
  1370                 slave < master->slaves + master->slave_count;
  1396                 slave < master->slaves + master->slave_count;
  1371                 slave++) {
  1397                 slave++) {
  1372             ec_fsm_slave_exec(&slave->fsm); // may queue datagram in fsm queue
  1398             ec_fsm_slave_exec(&slave->fsm); // may queue datagram in fsm queue
  1373         }
  1399         }
  2078 
  2104 
  2079     ec_master_inject_fsm_datagrams(master);
  2105     ec_master_inject_fsm_datagrams(master);
  2080 
  2106 
  2081     if (unlikely(!master->main_device.link_state)) {
  2107     if (unlikely(!master->main_device.link_state)) {
  2082         // link is down, no datagram can be sent
  2108         // link is down, no datagram can be sent
  2083         list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
  2109         list_for_each_entry_safe(datagram, next, &master->datagram_queue,
       
  2110                 queue) {
  2084             datagram->state = EC_DATAGRAM_ERROR;
  2111             datagram->state = EC_DATAGRAM_ERROR;
  2085             list_del_init(&datagram->queue);
  2112             list_del_init(&datagram->queue);
  2086         }
  2113         }
  2087 
  2114 
  2088         // query link state
  2115         // query link state