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:[email protected]] Sent: Wednesday, July 03, 2013 5:03 PM To: Thomas Bitsky Jr Cc: [email protected] 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 <[email protected]>"); > > MODULE_DESCRIPTION("Durability test environment"); > > > > module_init(init_mini_module); > > module_exit(cleanup_mini_module); > > > > > > _______________________________________________ > etherlab-dev mailing list > [email protected] > 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 _______________________________________________ etherlab-users mailing list [email protected] http://lists.etherlab.org/mailman/listinfo/etherlab-users
