master/master.c
changeset 1313 ed15eef57d5c
parent 1312 74853e018898
child 1326 ef907b0b5125
equal deleted inserted replaced
1312:74853e018898 1313:ed15eef57d5c
   109         const uint8_t *backup_mac, /**< MAC address of backup device */
   109         const uint8_t *backup_mac, /**< MAC address of backup device */
   110         dev_t device_number, /**< Character device number. */
   110         dev_t device_number, /**< Character device number. */
   111         struct class *class /**< Device class. */
   111         struct class *class /**< Device class. */
   112         )
   112         )
   113 {
   113 {
       
   114     int ret;
       
   115 
   114     master->index = index;
   116     master->index = index;
   115     master->reserved = 0;
   117     master->reserved = 0;
   116 
   118 
   117     init_MUTEX(&master->master_sem);
   119     init_MUTEX(&master->master_sem);
   118 
   120 
   174 
   176 
   175     INIT_LIST_HEAD(&master->phy_requests);
   177     INIT_LIST_HEAD(&master->phy_requests);
   176     init_waitqueue_head(&master->phy_queue);
   178     init_waitqueue_head(&master->phy_queue);
   177 
   179 
   178     // init devices
   180     // init devices
   179     if (ec_device_init(&master->main_device, master))
   181     ret = ec_device_init(&master->main_device, master);
       
   182     if (ret < 0)
   180         goto out_return;
   183         goto out_return;
   181 
   184 
   182     if (ec_device_init(&master->backup_device, master))
   185     ret = ec_device_init(&master->backup_device, master);
       
   186     if (ret < 0)
   183         goto out_clear_main;
   187         goto out_clear_main;
   184 
   188 
   185     // init state machine datagram
   189     // init state machine datagram
   186     ec_datagram_init(&master->fsm_datagram);
   190     ec_datagram_init(&master->fsm_datagram);
   187     snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
   191     snprintf(master->fsm_datagram.name, EC_DATAGRAM_NAME_SIZE, "master-fsm");
   188     if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) {
   192     ret = ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE);
       
   193     if (ret < 0) {
   189         EC_ERR("Failed to allocate FSM datagram.\n");
   194         EC_ERR("Failed to allocate FSM datagram.\n");
   190         goto out_clear_backup;
   195         goto out_clear_backup;
   191     }
   196     }
   192 
   197 
   193     // create state machine object
   198     // create state machine object
   194     ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
   199     ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram);
   195 
   200 
   196     // init character device
   201     // init character device
   197     if (ec_cdev_init(&master->cdev, master, device_number))
   202     ret = ec_cdev_init(&master->cdev, master, device_number);
       
   203     if (ret)
   198         goto out_clear_fsm;
   204         goto out_clear_fsm;
   199     
   205     
   200 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
   206 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
   201     master->class_device = device_create(class, NULL,
   207     master->class_device = device_create(class, NULL,
   202             MKDEV(MAJOR(device_number), master->index),
   208             MKDEV(MAJOR(device_number), master->index),
   210             MKDEV(MAJOR(device_number), master->index),
   216             MKDEV(MAJOR(device_number), master->index),
   211             NULL, "EtherCAT%u", master->index);
   217             NULL, "EtherCAT%u", master->index);
   212 #endif
   218 #endif
   213     if (IS_ERR(master->class_device)) {
   219     if (IS_ERR(master->class_device)) {
   214         EC_ERR("Failed to create class device!\n");
   220         EC_ERR("Failed to create class device!\n");
       
   221         ret = PTR_ERR(master->class_device);
   215         goto out_clear_cdev;
   222         goto out_clear_cdev;
   216     }
   223     }
   217 
   224 
   218     return 0;
   225     return 0;
   219 
   226 
   225 out_clear_backup:
   232 out_clear_backup:
   226     ec_device_clear(&master->backup_device);
   233     ec_device_clear(&master->backup_device);
   227 out_clear_main:
   234 out_clear_main:
   228     ec_device_clear(&master->main_device);
   235     ec_device_clear(&master->main_device);
   229 out_return:
   236 out_return:
   230     return -1;
   237     return ret;
   231 }
   238 }
   232 
   239 
   233 /*****************************************************************************/
   240 /*****************************************************************************/
   234 
   241 
   235 /** Destructor.
   242 /** Destructor.
   347 }
   354 }
   348 
   355 
   349 /*****************************************************************************/
   356 /*****************************************************************************/
   350 
   357 
   351 /** Starts the master thread.
   358 /** Starts the master thread.
       
   359  *
       
   360  * \retval  0 Success.
       
   361  * \retval <0 Error code.
   352  */
   362  */
   353 int ec_master_thread_start(
   363 int ec_master_thread_start(
   354         ec_master_t *master, /**< EtherCAT master */
   364         ec_master_t *master, /**< EtherCAT master */
   355         int (*thread_func)(void *), /**< thread function to start */
   365         int (*thread_func)(void *), /**< thread function to start */
   356         const char *name /**< Thread name. */
   366         const char *name /**< Thread name. */
   357         )
   367         )
   358 {
   368 {
   359     EC_INFO("Starting %s thread.\n", name);
   369     EC_INFO("Starting %s thread.\n", name);
   360     master->thread = kthread_run(thread_func, master, name);
   370     master->thread = kthread_run(thread_func, master, name);
   361     if (IS_ERR(master->thread)) {
   371     if (IS_ERR(master->thread)) {
   362         EC_ERR("Failed to start master thread (error %i)!\n",
   372         int err = (int) PTR_ERR(master->thread);
   363                 (int) PTR_ERR(master->thread));
   373         EC_ERR("Failed to start master thread (error %i)!\n", err);
   364         master->thread = NULL;
   374         master->thread = NULL;
   365         return -1;
   375         return err;
   366     }
   376     }
   367     
   377     
   368     return 0;
   378     return 0;
   369 }
   379 }
   370 
   380 
   404  */
   414  */
   405 int ec_master_enter_idle_phase(
   415 int ec_master_enter_idle_phase(
   406         ec_master_t *master /**< EtherCAT master */
   416         ec_master_t *master /**< EtherCAT master */
   407         )
   417         )
   408 {
   418 {
       
   419     int ret;
       
   420 
   409     if (master->debug_level)
   421     if (master->debug_level)
   410         EC_DBG("ORPHANED -> IDLE.\n");
   422         EC_DBG("ORPHANED -> IDLE.\n");
   411 
   423 
   412     master->request_cb = ec_master_request_cb;
   424     master->request_cb = ec_master_request_cb;
   413     master->release_cb = ec_master_release_cb;
   425     master->release_cb = ec_master_release_cb;
   414     master->cb_data = master;
   426     master->cb_data = master;
   415 
   427 
   416     master->phase = EC_IDLE;
   428     master->phase = EC_IDLE;
   417     if (ec_master_thread_start(master, ec_master_idle_thread,
   429     ret = ec_master_thread_start(master, ec_master_idle_thread,
   418                 "EtherCAT-IDLE")) {
   430             "EtherCAT-IDLE");
       
   431     if (ret)
   419         master->phase = EC_ORPHANED;
   432         master->phase = EC_ORPHANED;
   420         return -1;
   433 
   421     }
   434     return ret;
   422 
       
   423     return 0;
       
   424 }
   435 }
   425 
   436 
   426 /*****************************************************************************/
   437 /*****************************************************************************/
   427 
   438 
   428 /** Transition function from IDLE to ORPHANED phase.
   439 /** Transition function from IDLE to ORPHANED phase.
   448 
   459 
   449 /** Transition function from IDLE to OPERATION phase.
   460 /** Transition function from IDLE to OPERATION phase.
   450  */
   461  */
   451 int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
   462 int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
   452 {
   463 {
       
   464     int ret = 0;
   453     ec_slave_t *slave;
   465     ec_slave_t *slave;
   454 #ifdef EC_EOE
   466 #ifdef EC_EOE
   455     ec_eoe_t *eoe;
   467     ec_eoe_t *eoe;
   456 #endif
   468 #endif
   457 
   469 
   462     master->allow_config = 0; // temporarily disable slave configuration
   474     master->allow_config = 0; // temporarily disable slave configuration
   463     if (master->config_busy) {
   475     if (master->config_busy) {
   464         up(&master->config_sem);
   476         up(&master->config_sem);
   465 
   477 
   466         // wait for slave configuration to complete
   478         // wait for slave configuration to complete
   467         if (wait_event_interruptible(master->config_queue,
   479         ret = wait_event_interruptible(master->config_queue,
   468                     !master->config_busy)) {
   480                     !master->config_busy);
       
   481         if (ret) {
   469             EC_INFO("Finishing slave configuration interrupted by signal.\n");
   482             EC_INFO("Finishing slave configuration interrupted by signal.\n");
   470             goto out_allow;
   483             goto out_allow;
   471         }
   484         }
   472 
   485 
   473         if (master->debug_level)
   486         if (master->debug_level)
   482         up(&master->scan_sem);
   495         up(&master->scan_sem);
   483     } else {
   496     } else {
   484         up(&master->scan_sem);
   497         up(&master->scan_sem);
   485 
   498 
   486         // wait for slave scan to complete
   499         // wait for slave scan to complete
   487         if (wait_event_interruptible(master->scan_queue, !master->scan_busy)) {
   500         ret = wait_event_interruptible(master->scan_queue, !master->scan_busy);
       
   501         if (ret) {
   488             EC_INFO("Waiting for slave scan interrupted by signal.\n");
   502             EC_INFO("Waiting for slave scan interrupted by signal.\n");
   489             goto out_allow;
   503             goto out_allow;
   490         }
   504         }
   491         
   505         
   492         if (master->debug_level)
   506         if (master->debug_level)
   509 
   523 
   510     master->phase = EC_OPERATION;
   524     master->phase = EC_OPERATION;
   511     master->ext_request_cb = NULL;
   525     master->ext_request_cb = NULL;
   512     master->ext_release_cb = NULL;
   526     master->ext_release_cb = NULL;
   513     master->ext_cb_data = NULL;
   527     master->ext_cb_data = NULL;
   514     return 0;
   528     return ret;
   515     
   529     
   516 out_allow:
   530 out_allow:
   517     master->allow_scan = 1;
   531     master->allow_scan = 1;
   518     master->allow_config = 1;
   532     master->allow_config = 1;
   519     return -1;
   533     return ret;
   520 }
   534 }
   521 
   535 
   522 /*****************************************************************************/
   536 /*****************************************************************************/
   523 
   537 
   524 /** Transition function from OPERATION to IDLE phase.
   538 /** Transition function from OPERATION to IDLE phase.
  1273 
  1287 
  1274 /*****************************************************************************/
  1288 /*****************************************************************************/
  1275 
  1289 
  1276 /** Set the debug level.
  1290 /** Set the debug level.
  1277  *
  1291  *
  1278  * \retval 0 Success.
  1292  * \retval       0 Success.
  1279  * \retval -1 Invalid debug level.
  1293  * \retval -EINVAL Invalid debug level.
  1280  */
  1294  */
  1281 int ec_master_debug_level(
  1295 int ec_master_debug_level(
  1282         ec_master_t *master, /**< EtherCAT master. */
  1296         ec_master_t *master, /**< EtherCAT master. */
  1283         int level /**< Debug level. May be 0, 1 or 2. */
  1297         int level /**< Debug level. May be 0, 1 or 2. */
  1284         )
  1298         )
  1285 {
  1299 {
  1286     if (level < 0 || level > 2) {
  1300     if (level < 0 || level > 2) {
  1287         EC_ERR("Invalid debug level %i!\n", level);
  1301         EC_ERR("Invalid debug level %i!\n", level);
  1288         return -1;
  1302         return -EINVAL;
  1289     }
  1303     }
  1290 
  1304 
  1291     if (level != master->debug_level) {
  1305     if (level != master->debug_level) {
  1292         master->debug_level = level;
  1306         master->debug_level = level;
  1293         EC_INFO("Master debug level set to %i.\n", master->debug_level);
  1307         EC_INFO("Master debug level set to %i.\n", master->debug_level);
  1349 
  1363 
  1350 int ecrt_master_activate(ec_master_t *master)
  1364 int ecrt_master_activate(ec_master_t *master)
  1351 {
  1365 {
  1352     uint32_t domain_offset;
  1366     uint32_t domain_offset;
  1353     ec_domain_t *domain;
  1367     ec_domain_t *domain;
       
  1368     int ret;
  1354 
  1369 
  1355     if (master->debug_level)
  1370     if (master->debug_level)
  1356         EC_DBG("ecrt_master_activate(master = 0x%x)\n", (u32) master);
  1371         EC_DBG("ecrt_master_activate(master = 0x%x)\n", (u32) master);
  1357 
  1372 
  1358     down(&master->master_sem);
  1373     down(&master->master_sem);
  1359 
  1374 
  1360     // finish all domains
  1375     // finish all domains
  1361     domain_offset = 0;
  1376     domain_offset = 0;
  1362     list_for_each_entry(domain, &master->domains, list) {
  1377     list_for_each_entry(domain, &master->domains, list) {
  1363         if (ec_domain_finish(domain, domain_offset)) {
  1378         ret = ec_domain_finish(domain, domain_offset);
       
  1379         if (ret < 0) {
  1364             up(&master->master_sem);
  1380             up(&master->master_sem);
  1365             EC_ERR("Failed to finish domain 0x%08X!\n", (u32) domain);
  1381             EC_ERR("Failed to finish domain 0x%08X!\n", (u32) domain);
  1366             return -1;
  1382             return ret;
  1367         }
  1383         }
  1368         domain_offset += domain->data_size;
  1384         domain_offset += domain->data_size;
  1369     }
  1385     }
  1370     
  1386     
  1371     up(&master->master_sem);
  1387     up(&master->master_sem);
  1383     master->injection_seq_rt = 0;
  1399     master->injection_seq_rt = 0;
  1384     master->request_cb = master->ext_request_cb;
  1400     master->request_cb = master->ext_request_cb;
  1385     master->release_cb = master->ext_release_cb;
  1401     master->release_cb = master->ext_release_cb;
  1386     master->cb_data = master->ext_cb_data;
  1402     master->cb_data = master->ext_cb_data;
  1387     
  1403     
  1388     if (ec_master_thread_start(master, ec_master_operation_thread,
  1404     ret = ec_master_thread_start(master, ec_master_operation_thread,
  1389                 "EtherCAT-OP")) {
  1405                 "EtherCAT-OP");
       
  1406     if (ret < 0) {
  1390         EC_ERR("Failed to start master thread!\n");
  1407         EC_ERR("Failed to start master thread!\n");
  1391         return -1;
  1408         return ret;
  1392     }
  1409     }
  1393 #ifdef EC_EOE
  1410 #ifdef EC_EOE
  1394     ec_master_eoe_start(master);
  1411     ec_master_eoe_start(master);
  1395 #endif
  1412 #endif
  1396 
  1413