master/master.c
changeset 208 b7797f8a813d
parent 206 60a10d85c20b
child 211 c684b6b7adaf
equal deleted inserted replaced
207:3e0a148eb38d 208:b7797f8a813d
    44 #include "ethernet.h"
    44 #include "ethernet.h"
    45 
    45 
    46 /*****************************************************************************/
    46 /*****************************************************************************/
    47 
    47 
    48 void ec_master_freerun(unsigned long);
    48 void ec_master_freerun(unsigned long);
    49 void ec_master_run_eoe(void *);
    49 void ec_master_run_eoe(unsigned long);
    50 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
    50 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *);
    51 void ec_master_process_watch_command(ec_master_t *);
    51 void ec_master_process_watch_command(ec_master_t *);
    52 
    52 
    53 /*****************************************************************************/
    53 /*****************************************************************************/
    54 
    54 
   111     // init freerun timer
   111     // init freerun timer
   112     init_timer(&master->freerun_timer);
   112     init_timer(&master->freerun_timer);
   113     master->freerun_timer.function = ec_master_freerun;
   113     master->freerun_timer.function = ec_master_freerun;
   114     master->freerun_timer.data = (unsigned long) master;
   114     master->freerun_timer.data = (unsigned long) master;
   115 
   115 
   116     master->eoe_wq = NULL;
   116     // init eoe timer
   117     INIT_WORK(&master->eoe_work, ec_master_run_eoe, master);
   117     init_timer(&master->eoe_timer);
       
   118     master->eoe_timer.function = ec_master_run_eoe;
       
   119     master->eoe_timer.data = (unsigned long) master;
   118 
   120 
   119     ec_command_init(&master->simple_command);
   121     ec_command_init(&master->simple_command);
   120     ec_command_init(&master->watch_command);
   122     ec_command_init(&master->watch_command);
   121 
   123 
   122     ec_master_reset(master);
   124     ec_master_reset(master);
   135 {
   137 {
   136     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
   138     ec_master_t *master = container_of(kobj, ec_master_t, kobj);
   137 
   139 
   138     EC_INFO("Clearing master %i...\n", master->index);
   140     EC_INFO("Clearing master %i...\n", master->index);
   139 
   141 
       
   142     del_timer_sync(&master->eoe_timer);
   140     del_timer_sync(&master->freerun_timer);
   143     del_timer_sync(&master->freerun_timer);
   141 
   144 
   142     ec_master_reset(master);
   145     ec_master_reset(master);
   143 
   146 
   144     if (master->device) {
   147     if (master->device) {
   146         kfree(master->device);
   149         kfree(master->device);
   147     }
   150     }
   148 
   151 
   149     ec_command_clear(&master->simple_command);
   152     ec_command_clear(&master->simple_command);
   150     ec_command_clear(&master->watch_command);
   153     ec_command_clear(&master->watch_command);
   151 
       
   152     if (master->eoe_wq) destroy_workqueue(master->eoe_wq);
       
   153 
   154 
   154     EC_INFO("Master %i cleared.\n", master->index);
   155     EC_INFO("Master %i cleared.\n", master->index);
   155 }
   156 }
   156 
   157 
   157 /*****************************************************************************/
   158 /*****************************************************************************/
   168     ec_command_t *command, *next_c;
   169     ec_command_t *command, *next_c;
   169     ec_domain_t *domain, *next_d;
   170     ec_domain_t *domain, *next_d;
   170     ec_eoe_t *eoe, *next_eoe;
   171     ec_eoe_t *eoe, *next_eoe;
   171 
   172 
   172     // stop EoE processing
   173     // stop EoE processing
   173     if (master->eoe_wq && !cancel_delayed_work(&master->eoe_work)) {
   174     del_timer_sync(&master->eoe_timer);
   174         flush_workqueue(master->eoe_wq);
   175 
   175     }
   176     // stop free-run mode
   176 
       
   177     ec_master_freerun_stop(master);
   177     ec_master_freerun_stop(master);
   178 
   178 
   179     // remove all slaves
   179     // remove all slaves
   180     list_for_each_entry_safe(slave, next_s, &master->slaves, list) {
   180     list_for_each_entry_safe(slave, next_s, &master->slaves, list) {
   181         list_del(&slave->list);
   181         list_del(&slave->list);
   262 {
   262 {
   263     ec_command_t *command;
   263     ec_command_t *command;
   264     size_t command_size;
   264     size_t command_size;
   265     uint8_t *frame_data, *cur_data;
   265     uint8_t *frame_data, *cur_data;
   266     void *follows_word;
   266     void *follows_word;
   267     cycles_t start = 0, end;
   267     cycles_t t_start, t_end;
   268     unsigned int frame_count, more_commands_waiting;
   268     unsigned int frame_count, more_commands_waiting;
   269 
   269 
   270     frame_count = 0;
   270     frame_count = 0;
   271 
   271     t_start = get_cycles();
   272     if (unlikely(master->debug_level > 0)) {
   272 
       
   273     if (unlikely(master->debug_level > 0))
   273         EC_DBG("ec_master_send_commands\n");
   274         EC_DBG("ec_master_send_commands\n");
   274         start = get_cycles();
       
   275     }
       
   276 
   275 
   277     do {
   276     do {
   278         // fetch pointer to transmit socket buffer
   277         // fetch pointer to transmit socket buffer
   279         frame_data = ec_device_tx_data(master->device);
   278         frame_data = ec_device_tx_data(master->device);
   280         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
   279         cur_data = frame_data + EC_FRAME_HEADER_SIZE;
   292                 more_commands_waiting = 1;
   291                 more_commands_waiting = 1;
   293                 break;
   292                 break;
   294             }
   293             }
   295 
   294 
   296             command->state = EC_CMD_SENT;
   295             command->state = EC_CMD_SENT;
       
   296             command->t_sent = t_start;
   297             command->index = master->command_index++;
   297             command->index = master->command_index++;
   298 
   298 
   299             if (unlikely(master->debug_level > 0))
   299             if (unlikely(master->debug_level > 0))
   300                 EC_DBG("adding command 0x%02X\n", command->index);
   300                 EC_DBG("adding command 0x%02X\n", command->index);
   301 
   301 
   343         frame_count++;
   343         frame_count++;
   344     }
   344     }
   345     while (more_commands_waiting);
   345     while (more_commands_waiting);
   346 
   346 
   347     if (unlikely(master->debug_level > 0)) {
   347     if (unlikely(master->debug_level > 0)) {
   348         end = get_cycles();
   348         t_end = get_cycles();
   349         EC_DBG("ec_master_send_commands sent %i frames in %ius.\n",
   349         EC_DBG("ec_master_send_commands sent %i frames in %ius.\n",
   350                frame_count, (u32) (end - start) * 1000 / cpu_khz);
   350                frame_count, (u32) (t_end - t_start) * 1000 / cpu_khz);
   351     }
   351     }
   352 }
   352 }
   353 
   353 
   354 /*****************************************************************************/
   354 /*****************************************************************************/
   355 
   355 
   842 
   842 
   843 /**
   843 /**
   844    Does the Ethernet-over-EtherCAT processing.
   844    Does the Ethernet-over-EtherCAT processing.
   845 */
   845 */
   846 
   846 
   847 void ec_master_run_eoe(void *data /**< work data (= master pointer) */)
   847 void ec_master_run_eoe(unsigned long data /**< master pointer */)
   848 {
   848 {
   849     ec_master_t *master = (ec_master_t *) data;
   849     ec_master_t *master = (ec_master_t *) data;
   850 
       
   851 #if 0
       
   852     ec_eoe_t *eoe;
   850     ec_eoe_t *eoe;
   853 
   851 
       
   852     if (!master->request_cb(master->cb_data)) goto restart_timer;
       
   853 
       
   854     ecrt_master_async_receive(master);
   854     list_for_each_entry(eoe, &master->eoe_slaves, list) {
   855     list_for_each_entry(eoe, &master->eoe_slaves, list) {
   855         ec_eoe_run(eoe);
   856       ec_eoe_run(eoe);
   856     }
   857     }
   857 #endif
   858     ecrt_master_async_send(master);
   858 
   859 
   859     queue_delayed_work(master->eoe_wq, &master->eoe_work, HZ);
   860     master->release_cb(master->cb_data);
       
   861 
       
   862  restart_timer:
       
   863     master->eoe_timer.expires += HZ / 4;
       
   864     add_timer(&master->eoe_timer);
   860 }
   865 }
   861 
   866 
   862 /******************************************************************************
   867 /******************************************************************************
   863  *  Realtime interface
   868  *  Realtime interface
   864  *****************************************************************************/
   869  *****************************************************************************/
  1230 */
  1235 */
  1231 
  1236 
  1232 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */)
  1237 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */)
  1233 {
  1238 {
  1234     ec_command_t *command, *next;
  1239     ec_command_t *command, *next;
       
  1240     cycles_t t_received, t_timeout;
  1235 
  1241 
  1236     ec_device_call_isr(master->device);
  1242     ec_device_call_isr(master->device);
       
  1243 
       
  1244     t_received = get_cycles();
       
  1245     t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000);
  1237 
  1246 
  1238     // dequeue all received commands
  1247     // dequeue all received commands
  1239     list_for_each_entry_safe(command, next, &master->command_queue, queue)
  1248     list_for_each_entry_safe(command, next, &master->command_queue, queue)
  1240         if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue);
  1249         if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue);
  1241 
  1250 
  1242     // dequeue all remaining commands
  1251     // dequeue all commands that timed out
  1243     list_for_each_entry_safe(command, next, &master->command_queue, queue) {
  1252     list_for_each_entry_safe(command, next, &master->command_queue, queue) {
  1244         switch (command->state) {
  1253         switch (command->state) {
  1245             case EC_CMD_SENT:
  1254             case EC_CMD_SENT:
  1246             case EC_CMD_QUEUED:
  1255             case EC_CMD_QUEUED:
  1247                 command->state = EC_CMD_TIMEOUT;
  1256                 if (t_received - command->t_sent > t_timeout) {
  1248                 master->stats.timeouts++;
  1257                     list_del_init(&command->queue);
  1249                 ec_master_output_stats(master);
  1258                     command->state = EC_CMD_TIMEOUT;
       
  1259                     master->stats.timeouts++;
       
  1260                     ec_master_output_stats(master);
       
  1261                 }
  1250                 break;
  1262                 break;
  1251             default:
  1263             default:
  1252                 break;
  1264                 break;
  1253         }
  1265         }
  1254         list_del_init(&command->queue);
       
  1255     }
  1266     }
  1256 }
  1267 }
  1257 
  1268 
  1258 /*****************************************************************************/
  1269 /*****************************************************************************/
  1259 
  1270 
  1463     if (list_empty(&master->eoe_slaves)) {
  1474     if (list_empty(&master->eoe_slaves)) {
  1464         EC_WARN("start_eoe: no EoE-capable slaves present.\n");
  1475         EC_WARN("start_eoe: no EoE-capable slaves present.\n");
  1465         return 0;
  1476         return 0;
  1466     }
  1477     }
  1467 
  1478 
  1468     // create the EoE workqueue, if necessary
       
  1469     if (!master->eoe_wq) {
       
  1470         if (!(master->eoe_wq = create_singlethread_workqueue("eoework"))) {
       
  1471             EC_ERR("Failed to create EoE workqueue!\n");
       
  1472             return -1;
       
  1473         }
       
  1474     }
       
  1475 
       
  1476     // start EoE processing
  1479     // start EoE processing
  1477     queue_work(master->eoe_wq, &master->eoe_work);
  1480     master->eoe_timer.expires = jiffies + 10;
       
  1481     add_timer(&master->eoe_timer);
  1478     return 0;
  1482     return 0;
  1479 }
  1483 }
  1480 
  1484 
  1481 /*****************************************************************************/
  1485 /*****************************************************************************/
  1482 
  1486