[etherlab-users] [etherlab-dev] e1000e Limited to frame rate of 250/sec

Thomas Bitsky Jr tbj at automateddesign.com
Thu Jul 4 00:09:57 CEST 2013


Thank you, Mattieu. I'll implement the change immediately. You help is much appreciated.

Thomas C. Bitsky Jr. | Lead Developer
ADC | automateddesign.com
P: 630-783-1150 F: 630-783-1159 M: 630-632-6679

-----Original Message-----
From: Matthieu Bec [mailto:mbec at gmto.org] 
Sent: Wednesday, July 03, 2013 5:03 PM
To: Thomas Bitsky Jr
Cc: etherlab-users at etherlab.org
Subject: Re: [etherlab-dev] e1000e Limited to frame rate of 250/sec


Hello Tom,

linux regular timers won't be any good:

> timer.expires += HZ / FREQUENCY;

HZ (CONFIG_HZ) is commonly <= 1000. Yours probably 250 and you just sleep 0

try linux "hrtimers" - there are plenty of resources to get some examples, including the igh master itself (!)

Matthieu




On 7/3/13 2:25 PM, Thomas Bitsky Jr wrote:
> Hello, all.
> 
>  
> 
> I've been working for a week on running the EtherCAT master 1.5.1 on 
> an Intel Atom Desktop with two e1000e Intel cards. I need to get a 
> frame rate of 2000/sec, but with both the generic driver and ec_e1000e 
> driver, I can get no more than 250/sec. There are no errors or warning 
> while running.
> 
>  
> 
> The Operating System is Linux 2.6.33 with the RT PREMPT patch. I also 
> tried running the generic driver on 3.2.46-rt67 with the same results.
> 
>  
> 
> To get the network statistics, I type "ethercat master" at the command 
> line. When the EtherCAT master starts up, it seems to burst at a 
> massively fast frame rate, then quickly settle to 250/sec. Note that 
> on three different machines, the results are the same, although I 
> think they all have Intel NICs. When I start up the kernel module I 
> wrote and the network goes into Operation, the speed results are unchanged.
> 
>  
> 
> I know the e1000e driver can be slower than the 8139too driver, but 
> 250/sec seems excessively slow and the fact that it's ALWAYS 250 
> regardless of driver or machine leads me to believe I'm doing 
> something wrong. I've tried turning off the InterruptThrottleRate 
> feature of the card (with both the e1000e and ec_e1000e driver), but with no effect.
> 
>  
> 
> Below is the code that I'm using to run the test, which is based off 
> the "mini" example. Can anyone tell me what I'm doing wrong, or if 
> there is some feature in the e1000e driver that I need to disable?
> 
>  
> 
> Thanks in advance,
> 
> Tom
> 
>  
> 
>  
> 
> #include<linux/version.h>
> 
> #include<linux/module.h>
> 
> #include<linux/timer.h>
> 
> #include<linux/interrupt.h>
> 
> #include<linux/err.h>
> 
> #include<linux/semaphore.h>
> 
> #include<linux/time.h>
> 
>  
> 
> #ifLINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
> 
> #include<linux/semaphore.h>
> 
> #else
> 
> #include<asm/semaphore.h>
> 
> #endif
> 
>  
> 
>  
> 
> #defineMY_PRIORITY (49) /* we use 49 as the PRREMPT_RT use 50
> 
>                             as the priority of kernel tasklets
> 
>                             and interrupt handler by default */
> 
>  
> 
> #defineMAX_SAFE_STACK (8*1024) /* The maximum stack size which is
> 
>                                    guaranteed safe to access without
> 
>                                    faulting */
> 
>  
> 
> // #define NSEC_PER_SEC    (1000000000) /* The number of nsecs per sec. */
> 
>  
> 
>  
> 
> #definePFX "durability.c: "
> 
>  
> 
> #include"/home/tbj/srcroot/ethercat/include/ecrt.h" // EtherCAT 
> realtime interface
> 
> /*
> 
> * Import the bus topology generated by EtherLAB
> 
> */
> 
> #include"2369topology.h"
> 
>  
> 
> /*
> 
> * Application Parameters
> 
> */
> 
> #defineFREQUENCY 2000
> 
> #defineINHIBIT_TIME 20
> 
>  
> 
> // process data
> 
> staticuint8_t *processData = NULL;
> 
>  
> 
> /*
> 
> * macros for any of the hardware on the network.
> 
> * Use # ethercat slaves to see this info
> 
> * You can also use # ethercat cstruct > topology.h to generate a slave 
> header.
> 
> * The vendor id and product code for each slave will be listed in 
> comments in that file.
> 
> */
> 
> #defineBeckhoff_EK1100 0x00000002, 0x044c2c52        // uint32_t
> vendor_id, uint32_t product_code     
> 
> #defineBeckhoff_EL1004 0x00000002, 0x03ec3052
> 
> #defineBeckhoff_EL5101 0x00000002, 0x13ed3052
> 
> #defineBeckhoff_EL2004 0x00000002, 0x07d43052
> 
> #defineBeckhoff_EL6601 0x00000002, 0x19c93052
> 
> #defineSMC_EX260SEC3 0x00000114, 0x01000003
> 
> #defineBeckhoff_EP1809 0x00000002, 0x07114052
> 
> #defineBeckhoff_EP2028 0x00000002, 0x07ec4052
> 
> #defineBeckhoff_EP4174 0x00000002, 0x104e4052
> 
>  
> 
>  
> 
> /*
> 
> * Global variables for interacting with the EtherCAT master.
> 
> */
> 
> staticec_master_t *master = NULL;
> 
> staticec_master_state_t master_state = {};
> 
> structsemaphore master_sem;
> 
>  
> 
>  
> 
>  
> 
> staticec_domain_t *domain = NULL;
> 
> staticec_domain_state_t domain_state = {};
> 
>  
> 
> // Timer
> 
> staticstruct timer_list timer;
> 
>  
> 
> structtimespec lastCycle_;
> 
> structtimespec lastSend_;
> 
> structtimespec lastRead_;
> 
> structsched_param param;
> 
> structtimespec interval; // = 50000; /* 50us*/
> 
>                        
> 
>  
> 
> structPdoOffset
> 
>       {
> 
>       unsigned int offset;
> 
>       unsigned int bitPosition;
> 
>       };
> 
>  
> 
>  
> 
> staticstruct PdoOffset digInOffsets[255];
> 
> staticstruct PdoOffset digOutOffsets[255];
> 
> staticstruct PdoOffset analogInOffsets[255];
> 
> staticstruct PdoOffset analogOutOffsets[255];
> 
>  
> 
>  
> 
> conststatic ec_pdo_entry_reg_t domain_regs[] =
> 
>       {
> 
>             {0,1, Beckhoff_EL1004, 0x6000, 1, &digInOffsets[0].offset, 
> &digInOffsets[0].bitPosition},
> 
>             {0,1, Beckhoff_EL1004, 0x6010, 1, &digInOffsets[1].offset, 
> &digInOffsets[1].bitPosition},
> 
>             {0,1, Beckhoff_EL1004, 0x6020, 1, &digInOffsets[2].offset, 
> &digInOffsets[2].bitPosition},
> 
>             {0,1, Beckhoff_EL1004, 0x6030, 1, &digInOffsets[3].offset, 
> &digInOffsets[3].bitPosition},
> 
>            
> 
>             {0,2, Beckhoff_EL1004, 0x6000, 1, &digInOffsets[4].offset, 
> &digInOffsets[4].bitPosition},
> 
>             {0,2, Beckhoff_EL1004, 0x6010, 1, &digInOffsets[5].offset, 
> &digInOffsets[5].bitPosition},
> 
>             {0,2, Beckhoff_EL1004, 0x6020, 1, &digInOffsets[6].offset, 
> &digInOffsets[6].bitPosition},
> 
>             {0,2, Beckhoff_EL1004, 0x6030, 1, &digInOffsets[7].offset, 
> &digInOffsets[7].bitPosition},
> 
>            
> 
>             {0,3, Beckhoff_EL1004, 0x6000, 1, &digInOffsets[8].offset, 
> &digInOffsets[8].bitPosition},
> 
>             {0,3, Beckhoff_EL1004, 0x6010, 1, &digInOffsets[9].offset, 
> &digInOffsets[9].bitPosition},
> 
>             {0,3, Beckhoff_EL1004, 0x6020, 1, 
> &digInOffsets[10].offset, &digInOffsets[10].bitPosition},
> 
>             {0,3, Beckhoff_EL1004, 0x6030, 1, &digInOffsets[11].offset,
> &digInOffsets[11].bitPosition},          
> 
>                        
> 
>             {0,9, Beckhoff_EP1809, 0x6000, 1, 
> &digInOffsets[12].offset, &digInOffsets[12].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6010, 1, 
> &digInOffsets[13].offset, &digInOffsets[13].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6020, 1, 
> &digInOffsets[14].offset, &digInOffsets[14].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6030, 1, 
> &digInOffsets[15].offset, &digInOffsets[15].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6040, 1, 
> &digInOffsets[16].offset, &digInOffsets[16].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6050, 1, 
> &digInOffsets[17].offset, &digInOffsets[17].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6060, 1, 
> &digInOffsets[18].offset, &digInOffsets[18].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6070, 1, 
> &digInOffsets[19].offset, &digInOffsets[19].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6080, 1, 
> &digInOffsets[20].offset, &digInOffsets[20].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x6090, 1, 
> &digInOffsets[21].offset, &digInOffsets[21].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60A0, 1, 
> &digInOffsets[22].offset, &digInOffsets[22].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60B0, 1, 
> &digInOffsets[23].offset, &digInOffsets[23].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60C0, 1, 
> &digInOffsets[24].offset, &digInOffsets[24].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60D0, 1, 
> &digInOffsets[25].offset, &digInOffsets[25].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60E0, 1, 
> &digInOffsets[26].offset, &digInOffsets[26].bitPosition},
> 
>             {0,9, Beckhoff_EP1809, 0x60F0, 1, 
> &digInOffsets[27].offset, &digInOffsets[27].bitPosition},
> 
>                        
> 
>             {0,4, Beckhoff_EL5101, 0x6010, 0x11, 
> &analogInOffsets[0].offset, &analogInOffsets[0].bitPosition},
> 
>            
> 
>             {0,5, Beckhoff_EL2004, 0x7000, 1, 
> &digOutOffsets[0].offset, &digOutOffsets[0].bitPosition},
> 
>             {0,5, Beckhoff_EL2004, 0x7010, 1, 
> &digOutOffsets[1].offset, &digOutOffsets[1].bitPosition},
> 
>             {0,5, Beckhoff_EL2004, 0x7020, 1, 
> &digOutOffsets[2].offset, &digOutOffsets[2].bitPosition},
> 
>             {0,5, Beckhoff_EL2004, 0x7030, 1, 
> &digOutOffsets[3].offset, &digOutOffsets[3].bitPosition},
> 
>            
> 
>             {0,6, Beckhoff_EL2004, 0x7000, 1, 
> &digOutOffsets[4].offset, &digOutOffsets[4].bitPosition},
> 
>             {0,6, Beckhoff_EL2004, 0x7010, 1, 
> &digOutOffsets[5].offset, &digOutOffsets[5].bitPosition},
> 
>             {0,6, Beckhoff_EL2004, 0x7020, 1, 
> &digOutOffsets[6].offset, &digOutOffsets[6].bitPosition},
> 
>             {0,6, Beckhoff_EL2004, 0x7030, 1, &digOutOffsets[7].offset,
> &digOutOffsets[7].bitPosition},    
> 
>            
> 
>             {0,10, Beckhoff_EP2028, 0x7000, 1, &digOutOffsets[8].offset,
> &digOutOffsets[8].bitPosition},    
> 
>             {0,10, Beckhoff_EP2028, 0x7010, 1, &digOutOffsets[9].offset,
> &digOutOffsets[9].bitPosition},          
> 
>             {0,10, Beckhoff_EP2028, 0x7020, 1,
> &digOutOffsets[10].offset, &digOutOffsets[10].bitPosition},   
> 
>             {0,10, Beckhoff_EP2028, 0x7030, 1,
> &digOutOffsets[11].offset, &digOutOffsets[11].bitPosition},   
> 
>             {0,10, Beckhoff_EP2028, 0x7040, 1,
> &digOutOffsets[12].offset, &digOutOffsets[12].bitPosition},   
> 
>             {0,10, Beckhoff_EP2028, 0x7050, 1,
> &digOutOffsets[13].offset, &digOutOffsets[13].bitPosition},               
> 
>             {0,10, Beckhoff_EP2028, 0x7060, 1,
> &digOutOffsets[14].offset, &digOutOffsets[14].bitPosition},   
> 
>             {0,10, Beckhoff_EP2028, 0x7070, 1,
> &digOutOffsets[15].offset, &digOutOffsets[15].bitPosition},               
> 
>            
> 
>            
> 
>             // Encoder card registers for setting the counter
> 
>             {0,4, Beckhoff_EL5101, 0x7010, 0x03, 
> &analogOutOffsets[0].offset,
> &analogOutOffsets[0].bitPosition},             
> 
>             {0,4, Beckhoff_EL5101, 0x7010, 0x11, 
> &analogOutOffsets[1].offset,
> &analogOutOffsets[1].bitPosition},             
> 
>            
> 
>             // The bits of two bytes covers the valves on the block
> 
>             {0,8, SMC_EX260SEC3, 0x3101, 0x01,
> &analogOutOffsets[2].offset, &analogOutOffsets[2].bitPosition},       
> 
>             {0,8, SMC_EX260SEC3, 0x3101, 0x02, 
> &analogOutOffsets[3].offset, &analogOutOffsets[3].bitPosition},
> 
>            
> 
>             {0,11, Beckhoff_EP4174, 0x7000, 0x11, 
> &analogOutOffsets[4].offset, &analogOutOffsets[4].bitPosition},
> 
>             {0,11, Beckhoff_EP4174, 0x7010, 0x11, 
> &analogOutOffsets[5].offset, &analogOutOffsets[5].bitPosition},
> 
>             {0,11, Beckhoff_EP4174, 0x7020, 0x11, 
> &analogOutOffsets[6].offset, &analogOutOffsets[6].bitPosition},
> 
>             {0,11, Beckhoff_EP4174, 0x7030, 0x11, 
> &analogOutOffsets[7].offset, &analogOutOffsets[7].bitPosition},
> 
>            
> 
>             {}
> 
>            
> 
>       };
> 
>  
> 
>  
> 
> // process variables
> 
> staticunsigned int counter = 0;
> 
>  
> 
> /*
> 
> * Check and report on the state of the domain.
> 
> */
> 
> void
> 
> check_domain_state(void)
> 
>       {
> 
>       ec_domain_state_t ds;
> 
>  
> 
>       down(&master_sem);
> 
>       ecrt_domain_state(domain, &ds);
> 
>       up(&master_sem);
> 
>  
> 
>       if (ds.working_counter != domain_state.working_counter)
> 
>                   printk(KERN_INFO PFX "Domain: WC %u.\n", 
> ds.working_counter);
> 
>       if (ds.wc_state != domain_state.wc_state)
> 
>                   printk(KERN_INFO PFX "Domain: State %u.\n", 
> ds.wc_state);
> 
>  
> 
>       domain_state = ds;
> 
>       }
> 
>  
> 
>  
> 
>  
> 
> /*
> 
> * Check and report on the state of the master service.
> 
> */
> 
> void
> 
> check_master_state(void)
> 
>       {
> 
>       ec_master_state_t ms;
> 
>  
> 
>       down(&master_sem);
> 
>       ecrt_master_state(master, &ms);
> 
>       up(&master_sem);
> 
>  
> 
>       if (ms.slaves_responding != master_state.slaves_responding)
> 
>                   printk(KERN_INFO PFX "%u slave(s).\n", 
> ms.slaves_responding);
> 
>       if (ms.al_states != master_state.al_states)
> 
>                   printk(KERN_INFO PFX "AL states: 0x%02X.\n", 
> ms.al_states);
> 
>       if (ms.link_up != master_state.link_up)
> 
>                   printk(KERN_INFO PFX "Link is %s.\n", ms.link_up ?
> "up" : "down");
> 
>  
> 
>       master_state = ms;
> 
>       }
> 
>  
> 
>  
> 
> void
> 
> check_slave_config_states(void)
> 
>       {
> 
>       /*
> 
>     ec_slave_config_state_t s;
> 
>  
> 
>     ecrt_slave_config_state(sc_ana_in, &s);
> 
>  
> 
>     if (s.al_state != sc_ana_in_state.al_state)
> 
>         printk(KERN_ERR PFX "AnaIn: State 0x%02X.\n", s.al_state);
> 
>     if (s.online != sc_ana_in_state.online)
> 
>         printk(KERN_ERR PFX "AnaIn: %s.\n", s.online ? "online" :
> "offline");
> 
>     if (s.operational != sc_ana_in_state.operational)
> 
>         printk(KERN_ERR PFX "AnaIn: %soperational.\n",
> 
>                 s.operational ? "" : "Not ");
> 
>       */
> 
>       }
> 
>  
> 
>  
> 
>  
> 
> void
> 
> cyclic_task(unsigned long data)
> 
>       {
> 
>       // receive process data
> 
>       down(&master_sem);
> 
>       ecrt_master_receive(master);
> 
>       ecrt_domain_process(domain);
> 
>       up(&master_sem);
> 
>      
> 
>      
> 
>       ktime_get_ts(&lastCycle_);
> 
>      
> 
>       // check process data state (optional)
> 
>       check_domain_state();
> 
>  
> 
>       if (counter)
> 
>             {
> 
>             counter--;
> 
>             }
> 
>       else
> 
>             {
> 
>             counter = FREQUENCY;
> 
>  
> 
>             // check for master state
> 
>             check_master_state();
> 
>             }
> 
>  
> 
>       // send process data
> 
>       down(&master_sem);
> 
>       ecrt_domain_queue(domain);
> 
>       ecrt_master_send(master);
> 
>       up(&master_sem);
> 
>            
> 
>       // restart timer
> 
>   timer.expires += HZ / FREQUENCY;
> 
>   add_timer(&timer);   
> 
>       }
> 
>  
> 
>  
> 
> void
> 
> send_callback(void *cb_data)
> 
>       {
> 
>      
> 
>       struct timespec delta = timespec_sub(lastCycle_, lastSend_);
> 
>       ec_master_t *m = NULL;
> 
>  
> 
>       printk(KERN_INFO PFX "send_callback");
> 
>      
> 
>       if (timespec_compare(&delta, &interval) > 0)
> 
>             {
> 
>  
> 
>             printk(KERN_INFO PFX "ecrt_master_send_ext");
> 
>             m = (ec_master_t *) cb_data;
> 
>             down(&master_sem);
> 
>             ecrt_master_send_ext(m);
> 
>             up(&master_sem);
> 
>            
> 
>             ktime_get_ts(&lastSend_);
> 
>             }
> 
>       }
> 
>  
> 
> void
> 
> receive_callback(void *cb_data)
> 
>       {
> 
>      
> 
>       struct timespec delta = timespec_sub(lastCycle_, lastRead_);
> 
>       ec_master_t *m = NULL;
> 
>  
> 
>       printk(KERN_INFO PFX "receive_callback");
> 
>      
> 
>       if (timespec_compare(&delta, &interval) > 0)
> 
>             {
> 
>      
> 
>             printk(KERN_INFO PFX "ecrt_master_receive");
> 
>             m = (ec_master_t *) cb_data;
> 
>  
> 
>             down(&master_sem);
> 
>             ecrt_master_receive(m);      
> 
>             up(&master_sem);
> 
>            
> 
>             ktime_get_ts(&lastRead_);
> 
>             }
> 
>       }
> 
>  
> 
> int
> 
> __init init_mini_module(void)
> 
>       {
> 
>   ec_slave_config_t *sc;
> 
>   int ret = -1;
> 
>      
> 
>       /*
> 
>       * Requests an EtherCAT master for realtime operation.
> 
>       * Before an application can access an EtherCAT master, it has to 
> reserve one for exclusive use.
> 
>       * In userspace, this is a convenience function for
> ecrt_open_master() and ecrt_master_reserve().
> 
>       * This function has to be the first function an application has 
> to call to use EtherCAT.
> 
>        * The function takes the index of the master as its argument.
> 
>        * The first master has index 0, the n-th master has index n - 1.
> 
>        * The number of masters has to be specified when loading the 
> master module.
> 
>       */
> 
>   master = ecrt_request_master(0);
> 
>   if (!master)
> 
>             {
> 
>             printk(KERN_INFO PFX "Could not connect to the master 
> service. Exiting.\n\n");
> 
>             ret = -EBUSY;
> 
>             goto out_return;
> 
>             }
> 
>            
> 
>            
> 
>       ktime_get_ts(&lastCycle_);
> 
>       ktime_get_ts(&lastSend_);
> 
>       ktime_get_ts(&lastRead_);
> 
>      
> 
>       // setup a comparison
> 
>       interval.tv_nsec = 50000;
> 
>            
> 
>            
> 
>       sema_init(&master_sem, 1);
> 
>       ecrt_master_callbacks(
> 
>             master,                                   // pointer to master
> 
>             send_callback,                // fp to send ext callback
> 
>             receive_callback,       // fp to receive callback
> 
>             master);                                  // parameter to
> callback
> 
>            
> 
>            
> 
>       /*
> 
>       * Creates a new process data domain.
> 
>       * For process data exchange, at least one process data domain is 
> needed.
> 
>        * This method creates a new process data domain and returns a 
> pointer to the new domain object.
> 
>        * This object can be used for registering PDOs and exchanging 
> them in cyclic operation.
> 
>       */
> 
>       domain = ecrt_master_create_domain(master);
> 
>       if (!domain)
> 
>             {
> 
>             printk(KERN_INFO PFX "Could not create a domain on the 
> master. Exiting.\n\n");
> 
>             goto out_release_master;     
> 
>             }
> 
>            
> 
>            
> 
>       /*         
> 
>       * Register the slaves on the master
> 
>       * Doing the method this way means the registration will work 
> whether or
> 
>       * not the computer is connected to the network.
> 
>       */
> 
>      
> 
>       // Main Rack, Slot 1
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,1,                                            // Bus
> position
> 
>                   Beckhoff_EL1004               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_INFO PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_1_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }
> 
>                  
> 
>       // Main Rack, Slot 2
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,2,                                            // Bus
> position
> 
>                   Beckhoff_EL1004               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_2_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       // Main Rack, Slot 3
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,3,                                            // Bus
> position
> 
>                   Beckhoff_EL1004               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_3_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       // Main Rack, Slot 4
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,4,                                            // Bus
> position
> 
>                   Beckhoff_EL5101               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_4_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                
> 
>                        
> 
>       // Main Rack, Slot 5
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,5,                                            // Bus
> position
> 
>                   Beckhoff_EL2004               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>     ret = -ENOMEM;
> 
>     goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_5_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                      
> 
>            
> 
>       // Main Rack, Slot 6
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,6,                                            // Bus
> position
> 
>                   Beckhoff_EL2004               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_6_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                
> 
>            
> 
>       // Main Rack, Slot 7
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,7,                                            // Bus
> position
> 
>                   Beckhoff_EL6601               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_7_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }          
> 
>            
> 
>       // SMC EtherCAT Manifold, Slave 8, "EX260-SEC3"
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,8,                                            // Bus
> position
> 
>                   SMC_EX260SEC3                       // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_8_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                      
> 
>            
> 
>       // EP1809 Input Fieldbox, Slave 9,
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,9,                                            // Bus
> position
> 
>                   Beckhoff_EP1809               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>                   }    
> 
>  
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_9_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                      
> 
>            
> 
>       // EP2028 Input Fieldbox, Slave 10,
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,10,                                           // Bus
> position
> 
>                   Beckhoff_EP2028               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_10_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                      
> 
>            
> 
>       // EP4174 Input Fieldbox, Slave 11,
> 
>       if (!(sc = ecrt_master_slave_config(
> 
>                   master,
> 
>                   0,11,                                           // Bus
> position
> 
>                   Beckhoff_EP4174               // Slave type
> 
>                   )))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to get slave 
> configuration.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }    
> 
>            
> 
>       if (ecrt_slave_config_pdos(sc, EC_END, slave_11_syncs))
> 
>             {
> 
>             printk(KERN_ERR PFX "Failed to configure PDOs.\n");
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }                
> 
>            
> 
>       // Create configuration for bus coupler
> 
>       sc = ecrt_master_slave_config(master, 0,0, Beckhoff_EK1100);
> 
>   if (!sc)
> 
>             {
> 
>             ret = -ENOMEM;
> 
>             goto out_release_master;
> 
>             }
> 
>            
> 
>       /*
> 
>        * Registers a bunch of PDO entries for a domain.
> 
>        */
> 
>       printk(KERN_ERR PFX "\nAttempting to register PDOs on 
> domain...\n");
> 
>       if (ecrt_domain_reg_pdo_entry_list(domain, domain_regs))
> 
>             {
> 
>             printk(KERN_ERR PFX "PDO entry registration failed!\n");
> 
>             ret = -EBUSY;
> 
>             goto out_release_master;
> 
>             }          
> 
>            
> 
>       /*
> 
>       * Finishes the configuration phase and prepares for cyclic operation.
> 
>       * This function tells the master that the configuration phase is 
> finished and the realtime operation will begin.
> 
>       * The function allocates internal memory for the domains and 
> calculates the logical FMMU addresses for domain members.
> 
>        * It tells the master state machine that the bus configuration 
> is now to be applied
> 
>       */
> 
>       if (ecrt_master_activate(master))
> 
>             {
> 
>             ret = -EBUSY;
> 
>             goto out_release_master;;          
> 
>             }
> 
>            
> 
>       /*
> 
>       * Returns the domain's process data.
> 
>        */
> 
>       if (!(processData = ecrt_domain_data(domain)))
> 
>             {
> 
>             ret = -EBUSY;
> 
>             goto out_release_master;
> 
>             }          
> 
>            
> 
>       printk(KERN_INFO PFX "Starting cyclic thread.\n");
> 
>       init_timer(&timer);
> 
>       timer.function = cyclic_task;
> 
>       timer.expires = jiffies + 10;
> 
>       add_timer(&timer);           
> 
>            
> 
>       printk(KERN_INFO PFX "Durability Service Started.\n");
> 
>       return 0;        
> 
>  
> 
> out_release_master:
> 
>   printk(KERN_ERR PFX "Releasing master...\n");
> 
>   ecrt_release_master(master);
> 
> out_return:
> 
>   printk(KERN_ERR PFX "Failed to load. Aborting.\n");
> 
>       return ret;
> 
>       } // main
> 
>      
> 
>      
> 
> void
> 
> __exit cleanup_mini_module(void)
> 
>       {
> 
>       printk(KERN_INFO PFX "Stopping...\n");
> 
>  
> 
>       del_timer_sync(&timer);
> 
>  
> 
>       printk(KERN_INFO PFX "Releasing master...\n");
> 
>       ecrt_release_master(master);
> 
>  
> 
>       printk(KERN_INFO PFX "Unloading.\n");
> 
>       }
> 
>  
> 
> /*********************************************************************
> ********/
> 
>  
> 
> MODULE_LICENSE("GPL");
> 
> MODULE_AUTHOR("Thomas Bitsky <tbj at automateddesign.com>");
> 
> MODULE_DESCRIPTION("Durability test environment");
> 
>  
> 
> module_init(init_mini_module);
> 
> module_exit(cleanup_mini_module);
> 
>  
> 
> 
> 
> _______________________________________________
> etherlab-dev mailing list
> etherlab-dev at etherlab.org
> http://lists.etherlab.org/mailman/listinfo/etherlab-dev
> 

-- 
Matthieu Bec                GMTO Corp.
cell : +1 626 354 9367      P.O. Box 90933
phone: +1 626 204 0527      Pasadena, CA 91109-0933



More information about the Etherlab-users mailing list