fp@39: /****************************************************************************** fp@0: * fp@54: * m a s t e r . c fp@0: * fp@0: * Methoden für einen EtherCAT-Master. fp@0: * fp@39: * $Id$ fp@0: * fp@39: *****************************************************************************/ fp@0: fp@24: #include fp@0: #include fp@0: #include fp@0: #include fp@0: #include fp@0: fp@55: #include "../include/EtherCAT_rt.h" fp@54: #include "globals.h" fp@54: #include "master.h" fp@55: #include "slave.h" fp@55: #include "types.h" fp@54: #include "device.h" fp@73: #include "frame.h" fp@0: fp@39: /*****************************************************************************/ fp@0: fp@0: /** fp@0: Konstruktor des EtherCAT-Masters. fp@68: */ fp@68: fp@73: void ec_master_init(ec_master_t *master /**< EtherCAT-Master */) fp@73: { fp@73: master->slaves = NULL; fp@73: master->slave_count = 0; fp@73: master->device_registered = 0; fp@73: master->command_index = 0x00; fp@73: master->domain_count = 0; fp@73: master->debug_level = 0; fp@73: master->bus_time = 0; fp@73: master->frames_lost = 0; fp@73: master->t_lost_output = 0; fp@0: } fp@0: fp@39: /*****************************************************************************/ fp@0: fp@0: /** fp@0: Destruktor eines EtherCAT-Masters. fp@0: fp@0: Entfernt alle Kommandos aus der Liste, löscht den Zeiger fp@0: auf das Slave-Array und gibt die Prozessdaten frei. fp@68: */ fp@68: fp@73: void ec_master_clear(ec_master_t *master /**< EtherCAT-Master */) fp@73: { fp@73: ec_master_reset(master); fp@73: ec_device_clear(&master->device); fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: /** fp@73: Setzt den Master zurück in den Ausgangszustand. fp@56: fp@56: Bei einem "release" sollte immer diese Funktion aufgerufen werden, fp@56: da sonst Slave-Liste, Domains, etc. weiter existieren. fp@68: */ fp@68: fp@68: void ec_master_reset(ec_master_t *master fp@68: /**< Zeiger auf den zurückzusetzenden Master */ fp@68: ) fp@56: { fp@73: unsigned int i; fp@73: fp@74: ec_master_clear_slaves(master); fp@73: fp@73: for (i = 0; i < master->domain_count; i++) { fp@73: ec_domain_clear(master->domains[i]); fp@73: kfree(master->domains[i]); fp@73: } fp@73: master->domain_count = 0; fp@73: fp@73: master->command_index = 0; fp@73: master->debug_level = 0; fp@73: master->bus_time = 0; fp@73: master->frames_lost = 0; fp@73: master->t_lost_output = 0; fp@56: } fp@56: fp@56: /*****************************************************************************/ fp@56: fp@56: /** fp@74: Entfernt alle Slaves. fp@74: */ fp@74: fp@74: void ec_master_clear_slaves(ec_master_t *master /**< EtherCAT-Master */) fp@74: { fp@74: unsigned int i; fp@74: fp@74: if (master->slaves) { fp@74: for (i = 0; i < master->slave_count; i++) { fp@74: ec_slave_clear(master->slaves + i); fp@74: } fp@74: kfree(master->slaves); fp@74: master->slaves = NULL; fp@74: } fp@74: master->slave_count = 0; fp@74: } fp@74: fp@74: /*****************************************************************************/ fp@74: fp@74: /** fp@54: Öffnet das EtherCAT-Geraet des Masters. fp@54: fp@68: \return 0, wenn alles o.k., < 0, wenn kein Gerät registriert wurde oder fp@68: es nicht geoeffnet werden konnte. fp@68: */ fp@68: fp@68: int ec_master_open(ec_master_t *master /**< Der EtherCAT-Master */) fp@54: { fp@73: if (!master->device_registered) { fp@73: printk(KERN_ERR "EtherCAT: No device registered!\n"); fp@73: return -1; fp@73: } fp@73: fp@73: if (ec_device_open(&master->device) < 0) { fp@73: printk(KERN_ERR "EtherCAT: Could not open device!\n"); fp@73: return -1; fp@73: } fp@73: fp@73: return 0; fp@54: } fp@54: fp@54: /*****************************************************************************/ fp@54: fp@54: /** fp@54: Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet. fp@68: */ fp@68: fp@68: void ec_master_close(ec_master_t *master /**< EtherCAT-Master */) fp@54: { fp@73: if (!master->device_registered) { fp@73: printk(KERN_WARNING "EtherCAT: Warning -" fp@73: " Trying to close an unregistered device!\n"); fp@73: return; fp@73: } fp@73: fp@73: if (ec_device_close(&master->device) < 0) { fp@73: printk(KERN_WARNING "EtherCAT: Warning - Could not close device!\n"); fp@73: } fp@0: } fp@0: fp@39: /*****************************************************************************/ fp@0: fp@17: /** fp@52: Durchsucht den Bus nach Slaves. fp@17: fp@17: @return 0 bei Erfolg, sonst < 0 fp@17: */ fp@17: fp@68: int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */) fp@54: { fp@73: ec_frame_t frame; fp@73: ec_slave_t *slave; fp@73: ec_slave_ident_t *ident; fp@73: unsigned int i; fp@73: unsigned char data[2]; fp@73: fp@74: if (master->slaves || master->slave_count) fp@74: printk(KERN_WARNING "EtherCAT: Slave scan already done!\n"); fp@74: ec_master_clear_slaves(master); fp@73: fp@73: // Determine number of slaves on bus fp@73: fp@73: ec_frame_init_brd(&frame, master, 0x0000, 4); fp@73: if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1; fp@73: fp@73: master->slave_count = frame.working_counter; fp@73: printk("EtherCAT: Found %i slaves on bus.\n", master->slave_count); fp@73: fp@73: if (!master->slave_count) return 0; fp@73: fp@73: if (!(master->slaves = (ec_slave_t *) kmalloc(master->slave_count fp@73: * sizeof(ec_slave_t), fp@73: GFP_KERNEL))) { fp@73: printk(KERN_ERR "EtherCAT: Could not allocate memory for bus" fp@73: " slaves!\n"); fp@73: return -1; fp@73: } fp@73: fp@73: // Init slaves fp@73: for (i = 0; i < master->slave_count; i++) { fp@73: slave = master->slaves + i; fp@73: ec_slave_init(slave, master); fp@73: slave->ring_position = i; fp@73: slave->station_address = i + 1; fp@73: } fp@73: fp@73: // For every slave in the list fp@73: for (i = 0; i < master->slave_count; i++) fp@17: { fp@73: slave = master->slaves + i; fp@73: fp@73: // Write station address fp@73: data[0] = slave->station_address & 0x00FF; fp@73: data[1] = (slave->station_address & 0xFF00) >> 8; fp@73: fp@73: ec_frame_init_apwr(&frame, master, slave->ring_position, 0x0010, 2, fp@73: data); fp@73: fp@73: if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1; fp@73: fp@73: if (unlikely(frame.working_counter != 1)) { fp@73: printk(KERN_ERR "EtherCAT: Slave %i did not repond while writing" fp@73: " station address!\n", i); fp@73: return -1; fp@73: } fp@73: fp@73: // Fetch all slave information fp@73: if (ec_slave_fetch(slave)) return -1; fp@73: fp@73: // Search for identification in "database" fp@73: ident = slave_idents; fp@73: while (ident) { fp@73: if (unlikely(ident->vendor_id == slave->sii_vendor_id fp@73: && ident->product_code == slave->sii_product_code)) { fp@73: slave->type = ident->type; fp@73: break; fp@73: } fp@73: ident++; fp@73: } fp@73: fp@73: if (!slave->type) { fp@73: printk(KERN_WARNING "EtherCAT: Unknown slave device (vendor" fp@73: " 0x%08X, code 0x%08X) at position %i.\n", fp@73: slave->sii_vendor_id, slave->sii_product_code, i); fp@73: return 0; fp@73: } fp@73: } fp@73: fp@73: return 0; fp@54: } fp@54: fp@54: /*****************************************************************************/ fp@54: fp@54: /** fp@54: Gibt von Zeit zu Zeit die Anzahl verlorener Frames aus. fp@68: */ fp@68: fp@68: void ec_output_lost_frames(ec_master_t *master /**< EtherCAT-Master */) fp@54: { fp@73: unsigned long int t; fp@73: fp@73: if (master->frames_lost) { fp@73: rdtscl(t); fp@73: if ((t - master->t_lost_output) / cpu_khz > 1000) { fp@73: printk(KERN_ERR "EtherCAT: %u frame(s) LOST!\n", fp@73: master->frames_lost); fp@73: master->frames_lost = 0; fp@73: master->t_lost_output = t; fp@73: } fp@73: } fp@54: } fp@54: fp@68: /*****************************************************************************/ fp@68: fp@68: /** fp@68: Wandelt eine ASCII-kodierte Bus-Adresse in einen Slave-Zeiger. fp@68: fp@68: Gültige Adress-Strings sind Folgende: fp@68: fp@68: - \a "X" = der X. Slave im Bus, fp@68: - \a "X:Y" = der Y. Slave hinter dem X. Buskoppler, fp@68: - \a "#X" = der Slave mit der SSID X, fp@68: - \a "#X:Y" = der Y. Slave hinter dem Buskoppler mit der SSID X. fp@68: fp@68: \return Zeiger auf Slave bei Erfolg, sonst NULL fp@68: */ fp@68: fp@68: ec_slave_t *ec_address(const ec_master_t *master, fp@68: /**< EtherCAT-Master */ fp@68: const char *address fp@68: /**< Address-String */ fp@68: ) fp@68: { fp@73: unsigned long first, second; fp@73: char *remainder, *remainder2; fp@73: unsigned int i; fp@73: int coupler_idx, slave_idx; fp@73: ec_slave_t *slave; fp@73: fp@73: if (!address || address[0] == 0) return NULL; fp@73: fp@73: if (address[0] == '#') { fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - # not implemented" fp@73: " yet!\n", address); fp@73: return NULL; fp@73: } fp@73: fp@73: first = simple_strtoul(address, &remainder, 0); fp@73: if (remainder == address) { fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - First number empty!\n", fp@73: address); fp@73: return NULL; fp@73: } fp@73: fp@73: if (!remainder[0]) { // absolute position fp@73: if (first < master->slave_count) { fp@73: return master->slaves + first; fp@73: } fp@73: fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - Absolute position" fp@73: " illegal!\n", address); fp@73: } fp@73: fp@73: else if (remainder[0] == ':') { // field position fp@73: fp@73: remainder++; fp@73: second = simple_strtoul(remainder, &remainder2, 0); fp@73: fp@73: if (remainder2 == remainder) { fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - Sencond number" fp@73: " empty!\n", address); fp@73: return NULL; fp@73: } fp@73: fp@73: if (remainder2[0]) { fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - Illegal trailer" fp@73: " (2)!\n", address); fp@73: return NULL; fp@73: } fp@73: fp@73: coupler_idx = -1; fp@73: slave_idx = 0; fp@73: for (i = 0; i < master->slave_count; i++, slave_idx++) { fp@73: slave = master->slaves + i; fp@73: if (!slave->type) continue; fp@73: fp@73: if (strcmp(slave->type->vendor_name, "Beckhoff") == 0 && fp@73: strcmp(slave->type->product_name, "EK1100") == 0) { fp@73: coupler_idx++; fp@73: slave_idx = 0; fp@73: } fp@73: fp@73: if (coupler_idx == first && slave_idx == second) return slave; fp@73: } fp@73: } fp@73: fp@73: else { fp@73: printk(KERN_ERR "EtherCAT: Bus ID \"%s\" - Illegal trailer!\n", fp@73: address); fp@73: } fp@73: fp@68: return NULL; fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: /** fp@73: Initialisiert eine Sync-Manager-Konfigurationsseite. fp@73: fp@73: Der mit \a data referenzierte Speicher muss mindestens EC_SYNC_SIZE Bytes fp@73: groß sein. fp@73: */ fp@73: fp@73: void ec_sync_config(const ec_sync_t *sync, /**< Sync-Manager */ fp@73: uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ fp@73: ) fp@73: { fp@73: data[0] = sync->physical_start_address & 0xFF; fp@73: data[1] = (sync->physical_start_address >> 8) & 0xFF; fp@73: data[2] = sync->size & 0xFF; fp@73: data[3] = (sync->size >> 8) & 0xFF; fp@73: data[4] = sync->control_byte; fp@73: data[5] = 0x00; fp@73: data[6] = 0x01; // enable fp@73: data[7] = 0x00; fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: /** fp@73: Initialisiert eine FMMU-Konfigurationsseite. fp@73: fp@73: Der mit \a data referenzierte Speicher muss mindestens EC_FMMU_SIZE Bytes fp@73: groß sein. fp@73: */ fp@73: fp@73: void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< Sync-Manager */ fp@73: uint8_t *data /**> Zeiger auf Konfigurationsspeicher */ fp@73: ) fp@73: { fp@73: data[0] = fmmu->logical_start_address & 0xFF; fp@73: data[1] = (fmmu->logical_start_address >> 8) & 0xFF; fp@73: data[2] = (fmmu->logical_start_address >> 16) & 0xFF; fp@73: data[3] = (fmmu->logical_start_address >> 24) & 0xFF; fp@73: data[4] = fmmu->sync->size & 0xFF; fp@73: data[5] = (fmmu->sync->size >> 8) & 0xFF; fp@73: data[6] = 0x00; // Logical start bit fp@73: data[7] = 0x07; // Logical end bit fp@73: data[8] = fmmu->sync->physical_start_address & 0xFF; fp@73: data[9] = (fmmu->sync->physical_start_address >> 8) & 0xFF; fp@73: data[10] = 0x00; // Physical start bit fp@73: data[11] = (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01; fp@73: data[12] = 0x01; // Enable fp@73: data[13] = 0x00; // res. fp@73: data[14] = 0x00; // res. fp@73: data[15] = 0x00; // res. fp@68: } fp@68: fp@54: /****************************************************************************** fp@54: * fp@54: * Echtzeitschnittstelle fp@54: * fp@54: *****************************************************************************/ fp@54: fp@54: /** fp@73: Registriert eine neue Domäne. fp@73: fp@73: \return Zeiger auf die Domäne bei Erfolg, sonst NULL. fp@73: */ fp@73: fp@73: ec_domain_t *EtherCAT_rt_master_register_domain(ec_master_t *master, fp@73: /**< Domäne */ fp@73: ec_domain_mode_t mode, fp@73: /**< Modus */ fp@73: unsigned int timeout_us fp@73: /**< Timeout */ fp@73: ) fp@73: { fp@73: ec_domain_t *domain; fp@73: fp@73: if (master->domain_count >= EC_MASTER_MAX_DOMAINS) { fp@73: printk(KERN_ERR "EtherCAT: Maximum number of domains reached!\n"); fp@73: return NULL; fp@73: } fp@73: fp@73: if (!(domain = (ec_domain_t *) kmalloc(sizeof(ec_domain_t), GFP_KERNEL))) { fp@73: printk(KERN_ERR "EthertCAT: Error allocating domain memory!\n"); fp@73: return NULL; fp@73: } fp@73: fp@73: ec_domain_init(domain, master, mode, timeout_us); fp@73: master->domains[master->domain_count] = domain; fp@52: master->domain_count++; fp@73: fp@73: return domain; fp@73: } fp@61: fp@74: /*****************************************************************************/ fp@74: fp@61: /** fp@58: Konfiguriert alle Slaves und setzt den Operational-Zustand. fp@58: fp@58: Führt die komplette Konfiguration und Aktivierunge aller registrierten fp@58: Slaves durch. Setzt Sync-Manager und FMMU's, führt die entsprechenden fp@0: Zustandsübergänge durch, bis der Slave betriebsbereit ist. fp@0: fp@68: \return 0 bei Erfolg, sonst < 0 fp@68: */ fp@68: fp@73: int EtherCAT_rt_master_activate(ec_master_t *master /**< EtherCAT-Master */) fp@73: { fp@73: unsigned int i, j; fp@73: ec_slave_t *slave; fp@73: ec_frame_t frame; fp@73: const ec_sync_t *sync; fp@73: const ec_slave_type_t *type; fp@73: const ec_fmmu_t *fmmu; fp@73: uint8_t data[256]; fp@73: uint32_t domain_offset; fp@73: fp@73: // Domains erstellen fp@73: domain_offset = 0; fp@73: for (i = 0; i < master->domain_count; i++) { fp@73: ec_domain_t *domain = master->domains[i]; fp@73: if (ec_domain_alloc(domain, domain_offset)) { fp@73: printk(KERN_INFO "EtherCAT: Failed to allocate domain %i!\n", i); fp@73: return -1; fp@73: } fp@73: printk(KERN_INFO "EtherCAT: Domain %i - Allocated %i bytes (%i" fp@73: " Frame(s))\n", i, domain->data_size, fp@73: domain->data_size / EC_MAX_FRAME_SIZE + 1); fp@73: domain_offset += domain->data_size; fp@73: } fp@73: fp@73: // Slaves aktivieren fp@73: for (i = 0; i < master->slave_count; i++) fp@0: { fp@73: slave = master->slaves + i; fp@73: fp@73: // Change state to INIT fp@73: if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT))) fp@73: return -1; fp@73: fp@73: // Check if slave was registered... fp@73: if (!slave->type || !slave->registered) { fp@73: printk(KERN_INFO "EtherCAT: Slave %i was not registered.\n", i); fp@73: continue; fp@73: } fp@73: fp@73: type = slave->type; fp@73: fp@74: // Check and reset CRC fault counters fp@74: ec_slave_check_crc(slave); fp@74: fp@73: // Resetting FMMU's fp@73: if (slave->base_fmmu_count) { fp@73: memset(data, 0x00, EC_FMMU_SIZE * slave->base_fmmu_count); fp@73: ec_frame_init_npwr(&frame, master, slave->station_address, 0x0600, fp@73: EC_FMMU_SIZE * slave->base_fmmu_count, data); fp@73: if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1; fp@73: if (unlikely(frame.working_counter != 1)) { fp@73: printk(KERN_ERR "EtherCAT: Resetting FMMUs - Slave %i did" fp@73: " not respond!\n", slave->ring_position); fp@73: return -1; fp@73: } fp@73: } fp@73: fp@73: // Resetting Sync Manager channels fp@73: if (slave->base_sync_count) { fp@73: memset(data, 0x00, EC_SYNC_SIZE * slave->base_sync_count); fp@73: ec_frame_init_npwr(&frame, master, slave->station_address, 0x0800, fp@73: EC_SYNC_SIZE * slave->base_sync_count, data); fp@73: if (unlikely(ec_frame_send_receive(&frame) < 0)) return -1; fp@73: if (unlikely(frame.working_counter != 1)) { fp@73: printk(KERN_ERR "EtherCAT: Resetting SMs - Slave %i did not" fp@73: " respond!\n", slave->ring_position); fp@73: return -1; fp@73: } fp@73: } fp@73: fp@73: // Set Sync Managers fp@73: for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) fp@73: { fp@73: sync = type->sync_managers[j]; fp@73: fp@73: ec_sync_config(sync, data); fp@73: ec_frame_init_npwr(&frame, master, slave->station_address, fp@73: 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE, data); fp@73: fp@73: if (unlikely(ec_frame_send_receive(&frame))) return -1; fp@73: fp@73: if (unlikely(frame.working_counter != 1)) { fp@73: printk(KERN_ERR "EtherCAT: Setting sync manager %i - Slave" fp@73: " %i did not respond!\n", j, slave->ring_position); fp@73: return -1; fp@73: } fp@73: } fp@73: fp@73: // Change state to PREOP fp@73: if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_PREOP))) fp@73: return -1; fp@73: fp@73: // Set FMMUs fp@73: for (j = 0; j < slave->fmmu_count; j++) fp@73: { fp@73: fmmu = &slave->fmmus[j]; fp@73: fp@73: ec_fmmu_config(fmmu, data); fp@73: ec_frame_init_npwr(&frame, master, slave->station_address, fp@73: 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE, data); fp@73: fp@73: if (unlikely(ec_frame_send_receive(&frame))) return -1; fp@73: fp@73: if (unlikely(frame.working_counter != 1)) { fp@73: printk(KERN_ERR "EtherCAT: Setting FMMU %i - Slave %i did not" fp@73: " respond!\n", j, slave->ring_position); fp@73: return -1; fp@73: } fp@73: } fp@73: fp@73: // Change state to SAVEOP fp@73: if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_SAVEOP))) fp@73: return -1; fp@73: fp@73: // Change state to OP fp@73: if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_OP))) fp@73: return -1; fp@73: } fp@73: fp@73: return 0; fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: /** fp@73: Setzt alle Slaves zurück in den Init-Zustand. fp@73: fp@73: \return 0 bei Erfolg, sonst < 0 fp@73: */ fp@73: fp@73: int EtherCAT_rt_master_deactivate(ec_master_t *master /**< EtherCAT-Master */) fp@73: { fp@73: ec_slave_t *slave; fp@73: unsigned int i; fp@73: fp@73: for (i = 0; i < master->slave_count; i++) fp@0: { fp@73: slave = master->slaves + i; fp@73: fp@74: // CRC-Zählerstände ausgeben fp@74: ec_slave_check_crc(slave); fp@74: fp@73: if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT) != 0)) fp@73: return -1; fp@73: } fp@73: fp@73: return 0; fp@13: } fp@13: fp@39: /*****************************************************************************/ fp@13: fp@56: /** fp@56: Setzt die Debug-Ebene des Masters. fp@68: fp@68: Folgende Debug-level sind definiert: fp@68: fp@68: - 1: Nur Positionsmarken in bestimmten Funktionen fp@68: - 2: Komplette Frame-Inhalte fp@68: */ fp@68: fp@73: void EtherCAT_rt_master_debug(ec_master_t *master, fp@73: /**< EtherCAT-Master */ fp@73: int level fp@73: /**< Debug-Level */ fp@73: ) fp@73: { fp@73: master->debug_level = level; fp@73: fp@73: printk(KERN_INFO "EtherCAT: Master debug level set to %i.\n", level); fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: /** fp@73: Gibt alle Informationen zum Master aus. fp@73: */ fp@73: fp@73: void EtherCAT_rt_master_print(const ec_master_t *master fp@73: /**< EtherCAT-Master */ fp@73: ) fp@73: { fp@73: unsigned int i; fp@73: fp@73: printk(KERN_INFO "EtherCAT: *** Begin master information ***\n"); fp@73: fp@73: for (i = 0; i < master->slave_count; i++) { fp@73: ec_slave_print(&master->slaves[i]); fp@73: } fp@73: fp@73: printk(KERN_INFO "EtherCAT: *** End master information ***\n"); fp@73: } fp@73: fp@73: /*****************************************************************************/ fp@73: fp@73: EXPORT_SYMBOL(EtherCAT_rt_master_register_domain); fp@73: EXPORT_SYMBOL(EtherCAT_rt_master_activate); fp@73: EXPORT_SYMBOL(EtherCAT_rt_master_deactivate); fp@73: EXPORT_SYMBOL(EtherCAT_rt_master_debug); fp@73: EXPORT_SYMBOL(EtherCAT_rt_master_print); fp@42: fp@42: /*****************************************************************************/ fp@42: fp@42: /* Emacs-Konfiguration fp@42: ;;; Local Variables: *** fp@73: ;;; c-basic-offset:4 *** fp@42: ;;; End: *** fp@42: */