mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-08-18 17:17:23 +08:00
Neue ASCII-Adressierung und Code-Dokumantation.
This commit is contained in:
@@ -6,3 +6,5 @@ $Id$
|
||||
- Konfiguration SSI-/Inkrementalgeberklemmen (CoE)
|
||||
- Ethernet over EtherCAT (EoE)
|
||||
- eepro100-Kartentreiber
|
||||
- Proc/SysFS-Interface mit Baumdarstellung des Busses
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ ec_master_t *EtherCAT_rt_request_master(unsigned int master_index);
|
||||
void EtherCAT_rt_release_master(ec_master_t *master);
|
||||
|
||||
ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
|
||||
unsigned int slave_index,
|
||||
const char *address,
|
||||
const char *vendor_name,
|
||||
const char *product_name,
|
||||
int domain);
|
||||
@@ -106,9 +106,10 @@ struct ec_slave
|
||||
|
||||
struct ec_slave_init
|
||||
{
|
||||
ec_slave_t **slave_ptr; /**< Zeiger auf den Slave-Zeiger, der mit der
|
||||
Adresse des Slaves belegt werden soll. */
|
||||
unsigned int bus_index; /**< Bus-Index des zu registrierenden Slaves */
|
||||
ec_slave_t **slave_ptr; /**< Zeiger auf den Slave-Zeiger, der später auf
|
||||
die Slave-Struktur zeigen soll. */
|
||||
const char *address; /**< ASCII-kodierte Bus-Adresse des zu
|
||||
registrierenden Slaves \sa ec_address */
|
||||
const char *vendor_name; /**< Name des Herstellers */
|
||||
const char *product_name; /**< Name des Slaves-Typs */
|
||||
unsigned int domain; /**< Domäne, in der registriert werden soll. */
|
||||
|
||||
+446
-213
File diff suppressed because it is too large
Load Diff
@@ -48,6 +48,8 @@ doc:
|
||||
cleandoc:
|
||||
@rm -rf doc
|
||||
|
||||
.PHONY: doc
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
endif
|
||||
|
||||
+9
-10
@@ -30,13 +30,12 @@ ec_command_state_t;
|
||||
/**
|
||||
EtherCAT-Adresse.
|
||||
|
||||
Im EtherCAT-Rahmen sind 4 Bytes für die Adresse reserviert, die
|
||||
ja nach Kommandoty eine andere bedeutung haben: Bei Autoinkrement-
|
||||
befehlen sind die ersten zwei Bytes die (negative)
|
||||
Autoinkrement-Adresse, bei Knoten-adressierten Befehlen entsprechen
|
||||
sie der Knotenadresse. Das dritte und vierte Byte entspricht in
|
||||
diesen Fällen der physikalischen Speicheradresse auf dem Slave.
|
||||
Bei einer logischen Adressierung entsprechen alle vier Bytes
|
||||
Im EtherCAT-Rahmen sind 4 Bytes für die Adresse reserviert, die je nach
|
||||
Kommandotyp, eine andere Bedeutung haben können: Bei Autoinkrementbefehlen
|
||||
sind die ersten zwei Bytes die (negative) Autoinkrement-Adresse, bei Knoten-
|
||||
adressierten Befehlen entsprechen sie der Knotenadresse. Das dritte und
|
||||
vierte Byte entspricht in diesen Fällen der physikalischen Speicheradresse
|
||||
auf dem Slave. Bei einer logischen Adressierung entsprechen alle vier Bytes
|
||||
der logischen Adresse.
|
||||
*/
|
||||
|
||||
@@ -53,7 +52,7 @@ typedef union
|
||||
|
||||
unsigned short mem; /**< Physikalische Speicheradresse im Slave */
|
||||
}
|
||||
phy;
|
||||
phy; /**< Physikalische Adresse */
|
||||
|
||||
unsigned long logical; /**< Logische Adresse */
|
||||
unsigned char raw[4]; /**< Rohdaten für die Generierung des Frames */
|
||||
@@ -68,12 +67,12 @@ ec_address_t;
|
||||
|
||||
typedef struct ec_command
|
||||
{
|
||||
ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc...) */
|
||||
ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc) */
|
||||
ec_address_t address; /**< Adresse des/der Empfänger */
|
||||
unsigned int data_length; /**< Länge der zu sendenden und/oder
|
||||
empfangenen Daten */
|
||||
ec_command_state_t state; /**< Zustand des Kommandos
|
||||
(bereit, gesendet, etc...) */
|
||||
(bereit, gesendet, etc) */
|
||||
unsigned char index; /**< Kommando-Index, mit der das Kommando gesendet
|
||||
wurde (wird vom Master beim Senden gesetzt. */
|
||||
unsigned int working_counter; /**< Working-Counter bei Empfang (wird
|
||||
|
||||
+182
-100
@@ -36,11 +36,11 @@ void ec_output_lost_frames(ec_master_t *);
|
||||
|
||||
/**
|
||||
Konstruktor des EtherCAT-Masters.
|
||||
|
||||
@param master Zeiger auf den zu initialisierenden EtherCAT-Master
|
||||
*/
|
||||
|
||||
void ec_master_init(ec_master_t *master)
|
||||
void ec_master_init(ec_master_t *master
|
||||
/**< Zeiger auf den zu initialisierenden EtherCAT-Master */
|
||||
)
|
||||
{
|
||||
master->bus_slaves = NULL;
|
||||
master->bus_slaves_count = 0;
|
||||
@@ -62,11 +62,11 @@ void ec_master_init(ec_master_t *master)
|
||||
|
||||
Entfernt alle Kommandos aus der Liste, löscht den Zeiger
|
||||
auf das Slave-Array und gibt die Prozessdaten frei.
|
||||
|
||||
@param master Zeiger auf den zu löschenden Master
|
||||
*/
|
||||
|
||||
void ec_master_clear(ec_master_t *master)
|
||||
void ec_master_clear(ec_master_t *master
|
||||
/**< Zeiger auf den zu löschenden Master */
|
||||
)
|
||||
{
|
||||
if (master->bus_slaves) {
|
||||
kfree(master->bus_slaves);
|
||||
@@ -85,11 +85,11 @@ void ec_master_clear(ec_master_t *master)
|
||||
|
||||
Bei einem "release" sollte immer diese Funktion aufgerufen werden,
|
||||
da sonst Slave-Liste, Domains, etc. weiter existieren.
|
||||
|
||||
@param master Zeiger auf den zurückzusetzenden Master
|
||||
*/
|
||||
|
||||
void ec_master_reset(ec_master_t *master)
|
||||
void ec_master_reset(ec_master_t *master
|
||||
/**< Zeiger auf den zurückzusetzenden Master */
|
||||
)
|
||||
{
|
||||
if (master->bus_slaves) {
|
||||
kfree(master->bus_slaves);
|
||||
@@ -112,13 +112,11 @@ void ec_master_reset(ec_master_t *master)
|
||||
/**
|
||||
Öffnet das EtherCAT-Geraet des Masters.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
|
||||
@return 0, wenn alles o.k., < 0, wenn das Geraet nicht geoeffnet werden
|
||||
konnte.
|
||||
\return 0, wenn alles o.k., < 0, wenn kein Gerät registriert wurde oder
|
||||
es nicht geoeffnet werden konnte.
|
||||
*/
|
||||
|
||||
int ec_master_open(ec_master_t *master)
|
||||
int ec_master_open(ec_master_t *master /**< Der EtherCAT-Master */)
|
||||
{
|
||||
if (!master->device_registered) {
|
||||
printk(KERN_ERR "EtherCAT: No device registered!\n");
|
||||
@@ -137,11 +135,9 @@ int ec_master_open(ec_master_t *master)
|
||||
|
||||
/**
|
||||
Schliesst das EtherCAT-Geraet, auf dem der Master arbeitet.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
*/
|
||||
|
||||
void ec_master_close(ec_master_t *master)
|
||||
void ec_master_close(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
if (!master->device_registered) {
|
||||
printk(KERN_WARNING "EtherCAT: Warning -"
|
||||
@@ -160,13 +156,14 @@ void ec_master_close(ec_master_t *master)
|
||||
Sendet ein einzelnes Kommando in einem Frame und
|
||||
wartet auf dessen Empfang.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param cmd Kommando zum Senden/Empfangen
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_simple_send_receive(ec_master_t *master, ec_command_t *cmd)
|
||||
int ec_simple_send_receive(ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
ec_command_t *cmd
|
||||
/**< Kommando zum Senden/Empfangen */
|
||||
)
|
||||
{
|
||||
unsigned int tries_left;
|
||||
|
||||
@@ -194,13 +191,12 @@ int ec_simple_send_receive(ec_master_t *master, ec_command_t *cmd)
|
||||
/**
|
||||
Sendet ein einzelnes Kommando in einem Frame.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param cmd Kommando zum Senden
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_simple_send(ec_master_t *master, ec_command_t *cmd)
|
||||
int ec_simple_send(ec_master_t *master, /**< EtherCAT-Master */
|
||||
ec_command_t *cmd /**< Kommando zum Senden */
|
||||
)
|
||||
{
|
||||
unsigned int length, framelength, i;
|
||||
|
||||
@@ -294,13 +290,12 @@ int ec_simple_send(ec_master_t *master, ec_command_t *cmd)
|
||||
Wartet auf den Empfang eines einzeln gesendeten
|
||||
Kommandos.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param cmd Gesendetes Kommando
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_simple_receive(ec_master_t *master, ec_command_t *cmd)
|
||||
int ec_simple_receive(ec_master_t *master, /**< EtherCAT-Master */
|
||||
ec_command_t *cmd /**< Gesendetes Kommando */
|
||||
)
|
||||
{
|
||||
unsigned int length;
|
||||
int ret;
|
||||
@@ -377,12 +372,10 @@ int ec_simple_receive(ec_master_t *master, ec_command_t *cmd)
|
||||
/**
|
||||
Durchsucht den Bus nach Slaves.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_scan_for_slaves(ec_master_t *master)
|
||||
int ec_scan_for_slaves(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
ec_command_t cmd;
|
||||
ec_slave_t *slave;
|
||||
@@ -510,17 +503,19 @@ int ec_scan_for_slaves(ec_master_t *master)
|
||||
Liest Daten aus dem Slave-Information-Interface
|
||||
eines EtherCAT-Slaves.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param node_address Knotenadresse des Slaves
|
||||
@param offset Adresse des zu lesenden SII-Registers
|
||||
@param target Zeiger auf einen 4 Byte großen Speicher
|
||||
zum Ablegen der Daten
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_sii_read(ec_master_t *master, unsigned short int node_address,
|
||||
unsigned short int offset, unsigned int *target)
|
||||
int ec_sii_read(ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
unsigned short int node_address,
|
||||
/**< Knotenadresse des Slaves */
|
||||
unsigned short int offset,
|
||||
/**< Adresse des zu lesenden SII-Registers */
|
||||
unsigned int *target
|
||||
/**< Zeiger auf einen 4 Byte großen Speicher zum Ablegen der
|
||||
Daten */
|
||||
)
|
||||
{
|
||||
ec_command_t cmd;
|
||||
unsigned char data[10];
|
||||
@@ -586,20 +581,18 @@ int ec_sii_read(ec_master_t *master, unsigned short int node_address,
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Ändert den Zustand eines Slaves (asynchron).
|
||||
Ändert den Zustand eines Slaves.
|
||||
|
||||
Führt eine (asynchrone) Zustandsänderung bei einem Slave durch.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param slave Slave, dessen Zustand geändert werden soll
|
||||
@param state_and_ack Neuer Zustand, evtl. mit gesetztem
|
||||
Acknowledge-Flag
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int ec_state_change(ec_master_t *master, ec_slave_t *slave,
|
||||
unsigned char state_and_ack)
|
||||
int ec_state_change(ec_master_t *master,
|
||||
/**<EtherCAT-Master */
|
||||
ec_slave_t *slave,
|
||||
/**< Slave, dessen Zustand geändert werden soll */
|
||||
unsigned char state_and_ack
|
||||
/**< Neuer Zustand, evtl. mit gesetztem Acknowledge-Flag */
|
||||
)
|
||||
{
|
||||
ec_command_t cmd;
|
||||
unsigned char data[2];
|
||||
@@ -670,11 +663,9 @@ int ec_state_change(ec_master_t *master, ec_slave_t *slave,
|
||||
|
||||
/**
|
||||
Gibt Frame-Inhalte zwecks Debugging aus.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
*/
|
||||
|
||||
void ec_output_debug_data(const ec_master_t *master)
|
||||
void ec_output_debug_data(const ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@@ -705,11 +696,9 @@ void ec_output_debug_data(const ec_master_t *master)
|
||||
|
||||
/**
|
||||
Gibt von Zeit zu Zeit die Anzahl verlorener Frames aus.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
*/
|
||||
|
||||
void ec_output_lost_frames(ec_master_t *master)
|
||||
void ec_output_lost_frames(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
unsigned long int t;
|
||||
|
||||
@@ -723,6 +712,92 @@ void ec_output_lost_frames(ec_master_t *master)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
Wandelt eine ASCII-kodierte Bus-Adresse in einen Slave-Zeiger.
|
||||
|
||||
Gültige Adress-Strings sind Folgende:
|
||||
|
||||
- \a "X" = der X. Slave im Bus,
|
||||
- \a "X:Y" = der Y. Slave hinter dem X. Buskoppler,
|
||||
- \a "#X" = der Slave mit der SSID X,
|
||||
- \a "#X:Y" = der Y. Slave hinter dem Buskoppler mit der SSID X.
|
||||
|
||||
\return Zeiger auf Slave bei Erfolg, sonst NULL
|
||||
*/
|
||||
|
||||
ec_slave_t *ec_address(const ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
const char *address
|
||||
/**< Address-String */
|
||||
)
|
||||
{
|
||||
unsigned long first, second;
|
||||
char *remainder, *remainder2;
|
||||
unsigned int i;
|
||||
int coupler_idx, slave_idx;
|
||||
ec_slave_t *slave;
|
||||
|
||||
if (!address || address[0] == 0) return NULL;
|
||||
|
||||
if (address[0] == '#') {
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - #<SSID> not implemented yet!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
first = simple_strtoul(address, &remainder, 0);
|
||||
if (remainder == address) {
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - First number empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!remainder[0]) { // absolute position
|
||||
if (first < master->bus_slaves_count) {
|
||||
return master->bus_slaves + first;
|
||||
}
|
||||
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - Absolute position illegal!\n");
|
||||
}
|
||||
|
||||
else if (remainder[0] == ':') { // field position
|
||||
|
||||
remainder++;
|
||||
second = simple_strtoul(remainder, &remainder2, 0);
|
||||
|
||||
if (remainder2 == remainder) {
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - Sencond number empty!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (remainder2[0]) {
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - Illegal trailer (2)!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
coupler_idx = -1;
|
||||
slave_idx = 0;
|
||||
for (i = 0; i < master->bus_slaves_count; i++, slave_idx++) {
|
||||
slave = master->bus_slaves + i;
|
||||
if (!slave->type) continue;
|
||||
|
||||
if (strcmp(slave->type->vendor_name, "Beckhoff") == 0 &&
|
||||
strcmp(slave->type->product_name, "EK1100") == 0) {
|
||||
coupler_idx++;
|
||||
slave_idx = 0;
|
||||
}
|
||||
|
||||
if (coupler_idx == first && slave_idx == second) return slave;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
printk(KERN_ERR "EtherCAT: Bus ID - Illegal trailer!\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Echtzeitschnittstelle
|
||||
@@ -732,20 +807,21 @@ void ec_output_lost_frames(ec_master_t *master)
|
||||
/**
|
||||
Registriert einen Slave beim Master.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
@param bus_index Index des Slaves im EtherCAT-Bus
|
||||
@param vendor_name String mit dem Herstellernamen
|
||||
@param product_name String mit dem Produktnamen
|
||||
@param domain Domäne, in der der Slave sein soll
|
||||
|
||||
@return Zeiger auf den Slave bei Erfolg, sonst NULL
|
||||
\return Zeiger auf den Slave bei Erfolg, sonst NULL
|
||||
*/
|
||||
|
||||
ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
|
||||
unsigned int bus_index,
|
||||
/**< EtherCAT-Master */
|
||||
const char *address,
|
||||
/**< ASCII-Addresse des Slaves, siehe
|
||||
auch ec_address() */
|
||||
const char *vendor_name,
|
||||
/**< Herstellername */
|
||||
const char *product_name,
|
||||
int domain)
|
||||
/**< Produktname */
|
||||
int domain
|
||||
/**< Domäne */
|
||||
)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
const ec_slave_type_t *type;
|
||||
@@ -757,21 +833,20 @@ ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bus_index >= master->bus_slaves_count) {
|
||||
printk(KERN_ERR "EtherCAT: Illegal bus index! (%i / %i)\n", bus_index,
|
||||
master->bus_slaves_count);
|
||||
if ((slave = ec_address(master, address)) == NULL) {
|
||||
printk(KERN_ERR "EtherCAT: Illegal address: \"%s\"\n", address);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
slave = master->bus_slaves + bus_index;
|
||||
|
||||
if (slave->registered) {
|
||||
printk(KERN_ERR "EtherCAT: Slave %i is already registered!\n", bus_index);
|
||||
printk(KERN_ERR "EtherCAT: Slave \"%s\" (position %i) has already been"
|
||||
" registered!\n", address, slave->ring_position * (-1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!slave->type) {
|
||||
printk(KERN_ERR "EtherCAT: Unknown slave at position %i!\n", bus_index);
|
||||
printk(KERN_ERR "EtherCAT: Slave \"%s\" (position %i) has unknown type!\n",
|
||||
address, slave->ring_position * (-1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -829,23 +904,24 @@ ec_slave_t *EtherCAT_rt_register_slave(ec_master_t *master,
|
||||
/**
|
||||
Registriert eine ganze Liste von Slaves beim Master.
|
||||
|
||||
@param master Der EtherCAT-Master
|
||||
@param slaves Array von Slave-Initialisierungsstrukturen
|
||||
@param count Anzahl der Strukturen in "slaves"
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_rt_register_slave_list(ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
const ec_slave_init_t *slaves,
|
||||
unsigned int count)
|
||||
/**< Array von Slave-Initialisierungs-
|
||||
strukturen */
|
||||
unsigned int count
|
||||
/**< Anzahl der Strukturen in \a slaves */
|
||||
)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if ((*(slaves[i].slave_ptr) =
|
||||
EtherCAT_rt_register_slave(master, slaves[i].bus_index,
|
||||
EtherCAT_rt_register_slave(master, slaves[i].address,
|
||||
slaves[i].vendor_name,
|
||||
slaves[i].product_name,
|
||||
slaves[i].domain)) == NULL)
|
||||
@@ -864,12 +940,10 @@ int EtherCAT_rt_register_slave_list(ec_master_t *master,
|
||||
Slaves durch. Setzt Sync-Manager und FMMU's, führt die entsprechenden
|
||||
Zustandsübergänge durch, bis der Slave betriebsbereit ist.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_rt_activate_slaves(ec_master_t *master)
|
||||
int EtherCAT_rt_activate_slaves(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
unsigned int i;
|
||||
ec_slave_t *slave;
|
||||
@@ -1072,12 +1146,10 @@ int EtherCAT_rt_activate_slaves(ec_master_t *master)
|
||||
/**
|
||||
Setzt alle Slaves zurück in den Init-Zustand.
|
||||
|
||||
@param master EtherCAT-Master
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_rt_deactivate_slaves(ec_master_t *master)
|
||||
int EtherCAT_rt_deactivate_slaves(ec_master_t *master /**< EtherCAT-Master */)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
unsigned int i;
|
||||
@@ -1098,15 +1170,16 @@ int EtherCAT_rt_deactivate_slaves(ec_master_t *master)
|
||||
/**
|
||||
Sendet und empfängt Prozessdaten der angegebenen Domäne
|
||||
|
||||
@param master EtherCAT-Master
|
||||
@param domain Domäne
|
||||
@param timeout_us Timeout in Mikrosekunden
|
||||
|
||||
@return 0 bei Erfolg, sonst < 0
|
||||
\return 0 bei Erfolg, sonst < 0
|
||||
*/
|
||||
|
||||
int EtherCAT_rt_domain_xio(ec_master_t *master, unsigned int domain,
|
||||
unsigned int timeout_us)
|
||||
int EtherCAT_rt_domain_xio(ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
unsigned int domain,
|
||||
/**< Domäne */
|
||||
unsigned int timeout_us
|
||||
/**< Timeout in Mikrosekunden */
|
||||
)
|
||||
{
|
||||
unsigned int i;
|
||||
ec_domain_t *dom;
|
||||
@@ -1183,9 +1256,18 @@ int EtherCAT_rt_domain_xio(ec_master_t *master, unsigned int domain,
|
||||
|
||||
/**
|
||||
Setzt die Debug-Ebene des Masters.
|
||||
|
||||
Folgende Debug-level sind definiert:
|
||||
|
||||
- 1: Nur Positionsmarken in bestimmten Funktionen
|
||||
- 2: Komplette Frame-Inhalte
|
||||
*/
|
||||
|
||||
void EtherCAT_rt_debug_level(ec_master_t *master, int level)
|
||||
void EtherCAT_rt_debug_level(ec_master_t *master,
|
||||
/**< EtherCAT-Master */
|
||||
int level
|
||||
/**< Debug-Level */
|
||||
)
|
||||
{
|
||||
master->debug_level = level;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ void ec_master_close(ec_master_t *);
|
||||
|
||||
// Slave management
|
||||
int ec_scan_for_slaves(ec_master_t *);
|
||||
ec_slave_t *ec_address(const ec_master_t *, const char *);
|
||||
|
||||
// Data
|
||||
int ec_simple_send_receive(ec_master_t *, ec_command_t *);
|
||||
|
||||
+23
-6
@@ -24,9 +24,9 @@ struct timer_list timer;
|
||||
|
||||
ec_slave_init_t slaves[] = {
|
||||
// Zeiger, Index, Herstellername, Produktname, Domäne
|
||||
{ &s_out, 2, "Beckhoff", "EL2004", 1 },
|
||||
{ &s_in, 1, "Beckhoff", "EL3102", 1 },
|
||||
{ &s_ssi, 7, "Beckhoff", "EL5001", 1 }
|
||||
{ &s_in, "1", "Beckhoff", "EL3102", 1 },
|
||||
{ &s_out, "2", "Beckhoff", "EL2004", 1 },
|
||||
{ &s_ssi, "3", "Beckhoff", "EL5001", 1 }
|
||||
};
|
||||
|
||||
#define SLAVE_COUNT (sizeof(slaves) / sizeof(ec_slave_init_t))
|
||||
@@ -35,12 +35,28 @@ ec_slave_init_t slaves[] = {
|
||||
|
||||
void run(unsigned long data)
|
||||
{
|
||||
static unsigned int counter;
|
||||
|
||||
// Klemmen-IO
|
||||
EC_WRITE_EL20XX(s_out, 3, EC_READ_EL31XX(s_in, 0) < 0);
|
||||
|
||||
if (!counter) {
|
||||
EtherCAT_rt_debug_level(master, 2);
|
||||
}
|
||||
|
||||
// Prozessdaten lesen und schreiben
|
||||
EtherCAT_rt_domain_xio(master, 1, 100);
|
||||
|
||||
if (counter) {
|
||||
counter--;
|
||||
}
|
||||
else {
|
||||
EtherCAT_rt_debug_level(master, 0);
|
||||
printk("SSI status=%X value=%u\n",
|
||||
EC_READ_EL5001_STATE(s_ssi), EC_READ_EL5001_VALUE(s_ssi));
|
||||
counter = 1000;
|
||||
}
|
||||
|
||||
// Timer neu starten
|
||||
timer.expires += HZ / 1000;
|
||||
add_timer(&timer);
|
||||
@@ -71,14 +87,15 @@ int __init init_mini_module(void)
|
||||
|
||||
printk("Configuring EtherCAT slaves.\n");
|
||||
|
||||
EtherCAT_rt_debug_level(master, 2);
|
||||
|
||||
if (EtherCAT_rt_canopen_sdo_write(master, s_ssi, 0x4067, 0, 2, 2)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not set SSI baud rate!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
EtherCAT_rt_debug_level(master, 0);
|
||||
if (EtherCAT_rt_canopen_sdo_write(master, s_ssi, 0x4061, 4, 1, 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not set SSI feature bit!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
printk("Starting cyclic sample thread.\n");
|
||||
|
||||
|
||||
+36
-27
@@ -52,16 +52,15 @@ static struct ipipe_sysinfo sys_info;
|
||||
|
||||
// EtherCAT
|
||||
ec_master_t *master = NULL;
|
||||
ec_slave_t *s_in1, *s_out1, *s_out2, *s_out3;
|
||||
ec_slave_t *s_in1, *s_out1, *s_ssi, *s_inc;
|
||||
|
||||
double value;
|
||||
int dig1;
|
||||
uint16_t angle0;
|
||||
|
||||
ec_slave_init_t slaves[] = {
|
||||
{&s_in1, 1, "Beckhoff", "EL3102", 0},
|
||||
{&s_out1, 8, "Beckhoff", "EL2004", 0},
|
||||
{&s_out2, 9, "Beckhoff", "EL2004", 0},
|
||||
{&s_out3, 10, "Beckhoff", "EL2004", 0}
|
||||
{&s_in1, "1", "Beckhoff", "EL3102", 0},
|
||||
{&s_out1, "2", "Beckhoff", "EL2004", 0},
|
||||
{&s_ssi, "3", "Beckhoff", "EL5001", 0},
|
||||
{&s_inc, "0:4", "Beckhoff", "EL5101", 0}
|
||||
};
|
||||
|
||||
#define SLAVE_COUNT (sizeof(slaves) / sizeof(ec_slave_init_t))
|
||||
@@ -78,30 +77,29 @@ static void msr_controller_run(void)
|
||||
|
||||
msr_jitter_run(MSR_ABTASTFREQUENZ);
|
||||
|
||||
EC_WRITE_EL20XX(s_out1, 3, EC_READ_EL31XX(s_in1, 0) < 0);
|
||||
|
||||
if (!counter) {
|
||||
EtherCAT_rt_debug_level(master, 2);
|
||||
}
|
||||
|
||||
// Prozessdaten lesen und schreiben
|
||||
EtherCAT_rt_domain_xio(master, 0, 40);
|
||||
|
||||
if (counter) {
|
||||
counter--;
|
||||
}
|
||||
else {
|
||||
// "Star Trek"-Effekte
|
||||
EC_WRITE_EL20XX(s_out1, 0, jiffies & 1);
|
||||
EC_WRITE_EL20XX(s_out1, 1, (jiffies >> 1) & 1);
|
||||
EC_WRITE_EL20XX(s_out1, 2, (jiffies >> 2) & 1);
|
||||
EC_WRITE_EL20XX(s_out1, 3, (jiffies >> 3) & 1);
|
||||
EC_WRITE_EL20XX(s_out2, 0, (jiffies >> 4) & 1);
|
||||
EC_WRITE_EL20XX(s_out2, 1, (jiffies >> 3) & 1);
|
||||
EC_WRITE_EL20XX(s_out2, 2, (jiffies >> 2) & 1);
|
||||
EC_WRITE_EL20XX(s_out2, 3, (jiffies >> 6) & 1);
|
||||
EC_WRITE_EL20XX(s_out3, 0, (jiffies >> 7) & 1);
|
||||
EC_WRITE_EL20XX(s_out3, 1, (jiffies >> 2) & 1);
|
||||
EC_WRITE_EL20XX(s_out3, 2, (jiffies >> 8) & 1);
|
||||
EtherCAT_rt_debug_level(master, 0);
|
||||
printk("SSI status=0x%X value=%u\n",
|
||||
EC_READ_EL5001_STATE(s_ssi), EC_READ_EL5001_VALUE(s_ssi));
|
||||
printk("INC status=0x%X value=%u\n",
|
||||
EC_READ_EL5101_STATE(s_inc), EC_READ_EL5101_VALUE(s_inc));
|
||||
|
||||
counter = MSR_ABTASTFREQUENZ / 4;
|
||||
counter = MSR_ABTASTFREQUENZ * 5;
|
||||
}
|
||||
|
||||
EC_WRITE_EL20XX(s_out3, 3, EC_READ_EL31XX(s_in1, 0) < 0);
|
||||
|
||||
// Prozessdaten lesen und schreiben
|
||||
EtherCAT_rt_domain_xio(master, 0, 40);
|
||||
angle0 = EC_READ_EL5101_VALUE(s_inc);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -143,7 +141,7 @@ void domain_entry(void)
|
||||
ipipe_virtualize_irq(ipipe_current_domain,sys_info.archdep.tmirq,
|
||||
&msr_run, NULL, IPIPE_HANDLE_MASK);
|
||||
|
||||
ipipe_tune_timer(1000000000UL/MSR_ABTASTFREQUENZ,0);
|
||||
ipipe_tune_timer(1000000000UL / MSR_ABTASTFREQUENZ, 0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -162,8 +160,9 @@ void domain_entry(void)
|
||||
|
||||
int msr_globals_register(void)
|
||||
{
|
||||
msr_reg_kanal("/value", "V", &value, TDBL);
|
||||
msr_reg_kanal("/dig1", "", &dig1, TINT);
|
||||
//msr_reg_kanal("/value", "V", &value, TDBL);
|
||||
//msr_reg_kanal("/dig1", "", &dig1, TINT);
|
||||
msr_reg_kanal("/angle0", "", &angle0, TINT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -201,6 +200,16 @@ int __init init_rt_module(void)
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
if (EtherCAT_rt_canopen_sdo_write(master, s_ssi, 0x4067, 0, 1, 2)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not set SSI baud rate!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
if (EtherCAT_rt_canopen_sdo_write(master, s_ssi, 0x4061, 4, 1, 1)) {
|
||||
printk(KERN_ERR "EtherCAT: Could not set SSI feature bit!\n");
|
||||
goto out_release_master;
|
||||
}
|
||||
|
||||
do_gettimeofday(&process_time);
|
||||
msr_time_increment.tv_sec = 0;
|
||||
msr_time_increment.tv_usec = (unsigned int) (1000000 / MSR_ABTASTFREQUENZ);
|
||||
|
||||
Reference in New Issue
Block a user