Translated all comments and documentation to english language.

This commit is contained in:
Florian Pose
2006-04-20 13:31:31 +00:00
parent 09ac0b540f
commit 91c739da77
27 changed files with 1114 additions and 1381 deletions

View File

@@ -9,7 +9,7 @@
ifneq ($(KERNELRELEASE),)
#------------------------------------------------------------------------------
# kbuild section
# kbuild section
obj-m := master/ devices/
@@ -18,7 +18,7 @@ obj-m := master/ devices/
else
#------------------------------------------------------------------------------
# default section
# default section
ifneq ($(wildcard ethercat.conf),)
include ethercat.conf

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/******************************************************************************
*
* Oeffentliche EtherCAT-Schnittstellen fuer EtherCAT-Geraetetreiber.
* EtherCAT interface for EtherCAT device drivers.
*
* $Id$
* $Id$
*
*****************************************************************************/

View File

@@ -1,6 +1,6 @@
/******************************************************************************
*
* Oeffentliche EtherCAT-Schnittstellen fuer Echtzeitprozesse.
* EtherCAT realtime interface.
*
* $Id$
*

View File

@@ -28,14 +28,14 @@ const ec_code_msg_t sdo_abort_messages[];
/*****************************************************************************/
/**
Liest 32 Bit eines CANopen-SDOs im Expedited-Modus aus einem Slave.
\return 0 wenn alles ok, < 0 bei Fehler
Reads 32 bit of a CANopen SDO in expedited mode.
\return 0 in case of success, else < 0
*/
int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint8_t *target /**< Speicher für 4 Bytes */
int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint8_t *target /**< 4-byte memory */
)
{
size_t rec_size;
@@ -45,14 +45,14 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
EC_WRITE_U16(data, 0x2 << 12); // SDO request
EC_WRITE_U8 (data + 2, (0x1 << 1 // expedited transfer
| 0x2 << 5)); // initiate upload request
| 0x2 << 5)); // initiate upload request
EC_WRITE_U16(data + 3, sdo_index);
EC_WRITE_U8 (data + 5, sdo_subindex);
if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
sdo_index, sdo_subindex, slave->ring_position);
ec_canopen_abort_msg(EC_READ_U32(data + 6));
@@ -60,9 +60,9 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
}
if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
EC_READ_U8 (data + 2) >> 5 != 0x2 || // Upload response
EC_READ_U16(data + 3) != sdo_index || // Index
EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
EC_READ_U8 (data + 2) >> 5 != 0x2 || // upload response
EC_READ_U16(data + 3) != sdo_index || // index
EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
EC_ERR("Invalid SDO upload response at slave %i!\n",
slave->ring_position);
@@ -77,14 +77,14 @@ int ec_slave_sdo_read_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Beschreibt ein CANopen-SDO eines Slaves im Expedited-Modus.
\return 0 wenn alles ok, < 0 bei Fehler
Writes a CANopen SDO using expedited mode.
\return 0 in case of success, else < 0
*/
int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
const uint8_t *sdo_data, /**< Neuer Wert */
int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
const uint8_t *sdo_data, /**< new value */
size_t size
)
{
@@ -111,7 +111,7 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
EC_ERR("SDO download 0x%04X:%X (%i bytes) aborted on slave %i.\n",
sdo_index, sdo_subindex, size, slave->ring_position);
ec_canopen_abort_msg(EC_READ_U32(data + 6));
@@ -119,9 +119,9 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
}
if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response
EC_READ_U16(data + 3) != sdo_index || // Index
EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
EC_READ_U8 (data + 2) >> 5 != 0x3 || // download response
EC_READ_U16(data + 3) != sdo_index || // index
EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
EC_ERR("SDO download 0x%04X:%X (%i bytes) failed:\n",
sdo_index, sdo_subindex, size);
EC_ERR("Invalid SDO download response at slave %i!\n",
@@ -136,15 +136,17 @@ int ec_slave_sdo_write_exp(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Liest ein CANopen-SDO im "Normal-Modus" aus einem Slave.
\return 0 wenn alles ok, < 0 bei Fehler
Reads a CANopen SDO in normal mode.
\return 0 in case of success, else < 0
\todo size
*/
int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint8_t *target, /**< Speicher für gel. Wert */
size_t *size /**< Größe des Speichers */
int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint8_t *target, /**< memory for value */
size_t *size /**< target memory size */
)
{
uint8_t *data;
@@ -161,7 +163,7 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */
if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
if (EC_READ_U16(data) >> 12 == 0x2 && // SDO request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // Abort SDO transfer request
EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort SDO transfer request
EC_ERR("SDO upload 0x%04X:%X aborted on slave %i.\n",
sdo_index, sdo_subindex, slave->ring_position);
ec_canopen_abort_msg(EC_READ_U32(data + 6));
@@ -169,9 +171,9 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */
}
if (EC_READ_U16(data) >> 12 != 0x3 || // SDO response
EC_READ_U8 (data + 2) >> 5 != 0x2 || // Initiate upload response
EC_READ_U16(data + 3) != sdo_index || // Index
EC_READ_U8 (data + 5) != sdo_subindex) { // Subindex
EC_READ_U8 (data + 2) >> 5 != 0x2 || // initiate upload response
EC_READ_U16(data + 3) != sdo_index || // index
EC_READ_U8 (data + 5) != sdo_subindex) { // subindex
EC_ERR("SDO upload 0x%04X:%X failed:\n", sdo_index, sdo_subindex);
EC_ERR("Invalid SDO upload response at slave %i!\n",
slave->ring_position);
@@ -205,11 +207,11 @@ int ecrt_slave_sdo_read(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Lädt das gesamte SDO-Dictionary aus einem Slave.
\return 0, wenn alles ok, sonst < 0
Fetches the SDO dictionary of a slave.
\return 0 in case of success, else < 0
*/
int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT slave */)
{
uint8_t *data;
size_t rec_size;
@@ -223,7 +225,7 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
EC_WRITE_U8 (data + 2, 0x01); // Get OD List Request
EC_WRITE_U8 (data + 3, 0x00);
EC_WRITE_U16(data + 4, 0x0000);
EC_WRITE_U16(data + 6, 0x0001); // Deliver all SDOs!
EC_WRITE_U16(data + 6, 0x0001); // deliver all SDOs!
if (unlikely(ec_master_simple_io(slave->master, &slave->mbox_command))) {
EC_ERR("Mailbox checking failed on slave %i!\n", slave->ring_position);
@@ -235,7 +237,7 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
return -1;
if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
(EC_READ_U8(data + 2) & 0x7F) == 0x07) { // Error response
(EC_READ_U8(data + 2) & 0x7F) == 0x07) { // error response
EC_ERR("SDO information error response at slave %i!\n",
slave->ring_position);
ec_canopen_abort_msg(EC_READ_U32(data + 6));
@@ -259,7 +261,7 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
sdo_count = (rec_size - 8) / 2;
for (i = 0; i < sdo_count; i++) {
sdo_index = EC_READ_U16(data + 8 + i * 2);
if (!sdo_index) continue; // Manchmal ist der Index 0... ???
if (!sdo_index) continue; // sometimes index is 0... ???
if (!(sdo = (ec_sdo_t *) kmalloc(sizeof(ec_sdo_t), GFP_KERNEL))) {
EC_ERR("Failed to allocate memory for SDO!\n");
@@ -278,7 +280,7 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
}
while (EC_READ_U8(data + 2) & 0x80);
// Alle Beschreibungen laden
// Fetch all SDO descriptions
if (ec_slave_fetch_sdo_descriptions(slave)) return -1;
return 0;
@@ -287,11 +289,11 @@ int ec_slave_fetch_sdo_list(ec_slave_t *slave /**< EtherCAT-Slave */)
/*****************************************************************************/
/**
Holt die Beschreibungen zu allen bereits bekannten SDOs.
\return 0, wenn alles ok, sonst < 0
Fetches the SDO descriptions for the known SDOs.
\return 0 in case of success, else < 0
*/
int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */)
int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT slave */)
{
uint8_t *data;
size_t rec_size, name_size;
@@ -308,7 +310,7 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */)
if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // Error response
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
EC_ERR("SDO information error response at slave %i while"
" fetching SDO 0x%04X!\n", slave->ring_position,
sdo->index);
@@ -354,7 +356,7 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */)
return -1;
}
// Alle Entries (Subindizes) laden
// Fetch all entries (subindices)
if (ec_slave_fetch_sdo_entries(slave, sdo, EC_READ_U8(data + 10)))
return -1;
}
@@ -365,13 +367,13 @@ int ec_slave_fetch_sdo_descriptions(ec_slave_t *slave /**< EtherCAT-Slave */)
/*****************************************************************************/
/**
Lädt alle Entries (Subindizes) zu einem SDO.
\return 0, wenn alles ok, sonst < 0
Fetches all entries (subindices) to an SDO.
\return 0 in case of success, else < 0
*/
int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT-Slave */
int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT slave */
ec_sdo_t *sdo, /**< SDO */
uint8_t subindices /**< Anzahl Subindizes */
uint8_t subindices /**< number of subindices */
)
{
uint8_t *data;
@@ -394,7 +396,7 @@ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT-Slave */
if (!(data = ec_slave_mbox_simple_io(slave, &rec_size))) return -1;
if (EC_READ_U16(data) >> 12 == 0x8 && // SDO information
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // Error response
(EC_READ_U8 (data + 2) & 0x7F) == 0x07) { // error response
EC_ERR("SDO information error response at slave %i while"
" fetching SDO entry 0x%04X:%i!\n", slave->ring_position,
sdo->index, i);
@@ -403,7 +405,7 @@ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT-Slave */
}
if (EC_READ_U16(data) >> 12 != 0x8 || // SDO information
(EC_READ_U8(data + 2) & 0x7F) != 0x06 || // entry descr. response
(EC_READ_U8(data + 2) & 0x7F) != 0x06 || // Entry desc. response
EC_READ_U16(data + 6) != sdo->index || // SDO index
EC_READ_U8(data + 8) != i) { // SDO subindex
EC_ERR("Invalid entry description response at slave %i while"
@@ -449,7 +451,7 @@ int ec_slave_fetch_sdo_entries(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Gibt eine SDO-Abort-Meldung aus.
Outputs an SDO abort message.
*/
void ec_canopen_abort_msg(uint32_t abort_code)
@@ -506,21 +508,20 @@ const ec_code_msg_t sdo_abort_messages[] = {
{}
};
/*****************************************************************************/
// Echtzeitschnittstelle
/*****************************************************************************/
/******************************************************************************
* Realtime interface
*****************************************************************************/
/**
Liest ein 8-Bit CANopen-SDO im Expedited-Modus aus einem Slave.
Siehe ec_slave_sdo_read_exp()
\return 0 wenn alles ok, < 0 bei Fehler
Reads an 8-bit SDO in expedited mode.
See ec_slave_sdo_read_exp()
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint8_t *target /**< Speicher für gel. Wert */
int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint8_t *target /**< memory for read value */
)
{
uint8_t data[4];
@@ -532,15 +533,15 @@ int ecrt_slave_sdo_read_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Liest ein 16-Bit CANopen-SDO im Expedited-Modus aus einem Slave.
Siehe ec_slave_sdo_read_exp()
\return 0 wenn alles ok, < 0 bei Fehler
Reads a 16-bit SDO in expedited mode.
See ec_slave_sdo_read_exp()
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint16_t *target /**< Speicher für gel. Wert */
int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint16_t *target /**< memory for read value */
)
{
uint8_t data[4];
@@ -552,15 +553,15 @@ int ecrt_slave_sdo_read_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Liest ein 32-Bit CANopen-SDO im Expedited-Modus aus einem Slave.
Siehe ec_slave_sdo_read_exp()
\return 0 wenn alles ok, < 0 bei Fehler
Reads a 32-bit SDO in expedited mode.
See ec_slave_sdo_read_exp()
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint32_t *target /**< Speicher für gel. Wert */
int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint32_t *target /**< memory for read value */
)
{
uint8_t data[4];
@@ -572,14 +573,14 @@ int ecrt_slave_sdo_read_exp32(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Beschreibt ein 8-Bit CANopen-SDO eines Slaves im Expedited-Modus.
\return 0 wenn alles ok, < 0 bei Fehler
Writes an 8-bit SDO in expedited mode.
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint8_t value /**< Neuer Wert */
int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint8_t value /**< new value */
)
{
return ec_slave_sdo_write_exp(slave, sdo_index, sdo_subindex, &value, 1);
@@ -588,14 +589,14 @@ int ecrt_slave_sdo_write_exp8(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Beschreibt ein 16-Bit CANopen-SDO eines Slaves im Expedited-Modus.
\return 0 wenn alles ok, < 0 bei Fehler
Writes a 16-bit SDO in expedited mode.
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint16_t value /**< Neuer Wert */
int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint16_t value /**< new value */
)
{
uint8_t data[2];
@@ -606,14 +607,14 @@ int ecrt_slave_sdo_write_exp16(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Beschreibt ein 32-Bit CANopen-SDO eines Slaves im Expedited-Modus.
\return 0 wenn alles ok, < 0 bei Fehler
Writes a 32-bit SDO in expedited mode.
\return 0 in case of success, else < 0
*/
int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, /**< EtherCAT-Slave */
uint16_t sdo_index, /**< SDO-Index */
uint8_t sdo_subindex, /**< SDO-Subindex */
uint32_t value /**< Neuer Wert */
int ecrt_slave_sdo_write_exp32(ec_slave_t *slave, /**< EtherCAT slave */
uint16_t sdo_index, /**< SDO index */
uint8_t sdo_subindex, /**< SDO subindex */
uint32_t value /**< new value */
)
{
uint8_t data[4];
@@ -632,9 +633,3 @@ EXPORT_SYMBOL(ecrt_slave_sdo_write_exp32);
EXPORT_SYMBOL(ecrt_slave_sdo_read);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* c o m m a n d . c
*
* Methoden für ein EtherCAT-Kommando.
* Methods of an EtherCAT command.
*
* $Id$
*
@@ -31,7 +31,7 @@
/*****************************************************************************/
/**
EtherCAT-Kommando-Konstruktor.
Command constructor.
*/
void ec_command_init(ec_command_t *command)
@@ -49,7 +49,7 @@ void ec_command_init(ec_command_t *command)
/*****************************************************************************/
/**
EtherCAT-Kommando-Destruktor.
Command destructor.
*/
void ec_command_clear(ec_command_t *command)
@@ -60,7 +60,8 @@ void ec_command_clear(ec_command_t *command)
/*****************************************************************************/
/**
Alloziert Speicher.
Allocates command data memory.
\return 0 in case of success, else < 0
*/
int ec_command_prealloc(ec_command_t *command, size_t size)
@@ -85,19 +86,19 @@ int ec_command_prealloc(ec_command_t *command, size_t size)
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-NPRD-Kommando.
Initializes an EtherCAT NPRD command.
Node-adressed physical read.
\return 0 in case of success, else < 0
*/
int ec_command_nprd(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t node_address,
/**< Adresse des Knotens (Slaves) */
/**< configured station address */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu lesenden Daten */
/**< number of bytes to read */
)
{
if (unlikely(node_address == 0x0000))
@@ -113,19 +114,19 @@ int ec_command_nprd(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-NPWR-Kommando.
Initializes an EtherCAT NPWR command.
Node-adressed physical write.
\return 0 in case of success, else < 0
*/
int ec_command_npwr(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t node_address,
/**< Adresse des Knotens (Slaves) */
/**< configured station address */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu schreibenden Daten */
/**< number of bytes to write */
)
{
if (unlikely(node_address == 0x0000))
@@ -141,19 +142,19 @@ int ec_command_npwr(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-APRD-Kommando.
Initializes an EtherCAT APRD command.
Autoincrement physical read.
\return 0 in case of success, else < 0
*/
int ec_command_aprd(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t ring_position,
/**< Position des Slaves im Bus */
/**< auto-increment position */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu lesenden Daten */
/**< number of bytes to read */
)
{
EC_FUNC_HEADER;
@@ -166,19 +167,19 @@ int ec_command_aprd(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-APWR-Kommando.
Initializes an EtherCAT APWR command.
Autoincrement physical write.
\return 0 in case of success, else < 0
*/
int ec_command_apwr(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t ring_position,
/**< Position des Slaves im Bus */
/**< auto-increment position */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu schreibenden Daten */
/**< number of bytes to write */
)
{
EC_FUNC_HEADER;
@@ -191,17 +192,17 @@ int ec_command_apwr(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-BRD-Kommando.
Initializes an EtherCAT BRD command.
Broadcast read.
\return 0 in case of success, else < 0
*/
int ec_command_brd(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu lesenden Daten */
/**< number of bytes to read */
)
{
EC_FUNC_HEADER;
@@ -214,17 +215,17 @@ int ec_command_brd(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-BWR-Kommando.
Initializes an EtherCAT BWR command.
Broadcast write.
\return 0 in case of success, else < 0
*/
int ec_command_bwr(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint16_t offset,
/**< Physikalische Speicheradresse im Slave */
/**< physical memory address */
size_t data_size
/**< Länge der zu schreibenden Daten */
/**< number of bytes to write */
)
{
EC_FUNC_HEADER;
@@ -237,17 +238,17 @@ int ec_command_bwr(ec_command_t *command,
/*****************************************************************************/
/**
Initialisiert ein EtherCAT-LRW-Kommando.
Initializes an EtherCAT LRW command.
Logical read write.
\return 0 in case of success, else < 0
*/
int ec_command_lrw(ec_command_t *command,
/**< EtherCAT-Rahmen */
/**< EtherCAT command */
uint32_t offset,
/**< Logische Startadresse */
/**< logical address */
size_t data_size
/**< Länge der zu lesenden/schreibenden Daten */
/**< number of bytes to read/write */
)
{
EC_FUNC_HEADER;
@@ -257,9 +258,3 @@ int ec_command_lrw(ec_command_t *command,
}
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* c o m m a n d . h
*
* Struktur für ein EtherCAT-Kommando.
* EtherCAT command structure.
*
* $Id$
*
@@ -18,7 +18,7 @@
/*****************************************************************************/
/**
EtherCAT-Kommando-Typ.
EtherCAT command type.
*/
typedef enum
@@ -35,65 +35,57 @@ typedef enum
ec_command_type_t;
/**
EtherCAT-Kommando-Zustand.
EtherCAT command state.
*/
typedef enum
{
EC_CMD_INIT, /**< Neues Kommando */
EC_CMD_QUEUED, /**< Kommando in Warteschlange */
EC_CMD_SENT, /**< Kommando gesendet */
EC_CMD_RECEIVED, /**< Kommando empfangen */
EC_CMD_TIMEOUT, /**< Zeitgrenze überschritten */
EC_CMD_ERROR /**< Fehler beim Senden oder Empfangen */
EC_CMD_INIT, /**< new command */
EC_CMD_QUEUED, /**< command queued by master */
EC_CMD_SENT, /**< command has been sent */
EC_CMD_RECEIVED, /**< command has been received */
EC_CMD_TIMEOUT, /**< command timed out */
EC_CMD_ERROR /**< error while sending/receiving */
}
ec_command_state_t;
/*****************************************************************************/
/**
EtherCAT-Adresse.
Im EtherCAT-Kommando 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.
EtherCAT address.
*/
typedef union
{
struct
{
uint16_t slave; /**< Adresse des Slaves (Ringposition oder Knoten) */
uint16_t mem; /**< Physikalische Speicheradresse im Slave */
uint16_t slave; /**< configured or autoincrement address */
uint16_t mem; /**< physical memory address */
}
physical; /**< Physikalische Adresse */
physical; /**< physical address */
uint32_t logical; /**< Logische Adresse */
uint32_t logical; /**< logical address */
}
ec_address_t;
/*****************************************************************************/
/**
EtherCAT-Kommando.
EtherCAT command
*/
typedef struct
{
struct list_head list; /**< Kommando-Listeneintrag */
struct list_head queue; /**< Master-Kommando-Queue */
ec_command_type_t type; /**< Typ des Kommandos (APRD, NPWR, etc) */
ec_address_t address; /**< Adresse des/der Empfänger */
uint8_t *data; /**< Kommandodaten */
size_t mem_size; /**< Größe des Speichers */
size_t data_size; /**< Länge der zu sendenden und/oder empfangenen Daten */
uint8_t index; /**< Kommando-Index, wird vom Master beim Senden gesetzt. */
uint16_t working_counter; /**< Working-Counter */
ec_command_state_t state; /**< Zustand */
struct list_head list; /**< needed by domain command lists */
struct list_head queue; /**< master command queue item */
ec_command_type_t type; /**< command type (APRD, BWR, etc) */
ec_address_t address; /**< receipient address */
uint8_t *data; /**< command data */
size_t mem_size; /**< command \a data memory size */
size_t data_size; /**< size of the data in \a data */
uint8_t index; /**< command index (set by master) */
uint16_t working_counter; /**< working counter */
ec_command_state_t state; /**< command state */
}
ec_command_t;
@@ -113,9 +105,3 @@ int ec_command_lrw(ec_command_t *, uint32_t, size_t);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* d e v i c e . c
*
* Methoden für ein EtherCAT-Gerät.
* EtherCAT device methods.
*
* $Id$
*
@@ -20,16 +20,15 @@
/*****************************************************************************/
/**
EtherCAT-Geräte-Konstuktor.
\return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher)
Device constructor.
\return 0 in case of success, else < 0
*/
int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
ec_master_t *master, /**< Zugehöriger Master */
struct net_device *net_dev, /**< Net-Device */
ec_isr_t isr, /**< Adresse der ISR */
struct module *module /**< Modul-Adresse */
int ec_device_init(ec_device_t *device, /**< EtherCAT device */
ec_master_t *master, /**< master owning the device */
struct net_device *net_dev, /**< net_device structure */
ec_isr_t isr, /**< pointer to device's ISR */
struct module *module /**< pointer to the owning module */
)
{
struct ethhdr *eth;
@@ -49,7 +48,7 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT-Ger
device->tx_skb->dev = net_dev;
// Ethernet-II-Header hinzufuegen
// add Ethernet-II-header
skb_reserve(device->tx_skb, ETH_HLEN);
eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
eth->h_proto = htons(0x88A4);
@@ -62,13 +61,10 @@ int ec_device_init(ec_device_t *device, /**< EtherCAT-Ger
/*****************************************************************************/
/**
EtherCAT-Geräte-Destuktor.
Gibt den dynamisch allozierten Speicher des
EtherCAT-Gerätes (den Sende-Socket-Buffer) wieder frei.
EtherCAT device destuctor.
*/
void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
void ec_device_clear(ec_device_t *device /**< EtherCAT device */)
{
if (device->open) ec_device_close(device);
if (device->tx_skb) dev_kfree_skb(device->tx_skb);
@@ -77,17 +73,11 @@ void ec_device_clear(ec_device_t *device /**< EtherCAT-Ger
/*****************************************************************************/
/**
Führt die open()-Funktion des Netzwerktreibers aus.
Dies entspricht einem "ifconfig up". Vorher wird der Zeiger
auf das EtherCAT-Gerät auf Gültigkeit geprüft und der
Gerätezustand zurückgesetzt.
\return 0 bei Erfolg, < 0: Ungültiger Zeiger, oder open()
fehlgeschlagen
Opens the EtherCAT device.
\return 0 in case of success, else < 0
*/
int ec_device_open(ec_device_t *device /**< EtherCAT-Gerät */)
int ec_device_open(ec_device_t *device /**< EtherCAT device */)
{
unsigned int i;
@@ -101,7 +91,7 @@ int ec_device_open(ec_device_t *device /**< EtherCAT-Ger
return 0;
}
// Device could have received frames before
// device could have received frames before
for (i = 0; i < 4; i++) ec_device_call_isr(device);
device->link_state = 0;
@@ -114,13 +104,11 @@ int ec_device_open(ec_device_t *device /**< EtherCAT-Ger
/*****************************************************************************/
/**
Führt die stop()-Funktion des net_devices aus.
\return 0 bei Erfolg, < 0: Kein Gerät zum Schließen oder
Schließen fehlgeschlagen.
Stops the EtherCAT device.
\return 0 in case of success, else < 0
*/
int ec_device_close(ec_device_t *device /**< EtherCAT-Gerät */)
int ec_device_close(ec_device_t *device /**< EtherCAT device */)
{
if (!device->dev) {
EC_ERR("No device to close!\n");
@@ -140,12 +128,11 @@ int ec_device_close(ec_device_t *device /**< EtherCAT-Ger
/*****************************************************************************/
/**
Liefert einen Zeiger auf den Sende-Speicher.
\return Zeiger auf den Speicher, in den die Frame-Daten sollen.
Returns a pointer to the device's transmit memory.
\return pointer to the TX socket buffer
*/
uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Gerät */)
uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT device */)
{
return device->tx_skb->data + ETH_HLEN;
}
@@ -153,21 +140,19 @@ uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Ger
/*****************************************************************************/
/**
Sendet den Inhalt des Socket-Buffers.
Schneidet den Inhalt des Socket-Buffers auf die (nun bekannte) Größe zu,
fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der
Netzwerkkarte auf.
Sends the content of the transmit socket buffer.
Cuts the socket buffer content to the (now known) size, and calls the
start_xmit() function of the assigned net_device.
*/
void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
size_t size /**< Größe der zu sendenden Daten */
void ec_device_send(ec_device_t *device, /**< EtherCAT device */
size_t size /**< number of bytes to send */
)
{
if (unlikely(!device->link_state)) // Link down
return;
// Framegröße auf (jetzt bekannte) Länge abschneiden
// set the right length for the data
device->tx_skb->len = ETH_HLEN + size;
if (unlikely(device->master->debug_level > 1)) {
@@ -175,36 +160,33 @@ void ec_device_send(ec_device_t *device, /**< EtherCAT-Ger
ec_print_data(device->tx_skb->data + ETH_HLEN, size);
}
// Senden einleiten
// start sending
device->dev->hard_start_xmit(device->tx_skb, device->dev);
}
/*****************************************************************************/
/**
Ruft die Interrupt-Routine der Netzwerkkarte auf.
Calls the interrupt service routine of the assigned net_device.
*/
void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
void ec_device_call_isr(ec_device_t *device /**< EtherCAT device */)
{
if (likely(device->isr)) device->isr(0, device->dev, NULL);
}
/******************************************************************************
*
* Treiberschnittstelle
*
* Device interface
*****************************************************************************/
/**
Nimmt einen Empfangenen Rahmen entgegen.
Kopiert die empfangenen Daten in den Receive-Buffer.
Accepts a received frame.
Forwards the received data to the master.
*/
void ecdev_receive(ec_device_t *device, /**< EtherCAT-Gerät */
const void *data, /**< Zeiger auf empfangene Daten */
size_t size /**< Größe der empfangenen Daten */
void ecdev_receive(ec_device_t *device, /**< EtherCAT device */
const void *data, /**< pointer to receibed data */
size_t size /**< number of bytes received */
)
{
if (unlikely(device->master->debug_level > 1)) {
@@ -218,11 +200,11 @@ void ecdev_receive(ec_device_t *device, /**< EtherCAT-Ger
/*****************************************************************************/
/**
Setzt einen neuen Verbindungszustand.
Sets a new link state.
*/
void ecdev_link_state(ec_device_t *device, /**< EtherCAT-Gerät */
uint8_t state /**< Verbindungszustand */
void ecdev_link_state(ec_device_t *device, /**< EtherCAT device */
uint8_t state /**< new link state */
)
{
if (unlikely(!device)) {
@@ -242,9 +224,3 @@ EXPORT_SYMBOL(ecdev_receive);
EXPORT_SYMBOL(ecdev_link_state);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* d e v i c e . h
*
* Struktur für ein EtherCAT-Gerät.
* EtherCAT device structure.
*
* $Id$
*
@@ -20,23 +20,21 @@
/*****************************************************************************/
/**
EtherCAT-Gerät.
EtherCAT device.
Ein EtherCAT-Gerät ist eine Netzwerkkarte, die vom
EtherCAT-Master dazu verwendet wird, um Frames zu senden
und zu empfangen.
An EtherCAT device is a network interface card, that is owned by an
EtherCAT master to send and receive EtherCAT frames with.
*/
struct ec_device
{
ec_master_t *master; /**< EtherCAT-Master */
struct net_device *dev; /**< Zeiger auf das reservierte net_device */
uint8_t open; /**< Das net_device ist geoeffnet. */
struct sk_buff *tx_skb; /**< Zeiger auf Transmit-Socketbuffer */
ec_isr_t isr; /**< Adresse der ISR */
struct module *module; /**< Zeiger auf das Modul, das das Gerät zur
Verfügung stellt. */
uint8_t link_state; /**< Verbindungszustand */
ec_master_t *master; /**< EtherCAT master */
struct net_device *dev; /**< pointer to the assigned net_device */
uint8_t open; /**< true, if the net_device has been opened */
struct sk_buff *tx_skb; /**< transmit socket buffer */
ec_isr_t isr; /**< pointer to the device's interrupt service routine */
struct module *module; /**< pointer to the device's owning module */
uint8_t link_state; /**< device link state */
};
/*****************************************************************************/
@@ -55,9 +53,3 @@ void ec_device_send(ec_device_t *, size_t);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* d o m a i n . c
*
* Methoden für Gruppen von EtherCAT-Slaves.
* EtherCAT domain methods.
*
* $Id$
*
@@ -40,12 +40,13 @@ static struct kobj_type ktype_ec_domain = {
/*****************************************************************************/
/**
Konstruktor einer EtherCAT-Domäne.
Domain constructor.
\return 0 in case of success, else < 0
*/
int ec_domain_init(ec_domain_t *domain, /**< Domäne */
ec_master_t *master, /**< Zugehöriger Master */
unsigned int index /**< Domänen-Index */
int ec_domain_init(ec_domain_t *domain, /**< EtherCAT domain */
ec_master_t *master, /**< owning master */
unsigned int index /**< domain index */
)
{
domain->master = master;
@@ -57,7 +58,7 @@ int ec_domain_init(ec_domain_t *domain, /**< Dom
INIT_LIST_HEAD(&domain->field_regs);
INIT_LIST_HEAD(&domain->commands);
// Init kobject and add it to the hierarchy
// init kobject and add it to the hierarchy
memset(&domain->kobj, 0x00, sizeof(struct kobject));
kobject_init(&domain->kobj);
domain->kobj.ktype = &ktype_ec_domain;
@@ -73,10 +74,10 @@ int ec_domain_init(ec_domain_t *domain, /**< Dom
/*****************************************************************************/
/**
Destruktor einer EtherCAT-Domäne.
Domain destructor.
*/
void ec_domain_clear(struct kobject *kobj /**< Kobject der Domäne */)
void ec_domain_clear(struct kobject *kobj /**< kobject of the domain */)
{
ec_command_t *command, *next;
ec_domain_t *domain;
@@ -98,16 +99,16 @@ void ec_domain_clear(struct kobject *kobj /**< Kobject der Dom
/*****************************************************************************/
/**
Registriert ein Feld in einer Domäne.
\return 0 bei Erfolg, < 0 bei Fehler
Registeres a data field in a domain.
\return 0 in case of success, else < 0
*/
int ec_domain_reg_field(ec_domain_t *domain, /**< Domäne */
ec_slave_t *slave, /**< Slave */
const ec_sync_t *sync, /**< Sync-Manager */
uint32_t field_offset, /**< Datenfeld-Offset */
void **data_ptr /**< Adresse des Prozessdatenzeigers */
int ec_domain_reg_field(ec_domain_t *domain, /**< EtherCAT domain */
ec_slave_t *slave, /**< slave */
const ec_sync_t *sync, /**< sync manager */
uint32_t field_offset, /**< data field offset */
void **data_ptr /**< pointer to the process data
pointer */
)
{
ec_field_reg_t *field_reg;
@@ -136,10 +137,10 @@ int ec_domain_reg_field(ec_domain_t *domain, /**< Dom
/*****************************************************************************/
/**
Gibt die Liste der registrierten Datenfelder frei.
Clears the list of the registered data fields.
*/
void ec_domain_clear_field_regs(ec_domain_t *domain)
void ec_domain_clear_field_regs(ec_domain_t *domain /**< EtherCAT domain */)
{
ec_field_reg_t *field_reg, *next;
@@ -152,12 +153,13 @@ void ec_domain_clear_field_regs(ec_domain_t *domain)
/*****************************************************************************/
/**
Alloziert ein Prozessdatenkommando und fügt es in die Liste ein.
Allocates a process data command and appends it to the list.
\return 0 in case of success, else < 0
*/
int ec_domain_add_command(ec_domain_t *domain, /**< Domäne */
uint32_t offset, /**< Logisches Offset */
size_t data_size /**< Größe der Kommando-Daten */
int ec_domain_add_command(ec_domain_t *domain, /**< EtherCAT domain */
uint32_t offset, /**< logical offset */
size_t data_size /**< size of the command data */
)
{
ec_command_t *command;
@@ -181,15 +183,14 @@ int ec_domain_add_command(ec_domain_t *domain, /**< Dom
/*****************************************************************************/
/**
Erzeugt eine Domäne.
Reserviert den Speicher einer Domäne, berechnet die logischen Adressen der
FMMUs und setzt die Prozessdatenzeiger der registrierten Felder.
\return 0 bei Erfolg, < 0 bei Fehler
Creates a domain.
Reserves domain memory, calculates the logical addresses of the
corresponding FMMUs and sets the process data pointer of the registered
data fields.
\return 0 in case of success, else < 0
*/
int ec_domain_alloc(ec_domain_t *domain, /**< Domäne */
int ec_domain_alloc(ec_domain_t *domain, /**< EtherCAT domain */
uint32_t base_address /**< Logische Basisadresse */
)
{
@@ -276,30 +277,33 @@ int ec_domain_alloc(ec_domain_t *domain, /**< Dom
/*****************************************************************************/
/**
Gibt die Anzahl der antwortenden Slaves aus.
Sets the number of responding slaves and outputs it on demand.
This number isn't really the number of responding slaves, but the sum of
the working counters of all domain commands. Some slaves increase the
working counter by 2, some by 1.
*/
void ec_domain_response_count(ec_domain_t *domain, /**< Domäne */
unsigned int count /**< Neue Anzahl */
void ec_domain_response_count(ec_domain_t *domain, /**< EtherCAT domain */
unsigned int count /**< new WC sum */
)
{
if (count != domain->response_count) {
domain->response_count = count;
EC_INFO("Domain %i working counter change: %i\n", domain->index, count);
EC_INFO("Domain %i working counter change: %i\n", domain->index,
count);
}
}
/*****************************************************************************/
/**
Formatiert Attribut-Daten für lesenden Zugriff im SysFS
\return Anzahl Bytes im Speicher
Formats attribute data for SysFS reading.
\return number of bytes to read
*/
ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< KObject */
struct attribute *attr, /**< Attribut */
char *buffer /**< Speicher für die Daten */
ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< kobject */
struct attribute *attr, /**< attribute */
char *buffer /**< memory to store data in */
)
{
ec_domain_t *domain = container_of(kobj, ec_domain_t, kobj);
@@ -312,43 +316,39 @@ ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< KObject */
}
/******************************************************************************
*
* Echtzeitschnittstelle
*
* Realtime interface
*****************************************************************************/
/**
Registriert ein Datenfeld innerhalb einer Domäne.
- Ist \a data_ptr NULL, so wird der Slave nur auf den Typ überprüft.
- Wenn \a field_count 0 ist, wird angenommen, dass 1 Feld registriert werden
soll.
- Wenn \a field_count größer als 1 ist, wird angenommen, dass \a data_ptr
auf ein entsprechend großes Array zeigt.
\return Zeiger auf den Slave bei Erfolg, sonst NULL
Registers a data field in a domain.
- If \a data_ptr is NULL, the slave is only checked against its type.
- If \a field_count is 0, it is assumed that one data field is to be
registered.
- If \a field_count is greater then 1, it is assumed that \a data_ptr
is an array of the respective size.
\return pointer to the slave on success, else NULL
*/
ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
/**< Domäne */
/**< EtherCAT domain */
const char *address,
/**< ASCII-Addresse des Slaves,
siehe ecrt_master_get_slave() */
/**< ASCII address of the slave,
see ecrt_master_get_slave() */
const char *vendor_name,
/**< Herstellername */
/**< vendor name */
const char *product_name,
/**< Produktname */
/**< product name */
void **data_ptr,
/**< Adresse des Zeigers auf die
Prozessdaten */
/**< address of the process data
pointer */
const char *field_name,
/**< Name des Datenfeldes */
/**< data field name */
unsigned int field_index,
/**< Gibt an, ab welchem Feld mit
Typ \a field_type gezählt
werden soll. */
/**< offset of data fields with
\a field_type */
unsigned int field_count
/**< Anzahl Felder selben Typs */
/**< number of data fields (with
the same type) to register */
)
{
ec_slave_t *slave;
@@ -361,7 +361,7 @@ ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
master = domain->master;
// Adresse übersetzen
// translate address
if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
if (!(type = slave->type)) {
@@ -379,7 +379,7 @@ ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
}
if (!data_ptr) {
// Wenn data_ptr NULL, Slave als registriert ansehen (nicht warnen).
// data_ptr is NULL => mark slave as "registered" (do not warn)
slave->registered = 1;
}
@@ -415,17 +415,15 @@ ec_slave_t *ecrt_domain_register_field(ec_domain_t *domain,
/*****************************************************************************/
/**
Registriert eine ganze Liste von Datenfeldern innerhalb einer Domäne.
Achtung: Die Liste muss mit einer NULL-Struktur ({}) abgeschlossen sein!
\return 0 bei Erfolg, sonst < 0
Registeres a bunch of data fields.
Caution! The list has to be terminated with a NULL structure ({})!
\return 0 in case of success, else < 0
*/
int ecrt_domain_register_field_list(ec_domain_t *domain,
/**< Domäne */
/**< EtherCAT domain */
const ec_field_init_t *fields
/**< Array mit Datenfeldern */
/**< array of data field registrations */
)
{
const ec_field_init_t *field;
@@ -444,10 +442,10 @@ int ecrt_domain_register_field_list(ec_domain_t *domain,
/*****************************************************************************/
/**
Setzt Prozessdaten-Kommandos in die Warteschlange des Masters.
Places all process data commands in the masters command queue.
*/
void ecrt_domain_queue(ec_domain_t *domain /**< Domäne */)
void ecrt_domain_queue(ec_domain_t *domain /**< EtherCAT domain */)
{
ec_command_t *command;
@@ -459,10 +457,10 @@ void ecrt_domain_queue(ec_domain_t *domain /**< Dom
/*****************************************************************************/
/**
Verarbeitet empfangene Prozessdaten.
Processes received process data.
*/
void ecrt_domain_process(ec_domain_t *domain /**< Domäne */)
void ecrt_domain_process(ec_domain_t *domain /**< EtherCAT domain */)
{
unsigned int working_counter_sum;
ec_command_t *command;
@@ -481,12 +479,11 @@ void ecrt_domain_process(ec_domain_t *domain /**< Dom
/*****************************************************************************/
/**
Gibt den Status einer Domäne zurück.
\return 0 wenn alle Kommandos empfangen wurden, sonst -1.
Returns the state of a domain.
\return 0 if all commands were received, else -1.
*/
int ecrt_domain_state(ec_domain_t *domain /**< Domäne */)
int ecrt_domain_state(ec_domain_t *domain /**< EtherCAT domain */)
{
ec_command_t *command;
@@ -506,9 +503,3 @@ EXPORT_SYMBOL(ecrt_domain_process);
EXPORT_SYMBOL(ecrt_domain_state);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* d o m a i n . h
*
* Struktur für eine Gruppe von EtherCAT-Slaves.
* EtherCAT domain structure.
*
* $Id$
*
@@ -21,39 +21,38 @@
/*****************************************************************************/
/**
Datenfeld-Konfiguration.
Data field registration type.
*/
typedef struct
{
struct list_head list;
ec_slave_t *slave;
const ec_sync_t *sync;
uint32_t field_offset;
void **data_ptr;
struct list_head list; /**< list item */
ec_slave_t *slave; /**< slave */
const ec_sync_t *sync; /**< sync manager */
uint32_t field_offset; /**< data field offset */
void **data_ptr; /**< pointer to process data pointer(s) */
}
ec_field_reg_t;
/*****************************************************************************/
/**
EtherCAT-Domäne
Verwaltet die Prozessdaten und das hierfür nötige Kommando einer bestimmten
Menge von Slaves.
EtherCAT domain.
Handles the process data and the therefore needed commands of a certain
group of slaves.
*/
struct ec_domain
{
struct kobject kobj; /**< Kobject der Domäne */
struct list_head list; /**< Listenkopf */
unsigned int index; /**< Domänen-Index */
ec_master_t *master; /**< EtherCAT-Master, zu der die Domäne gehört. */
size_t data_size; /**< Größe der Prozessdaten */
struct list_head commands; /**< EtherCAT-Kommandos für die Prozessdaten */
uint32_t base_address; /**< Logische Basisaddresse der Domain */
unsigned int response_count; /**< Anzahl antwortender Slaves */
struct list_head field_regs; /**< Liste der Datenfeldregistrierungen */
struct kobject kobj; /**< kobject */
struct list_head list; /**< list item */
unsigned int index; /**< domain index (just a number) */
ec_master_t *master; /**< EtherCAT master owning the domain */
size_t data_size; /**< size of the process data */
struct list_head commands; /**< process data commands */
uint32_t base_address; /**< logical offset address of the process data */
unsigned int response_count; /**< number of responding slaves */
struct list_head field_regs; /**< data field registrations */
};
/*****************************************************************************/
@@ -65,9 +64,3 @@ int ec_domain_alloc(ec_domain_t *, uint32_t);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -117,9 +117,3 @@ void ec_eoe_print(const ec_eoe_t *eoe)
}
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -43,9 +43,3 @@ void ec_eoe_run(ec_eoe_t *);
void ec_eoe_print(const ec_eoe_t *);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* g l o b a l s . h
*
* Globale Definitionen und Makros für das EtherCAT-Protokoll.
* Global definitions and macros.
*
* $Id$
*
@@ -16,21 +16,20 @@
/*****************************************************************************/
// EtherCAT-Protokoll
#define EC_MAX_FRAME_SIZE 1500 /**< Maximale Größe eines EtherCAT-Frames ohne
Ethernet-II-Header und -Prüfsumme */
#define EC_MIN_FRAME_SIZE 46 /** Minimale Größe, s. o. */
#define EC_FRAME_HEADER_SIZE 2 /**< Größe des EtherCAT-Frame-Headers */
#define EC_COMMAND_HEADER_SIZE 10 /**< Größe eines EtherCAT-Kommando-Headers */
#define EC_COMMAND_FOOTER_SIZE 2 /**< Größe eines EtherCAT-Kommando-Footers */
#define EC_SYNC_SIZE 8 /**< Größe einer Sync-Manager-Konfigurationsseite */
#define EC_FMMU_SIZE 16 /**< Größe einer FMMU-Konfigurationsseite */
#define EC_MAX_FMMUS 16 /**< Maximale Anzahl FMMUs pro Slave */
#define EC_MAX_FRAME_SIZE 1500 /**< maximum size of an EtherCAT frame (without
header and CRC) */
#define EC_MIN_FRAME_SIZE 46 /** ... minimum size */
#define EC_FRAME_HEADER_SIZE 2 /**< size of an EtherCAT frame header */
#define EC_COMMAND_HEADER_SIZE 10 /**< size of an EtherCAT command header */
#define EC_COMMAND_FOOTER_SIZE 2 /**< size of an EtherCAT command footer */
#define EC_SYNC_SIZE 8 /**< size of a sync manager configuration page */
#define EC_FMMU_SIZE 16 /**< size of an FMMU configuration page */
#define EC_MAX_FMMUS 16 /**< maximum number of FMMUs per slave */
#define EC_MAX_DATA_SIZE (EC_MAX_FRAME_SIZE \
- EC_FRAME_HEADER_SIZE \
- EC_COMMAND_HEADER_SIZE \
- EC_COMMAND_FOOTER_SIZE) /**< Maximale Datengröße
bei einem Kommando pro
Frame */
- EC_COMMAND_FOOTER_SIZE) /**< maximum data size of a
single command */
/*****************************************************************************/
@@ -59,16 +58,15 @@ extern void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
/*****************************************************************************/
/**
Code - Message Pair.
Code - Message pair.
Some EtherCAT commands support reading a status code to display a certain
message. This type allows to map a code to a message string.
*/
typedef struct
{
uint32_t code; /**< Code */
const char *message; /**< Message belonging to \a code */
uint32_t code; /**< code */
const char *message; /**< message belonging to \a code */
}
ec_code_msg_t;
@@ -76,8 +74,3 @@ ec_code_msg_t;
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* m a i l b o x . c
*
* Mailbox-Funktionen
* Mailbox functionality.
*
* $Id$
*
@@ -18,12 +18,13 @@
/*****************************************************************************/
/**
Bereitet ein Mailbox-Send-Kommando vor.
*/
Prepares a mailbox-send command.
\return pointer to mailbox command data
*/
uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< Slave */
uint8_t type, /**< Mailbox-Protokoll */
size_t size /**< Datengröße */
uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< slave */
uint8_t type, /**< mailbox protocol */
size_t size /**< size of the data */
)
{
ec_command_t *command = &slave->mbox_command;
@@ -46,10 +47,10 @@ uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< Slave */
slave->sii_rx_mailbox_size))
return NULL;
EC_WRITE_U16(command->data, size); // Mailbox service data length
EC_WRITE_U16(command->data + 2, slave->station_address); // Station address
EC_WRITE_U8 (command->data + 4, 0x00); // Channel & priority
EC_WRITE_U8 (command->data + 5, type); // Underlying protocol type
EC_WRITE_U16(command->data, size); // mailbox service data length
EC_WRITE_U16(command->data + 2, slave->station_address); // station address
EC_WRITE_U8 (command->data + 4, 0x00); // hhannel & priority
EC_WRITE_U8 (command->data + 5, type); // underlying protocol type
return command->data + 6;
}
@@ -57,14 +58,15 @@ uint8_t *ec_slave_mbox_prepare_send(ec_slave_t *slave, /**< Slave */
/*****************************************************************************/
/**
Bereitet ein Kommando zum Abfragen des Mailbox-Zustandes vor.
*/
Prepares a command for checking the mailbox state.
\return 0 in case of success, else < 0
*/
int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< Slave */)
int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< slave */)
{
ec_command_t *command = &slave->mbox_command;
// FIXME: Zweiter Sync-Manager nicht immer TX-Mailbox?
// FIXME: second sync manager?
if (ec_command_nprd(command, slave->station_address, 0x808, 8))
return -1;
@@ -74,10 +76,11 @@ int ec_slave_mbox_prepare_check(ec_slave_t *slave /**< Slave */)
/*****************************************************************************/
/**
Liest den Mailbox-Zustand aus einem empfangenen Kommando.
*/
Processes a mailbox state checking command.
\return 0 in case of success, else < 0
*/
int ec_slave_mbox_check(const ec_slave_t *slave /**< Slave */)
int ec_slave_mbox_check(const ec_slave_t *slave /**< slave */)
{
return EC_READ_U8(slave->mbox_command.data + 5) & 8 ? 1 : 0;
}
@@ -85,10 +88,11 @@ int ec_slave_mbox_check(const ec_slave_t *slave /**< Slave */)
/*****************************************************************************/
/**
Bereitet ein Kommando zum Laden von Daten von der Mailbox vor.
*/
Prepares a command to fetch mailbox data.
\return 0 in case of success, else < 0
*/
int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< Slave */)
int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< slave */)
{
ec_command_t *command = &slave->mbox_command;
@@ -101,12 +105,13 @@ int ec_slave_mbox_prepare_fetch(ec_slave_t *slave /**< Slave */)
/*****************************************************************************/
/**
Verarbeitet empfangene Mailbox-Daten.
*/
Processes received mailbox data.
\return pointer to the received data
*/
uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< Slave */
uint8_t type, /**< Protokoll */
size_t *size /**< Größe der empfangenen Daten */
uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< slave */
uint8_t type, /**< expected mailbox protocol */
size_t *size /**< size of the received data */
)
{
ec_command_t *command = &slave->mbox_command;
@@ -132,12 +137,12 @@ uint8_t *ec_slave_mbox_fetch(ec_slave_t *slave, /**< Slave */
/*****************************************************************************/
/**
Sendet und wartet auf den Empfang eines Mailbox-Kommandos.
*/
Sends a mailbox command and waits for its reception.
\return pointer to the received data
*/
uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< Slave */
size_t *size /**< Größe der gelesenen
Daten */
uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< slave */
size_t *size /**< size of the received data */
)
{
uint8_t type;
@@ -158,13 +163,13 @@ uint8_t *ec_slave_mbox_simple_io(ec_slave_t *slave, /**< Slave */
/*****************************************************************************/
/**
Wartet auf den Empfang eines Mailbox-Kommandos.
*/
Waits for the reception of a mailbox command.
\return pointer to the received data
*/
uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< Slave */
uint8_t type, /**< Protokoll */
size_t *size /**< Größe der gelesenen
Daten */
uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< slave */
uint8_t type, /**< expected protocol */
size_t *size /**< received data size */
)
{
cycles_t start, end, timeout;
@@ -186,7 +191,7 @@ uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *slave, /**< Slave */
end = get_cycles();
if (ec_slave_mbox_check(slave))
break; // Proceed with receiving data
break; // proceed with receiving data
if ((end - start) >= timeout) {
EC_ERR("Mailbox check - Slave %i timed out.\n",

View File

@@ -2,7 +2,7 @@
*
* m a i l b o x . h
*
* Mailbox-Funktionen.
* Mailbox functionality.
*
* $Id$
*
@@ -27,9 +27,3 @@ uint8_t *ec_slave_mbox_simple_receive(ec_slave_t *, uint8_t, size_t *);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
*
* m a s t e r . h
*
* Struktur für einen EtherCAT-Master.
* EtherCAT master structure.
*
* $Id$
*
@@ -35,61 +35,59 @@ ec_master_mode_t;
/*****************************************************************************/
/**
EtherCAT-Rahmen-Statistiken.
Cyclic EtherCAT statistics.
*/
typedef struct
{
unsigned int timeouts; /**< Kommando-Timeouts */
unsigned int delayed; /**< Verzögerte Kommandos */
unsigned int corrupted; /**< Verfälschte Rahmen */
unsigned int unmatched; /**< Unpassende Kommandos */
unsigned int eoe_errors; /**< Ethernet-over-EtherCAT Fehler */
cycles_t t_last; /**< Timestamp-Counter bei der letzten Ausgabe */
unsigned int timeouts; /**< command timeouts */
unsigned int delayed; /**< delayed commands */
unsigned int corrupted; /**< corrupted frames */
unsigned int unmatched; /**< unmatched commands */
unsigned int eoe_errors; /**< Ethernet-over-EtherCAT errors */
cycles_t t_last; /**< time of last output */
}
ec_stats_t;
/*****************************************************************************/
/**
EtherCAT-Master
Verwaltet die EtherCAT-Slaves und kommuniziert mit
dem zugewiesenen EtherCAT-Gerät.
EtherCAT-Master.
Manages slaves, domains and IO.
*/
struct ec_master
{
struct list_head list; /**< Noetig fuer Master-Liste */
struct kobject kobj; /**< Kernel-Object */
unsigned int index; /**< Master-Index */
struct list_head slaves; /**< Liste der Slaves auf dem Bus */
unsigned int slave_count; /**< Anzahl Slaves auf dem Bus */
ec_device_t *device; /**< EtherCAT-Gerät */
struct list_head command_queue; /**< Kommando-Warteschlange */
uint8_t command_index; /**< Aktueller Kommando-Index */
struct list_head domains; /**< Liste der Prozessdatendomänen */
ec_command_t simple_command; /**< Kommando für Initialisierungsphase */
ec_command_t watch_command; /**< Kommando zum Überwachen der Slaves */
unsigned int slaves_responding; /**< Anzahl antwortender Slaves */
ec_slave_state_t slave_states; /**< Zustände der antwortenden Slaves */
int debug_level; /**< Debug-Level im Master-Code */
ec_stats_t stats; /**< Rahmen-Statistiken */
unsigned int timeout; /**< Timeout für synchronen Datenaustausch */
struct list_head eoe_slaves; /**< Ethernet over EtherCAT Slaves */
unsigned int reserved; /**< Master durch Echtzeitprozess reserviert */
struct timer_list freerun_timer; /**< Timer fuer Free-Run-Modus. */
ec_master_mode_t mode; /**< Modus des Masters */
struct list_head list; /**< list item */
struct kobject kobj; /**< kobject */
unsigned int index; /**< master index */
struct list_head slaves; /**< list of slaves on the bus */
unsigned int slave_count; /**< number of slaves on the bus */
ec_device_t *device; /**< EtherCAT device */
struct list_head command_queue; /**< command queue */
uint8_t command_index; /**< current command index */
struct list_head domains; /**< list of domains */
ec_command_t simple_command; /**< command structure for initialization */
ec_command_t watch_command; /**< command for watching the slaves */
unsigned int slaves_responding; /**< number of responding slaves */
ec_slave_state_t slave_states; /**< states of the responding slaves */
int debug_level; /**< master debug level */
ec_stats_t stats; /**< cyclic statistics */
unsigned int timeout; /**< timeout in synchronous IO */
struct list_head eoe_slaves; /**< Ethernet-over-EtherCAT slaves */
unsigned int reserved; /**< true, if the master is reserved for RT */
struct timer_list freerun_timer; /**< timer object for free run mode */
ec_master_mode_t mode; /**< master mode */
};
/*****************************************************************************/
// Master creation and deletion
// master creation and deletion
int ec_master_init(ec_master_t *, unsigned int);
void ec_master_clear(struct kobject *);
void ec_master_reset(ec_master_t *);
// Free-Run
// free run
void ec_master_freerun_start(ec_master_t *);
void ec_master_freerun_stop(ec_master_t *);
@@ -98,10 +96,10 @@ void ec_master_receive(ec_master_t *, const uint8_t *, size_t);
void ec_master_queue_command(ec_master_t *, ec_command_t *);
int ec_master_simple_io(ec_master_t *, ec_command_t *);
// Slave management
// slave management
int ec_master_bus_scan(ec_master_t *);
// Misc
// misc.
void ec_master_debug(const ec_master_t *);
void ec_master_output_stats(ec_master_t *);
void ec_master_run_eoe(ec_master_t *);
@@ -109,9 +107,3 @@ void ec_master_run_eoe(ec_master_t *);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,9 +2,9 @@
*
* m o d u l e . c
*
* EtherCAT-Master-Treiber
* EtherCAT master driver module.
*
* Autoren: Wilhelm Hagemeister, Florian Pose
* Author: Florian Pose <fp@igh-essen.com>
*
* $Id$
*
@@ -50,18 +50,14 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(COMPILE_INFO);
module_param(ec_master_count, int, 1);
MODULE_PARM_DESC(ec_master_count, "Number of EtherCAT master to initialize.");
MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
/*****************************************************************************/
/**
Init-Funktion des EtherCAT-Master-Treibermodules
Initialisiert soviele Master, wie im Parameter ec_master_count
angegeben wurde (Default ist 1).
\return 0 wenn alles ok, < 0 bei ungültiger Anzahl Master
oder zu wenig Speicher.
Module initialization.
Initializes \a ec_master_count masters.
\return 0 on success, else < 0
*/
int __init ec_init_module(void)
@@ -115,9 +111,8 @@ int __init ec_init_module(void)
/*****************************************************************************/
/**
Cleanup-Funktion des EtherCAT-Master-Treibermoduls
Entfernt alle Master-Instanzen.
Module cleanup.
Clears all master instances.
*/
void __exit ec_cleanup_module(void)
@@ -142,7 +137,7 @@ void __exit ec_cleanup_module(void)
\returns pointer to master
*/
ec_master_t *ec_find_master(unsigned int master_index)
ec_master_t *ec_find_master(unsigned int master_index /**< master index */)
{
ec_master_t *master;
@@ -155,26 +150,19 @@ ec_master_t *ec_find_master(unsigned int master_index)
}
/******************************************************************************
*
* Treiberschnittstelle
*
* Device interface
*****************************************************************************/
/**
Registeriert das EtherCAT-Geraet fuer einen EtherCAT-Master.
\return 0 wenn alles ok, oder < 0 wenn bereits ein Gerät registriert
oder das Geraet nicht geöffnet werden konnte.
Registeres an EtherCAT device for a certain master.
\return 0 on success, else < 0
*/
ec_device_t *ecdev_register(unsigned int master_index,
/**< Index des EtherCAT-Masters */
struct net_device *net_dev,
/**< net_device des EtherCAT-Gerätes */
ec_isr_t isr,
/**< Interrupt-Service-Routine */
struct module *module
/**< Zeiger auf das Modul */
ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
struct net_device *net_dev, /**< net_device of
the device */
ec_isr_t isr, /**< interrupt service routine */
struct module *module /**< pointer to the module */
)
{
ec_master_t *master;
@@ -218,13 +206,11 @@ ec_device_t *ecdev_register(unsigned int master_index,
/*****************************************************************************/
/**
Hebt die Registrierung eines EtherCAT-Gerätes auf.
Unregisteres an EtherCAT device.
*/
void ecdev_unregister(unsigned int master_index,
/**< Index des EtherCAT-Masters */
ec_device_t *device
/**< EtherCAT-Geraet */
void ecdev_unregister(unsigned int master_index, /**< master index */
ec_device_t *device /**< EtherCAT device */
)
{
ec_master_t *master;
@@ -244,12 +230,10 @@ void ecdev_unregister(unsigned int master_index,
/*****************************************************************************/
/**
Starts the master.
Starts the master associated with the device.
*/
int ecdev_start(unsigned int master_index
/**< Index des EtherCAT-Masters */
)
int ecdev_start(unsigned int master_index /**< master index */)
{
ec_master_t *master;
if (!(master = ec_find_master(master_index))) return -1;
@@ -266,12 +250,10 @@ int ecdev_start(unsigned int master_index
/*****************************************************************************/
/**
Stops the master.
Stops the master associated with the device.
*/
void ecdev_stop(unsigned int master_index
/**< Index des EtherCAT-Masters */
)
void ecdev_stop(unsigned int master_index /**< master index */)
{
ec_master_t *master;
if (!(master = ec_find_master(master_index))) return;
@@ -283,21 +265,16 @@ void ecdev_stop(unsigned int master_index
}
/******************************************************************************
*
* Echtzeitschnittstelle
*
* Realtime interface
*****************************************************************************/
/**
Reserviert einen bestimmten EtherCAT-Master und das zugehörige Gerät.
Gibt einen Zeiger auf den reservierten EtherCAT-Master zurueck.
\return Zeiger auf EtherCAT-Master oder NULL, wenn Parameter ungueltig.
Reserves an EtherCAT master for realtime operation.
\return pointer to reserved master, or NULL on error
*/
ec_master_t *ecrt_request_master(unsigned int master_index
/**< EtherCAT-Master-Index */
/**< master index */
)
{
ec_master_t *master;
@@ -351,10 +328,10 @@ ec_master_t *ecrt_request_master(unsigned int master_index
/*****************************************************************************/
/**
Gibt einen zuvor angeforderten EtherCAT-Master wieder frei.
Releases a reserved EtherCAT master.
*/
void ecrt_release_master(ec_master_t *master /**< EtherCAT-Master */)
void ecrt_release_master(ec_master_t *master /**< EtherCAT master */)
{
EC_INFO("Releasing master %i...\n", master->index);
@@ -378,10 +355,12 @@ void ecrt_release_master(ec_master_t *master /**< EtherCAT-Master */)
/*****************************************************************************/
/**
Gibt Frame-Inhalte zwecks Debugging aus.
Outputs frame contents for debugging purposes.
*/
void ec_print_data(const uint8_t *data, size_t size)
void ec_print_data(const uint8_t *data, /**< pointer to data */
size_t size /**< number of bytes to output */
)
{
unsigned int i;
@@ -399,12 +378,12 @@ void ec_print_data(const uint8_t *data, size_t size)
/*****************************************************************************/
/**
Gibt Frame-Inhalte zwecks Debugging aus, differentiell.
Outputs frame contents and differences for debugging purposes.
*/
void ec_print_data_diff(const uint8_t *d1, /**< Daten 1 */
const uint8_t *d2, /**< Daten 2 */
size_t size /** Anzahl Bytes */
void ec_print_data_diff(const uint8_t *d1, /**< first data */
const uint8_t *d2, /**< second data */
size_t size /** number of bytes to output */
)
{
unsigned int i;
@@ -434,9 +413,3 @@ EXPORT_SYMBOL(ecrt_request_master);
EXPORT_SYMBOL(ecrt_release_master);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
*
* s l a v e . h
*
* Struktur für einen EtherCAT-Slave.
* EtherCAT stave structure.
*
* $Id$
*
@@ -21,30 +21,30 @@
/*****************************************************************************/
/**
Zustand eines EtherCAT-Slaves.
State of an EtherCAT slave.
*/
typedef enum
{
EC_SLAVE_STATE_UNKNOWN = 0x00,
/**< Status unbekannt */
/**< unknown state */
EC_SLAVE_STATE_INIT = 0x01,
/**< Init-Zustand (Keine Mailbox-Kommunikation, Kein I/O) */
/**< INIT state (no mailbox communication, no IO) */
EC_SLAVE_STATE_PREOP = 0x02,
/**< Pre-Operational (Mailbox-Kommunikation, Kein I/O) */
/**< PREOP state (mailbox communication, no IO) */
EC_SLAVE_STATE_SAVEOP = 0x04,
/**< Save-Operational (Mailbox-Kommunikation und Input Update) */
/**< SAVEOP (mailbox communication and input update) */
EC_SLAVE_STATE_OP = 0x08,
/**< Operational, (Mailbox-Kommunikation und Input/Output Update) */
/**< OP (mailbox communication and input/output update) */
EC_ACK = 0x10
/**< Acknoledge-Bit beim Zustandswechsel (kein eigener Zustand) */
/**< Acknoledge bit (no state) */
}
ec_slave_state_t;
/*****************************************************************************/
/**
Unterstützte Mailbox-Protokolle.
Supported mailbox protocols.
*/
enum
@@ -60,124 +60,124 @@ enum
/*****************************************************************************/
/**
FMMU-Konfiguration.
FMMU configuration.
*/
typedef struct
{
const ec_domain_t *domain;
const ec_sync_t *sync;
uint32_t logical_start_address;
const ec_domain_t *domain; /**< domain */
const ec_sync_t *sync; /**< sync manager */
uint32_t logical_start_address; /**< logical start address */
}
ec_fmmu_t;
/*****************************************************************************/
/**
String im EEPROM eines EtherCAT-Slaves.
String object (EEPROM).
*/
typedef struct
{
struct list_head list;
size_t size;
char *data;
struct list_head list; /**< list item */
size_t size; /**< size in bytes */
char *data; /**< string data */
}
ec_eeprom_string_t;
/*****************************************************************************/
/**
Sync-Manager-Konfiguration laut EEPROM.
Sync manager configuration (EEPROM).
*/
typedef struct
{
struct list_head list;
unsigned int index;
uint16_t physical_start_address;
uint16_t length;
uint8_t control_register;
uint8_t enable;
struct list_head list; /**< list item */
unsigned int index; /**< sync manager index */
uint16_t physical_start_address; /**< physical start address */
uint16_t length; /**< data length in bytes */
uint8_t control_register; /**< control register value */
uint8_t enable; /**< enable bit */
}
ec_eeprom_sync_t;
/*****************************************************************************/
/**
PDO-Typ.
PDO type.
*/
typedef enum
{
EC_RX_PDO,
EC_TX_PDO
EC_RX_PDO, /**< Reveive PDO */
EC_TX_PDO /**< Transmit PDO */
}
ec_pdo_type_t;
/*****************************************************************************/
/**
PDO-Beschreibung im EEPROM.
PDO description (EEPROM).
*/
typedef struct
{
struct list_head list;
ec_pdo_type_t type;
uint16_t index;
uint8_t sync_manager;
char *name;
struct list_head entries;
struct list_head list; /**< list item */
ec_pdo_type_t type; /**< PDO type */
uint16_t index; /**< PDO index */
uint8_t sync_manager; /**< assigned sync manager */
char *name; /**< PDO name */
struct list_head entries; /**< entry list */
}
ec_eeprom_pdo_t;
/*****************************************************************************/
/**
PDO-Entry-Beschreibung im EEPROM.
PDO entry description (EEPROM).
*/
typedef struct
{
struct list_head list;
uint16_t index;
uint8_t subindex;
char *name;
uint8_t bit_length;
struct list_head list; /**< list item */
uint16_t index; /**< PDO index */
uint8_t subindex; /**< entry subindex */
char *name; /**< entry name */
uint8_t bit_length; /**< entry length in bit */
}
ec_eeprom_pdo_entry_t;
/*****************************************************************************/
/**
CANopen-SDO.
CANopen SDO.
*/
typedef struct
{
struct list_head list;
uint16_t index;
struct list_head list; /**< list item */
uint16_t index; /**< SDO index */
//uint16_t type;
uint8_t object_code;
char *name;
struct list_head entries;
uint8_t object_code; /**< object code */
char *name; /**< SDO name */
struct list_head entries; /**< entry list */
}
ec_sdo_t;
/*****************************************************************************/
/**
CANopen-SDO-Entry.
CANopen SDO entry.
*/
typedef struct
{
struct list_head list;
uint8_t subindex;
uint16_t data_type;
uint16_t bit_length;
char *name;
struct list_head list; /**< list item */
uint8_t subindex; /**< entry subindex */
uint16_t data_type; /**< entry data type */
uint16_t bit_length; /**< entry length in bit */
char *name; /**< entry name */
}
ec_sdo_entry_t;
@@ -189,69 +189,68 @@ ec_sdo_entry_t;
struct ec_slave
{
struct list_head list; /**< Noetig fuer Slave-Liste im Master */
struct kobject kobj; /**< Kernel-Object */
ec_master_t *master; /**< EtherCAT-Master, zu dem der Slave gehört. */
struct list_head list; /**< list item */
struct kobject kobj; /**< kobject */
ec_master_t *master; /**< master owning the slave */
// Addresses
uint16_t ring_position; /**< Position des Slaves im Bus */
uint16_t station_address; /**< Konfigurierte Slave-Adresse */
uint16_t coupler_index; /**< Letzter Buskoppler */
uint16_t coupler_subindex; /**< Index hinter letztem Buskoppler */
// addresses
uint16_t ring_position; /**< ring position */
uint16_t station_address; /**< configured station address */
uint16_t coupler_index; /**< index of the last bus coupler */
uint16_t coupler_subindex; /**< index of this slave after last coupler */
// Base data
uint8_t base_type; /**< Slave-Typ */
uint8_t base_revision; /**< Revision */
uint16_t base_build; /**< Build-Nummer */
uint16_t base_fmmu_count; /**< Anzahl unterstützter FMMUs */
uint16_t base_sync_count; /**< Anzahl unterstützter Sync-Manager */
// base data
uint8_t base_type; /**< slave type */
uint8_t base_revision; /**< revision */
uint16_t base_build; /**< build number */
uint16_t base_fmmu_count; /**< number of supported FMMUs */
uint16_t base_sync_count; /**< number of supported sync managers */
// Data link status
uint8_t dl_link[4]; /**< Verbindung erkannt */
uint8_t dl_loop[4]; /**< Loop geschlossen */
uint8_t dl_signal[4]; /**< Signal an RX-Seite erkannt */
// data link status
uint8_t dl_link[4]; /**< link detected */
uint8_t dl_loop[4]; /**< loop closed */
uint8_t dl_signal[4]; /**< detected signal on RX port */
// Slave information interface
uint16_t sii_alias; /**< Configured station alias */
uint32_t sii_vendor_id; /**< Identifikationsnummer des Herstellers */
uint32_t sii_product_code; /**< Herstellerspezifischer Produktcode */
uint32_t sii_revision_number; /**< Revisionsnummer */
uint32_t sii_serial_number; /**< Seriennummer der Klemme */
uint16_t sii_rx_mailbox_offset; /**< Adresse der Mailbox (Master->Slave) */
uint16_t sii_rx_mailbox_size; /**< Adresse der Mailbox (Master->Slave) */
uint16_t sii_tx_mailbox_offset; /**< Adresse der Mailbox (Slave->Master) */
uint16_t sii_tx_mailbox_size; /**< Adresse der Mailbox (Slave->Master) */
uint16_t sii_mailbox_protocols; /**< Unterstützte Mailbox-Protokolle */
uint8_t sii_physical_layer[4]; /**< Uebertragungsarten der Ports */
// slave information interface
uint16_t sii_alias; /**< configured station alias */
uint32_t sii_vendor_id; /**< vendor id */
uint32_t sii_product_code; /**< vendor's product code */
uint32_t sii_revision_number; /**< revision number */
uint32_t sii_serial_number; /**< serial number */
uint16_t sii_rx_mailbox_offset; /**< mailbox address (master to slave) */
uint16_t sii_rx_mailbox_size; /**< mailbox size (master to slave) */
uint16_t sii_tx_mailbox_offset; /**< mailbox address (slave to master) */
uint16_t sii_tx_mailbox_size; /**< mailbox size (slave to master) */
uint16_t sii_mailbox_protocols; /**< supported mailbox protocols */
uint8_t sii_physical_layer[4]; /**< port media */
const ec_slave_type_t *type; /**< Zeiger auf die Beschreibung
des Slave-Typs */
const ec_slave_type_t *type; /**< pointer to slave type object */
uint8_t registered; /**< Der Slave wurde registriert */
uint8_t registered; /**< true, if slave has been registered */
ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU-Konfigurationen */
uint8_t fmmu_count; /**< Wieviele FMMUs schon benutzt sind. */
ec_fmmu_t fmmus[EC_MAX_FMMUS]; /**< FMMU configurations */
uint8_t fmmu_count; /**< number of FMMUs used */
struct list_head eeprom_strings; /**< Strings im EEPROM */
struct list_head eeprom_syncs; /**< Syncmanager-Konfigurationen (EEPROM) */
struct list_head eeprom_pdos; /**< PDO-Beschreibungen im EEPROM */
struct list_head eeprom_strings; /**< EEPROM STRING categories */
struct list_head eeprom_syncs; /**< EEPROM SYNC MANAGER categories */
struct list_head eeprom_pdos; /**< EEPROM [RT]XPDO categories */
char *eeprom_name; /**< Slave-Name laut Hersteller */
char *eeprom_group; /**< Slave-Beschreibung laut Hersteller */
char *eeprom_desc; /**< Slave-Beschreibung laut Hersteller */
char *eeprom_name; /**< slave name acc. to EEPROM */
char *eeprom_group; /**< slave group acc. to EEPROM */
char *eeprom_desc; /**< slave description acc. to EEPROM */
struct list_head sdo_dictionary; /**< SDO-Verzeichnis des Slaves */
struct list_head sdo_dictionary; /**< SDO directory list */
ec_command_t mbox_command; /**< Kommando für Mailbox-Kommunikation */
ec_command_t mbox_command; /**< mailbox command */
};
/*****************************************************************************/
// Slave construction/destruction
// slave construction/destruction
int ec_slave_init(ec_slave_t *, ec_master_t *, uint16_t, uint16_t);
void ec_slave_clear(struct kobject *);
// Slave control
// slave control
int ec_slave_fetch(ec_slave_t *);
int ec_slave_sii_read16(ec_slave_t *, uint16_t, uint16_t *);
int ec_slave_sii_read32(ec_slave_t *, uint16_t, uint32_t *);
@@ -260,19 +259,13 @@ int ec_slave_state_change(ec_slave_t *, uint8_t);
int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *,
const ec_sync_t *);
// CANopen over EtherCAT
// CoE
int ec_slave_fetch_sdo_list(ec_slave_t *);
// Misc
// misc.
void ec_slave_print(const ec_slave_t *, unsigned int);
int ec_slave_check_crc(ec_slave_t *);
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* t y p e s . c
*
* EtherCAT-Slave-Typen.
* EtherCAT slave descriptions.
*
* $Id$
*
@@ -18,36 +18,34 @@
const ec_sync_t mailbox_sm0 = {0x1800, 246, 0x26, {NULL}};
const ec_sync_t mailbox_sm1 = {0x18F6, 246, 0x22, {NULL}};
/*****************************************************************************/
/* Klemmen-Objekte */
/*****************************************************************************/
/******************************************************************************
* slave objects
*****************************************************************************/
const ec_slave_type_t Beckhoff_EK1100 = {
"Beckhoff", "EK1100", "Bus Coupler", EC_TYPE_BUS_COUPLER,
{NULL} // Keine Sync-Manager
{NULL} // no sync managers
};
/*****************************************************************************/
const ec_slave_type_t Beckhoff_EK1110 = {
"Beckhoff", "EK1110", "Extension terminal", EC_TYPE_NORMAL,
{NULL} // Keine Sync-Manager
{NULL} // no sync managers
};
/*****************************************************************************/
const ec_slave_type_t Beckhoff_BK1120 = {
"Beckhoff", "BK1120", "KBUS Coupler", EC_TYPE_NORMAL,
{NULL} // Keine Sync-Manager
{NULL} // no sync managers
};
/*****************************************************************************/
const ec_field_t el1014_in = {"InputValue", 1};
const ec_sync_t el1014_sm0 = { // Inputs
const ec_sync_t el1014_sm0 = { // inputs
0x1000, 1, 0x00,
{&el1014_in, NULL}
};
@@ -195,15 +193,10 @@ const ec_slave_type_t TR_Electronic_LinEnc2 = {
/*****************************************************************************/
/**
Beziehung zwischen Identifikationsnummern und Klemmen-Objekt.
Diese Tabelle stellt die Beziehungen zwischen bestimmten Kombinationen
aus Vendor-IDs und Product-Codes und der entsprechenden Klemme her.
Neue Klemmen müssen hier eingetragen werden.
Mapping between vendor IDs and product codes <=> slave objects.
*/
ec_slave_ident_t slave_idents[] =
{
ec_slave_ident_t slave_idents[] = {
{0x00000002, 0x03F63052, &Beckhoff_EL1014},
{0x00000002, 0x044C2C52, &Beckhoff_EK1100},
{0x00000002, 0x04562C52, &Beckhoff_EK1110},
@@ -222,9 +215,3 @@ ec_slave_ident_t slave_idents[] =
};
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
*
* t y p e s . h
*
* EtherCAT-Slave-Typen.
* EtherCAT slave types.
*
* $Id$
*
@@ -23,27 +23,27 @@
/*****************************************************************************/
/**
Besondere Slaves.
Special slaves.
*/
typedef enum
{
EC_TYPE_NORMAL,
EC_TYPE_BUS_COUPLER,
EC_TYPE_EOE
EC_TYPE_NORMAL, /**< no special slave */
EC_TYPE_BUS_COUPLER, /**< slave is a bus coupler */
EC_TYPE_EOE /**< slave is an EoE switch */
}
ec_special_type_t;
/*****************************************************************************/
/**
Prozessdatenfeld.
Process data field.
*/
typedef struct
{
const char *name;
size_t size;
const char *name; /**< field name */
size_t size; /**< field size in bytes */
}
ec_field_t;
@@ -55,60 +55,45 @@ ec_field_t;
typedef struct
{
uint16_t physical_start_address;
uint16_t size;
uint8_t control_byte;
const ec_field_t *fields[EC_MAX_FIELDS];
uint16_t physical_start_address; /**< physical start address */
uint16_t size; /**< size in bytes */
uint8_t control_byte; /**< control register value */
const ec_field_t *fields[EC_MAX_FIELDS]; /**< field array */
}
ec_sync_t;
/*****************************************************************************/
/**
Beschreibung eines EtherCAT-Slave-Typs.
Diese Beschreibung dient zur Konfiguration einer bestimmten
Slave-Art. Sie enthält die Konfigurationsdaten für die
Slave-internen Sync-Manager und FMMUs.
Slave description type.
*/
typedef struct ec_slave_type
{
const char *vendor_name; /**< Name des Herstellers */
const char *product_name; /**< Name des Slaves-Typs */
const char *description; /**< Genauere Beschreibung des Slave-Typs */
ec_special_type_t special; /**< Spezieller Slave-Typ */
const ec_sync_t *sync_managers[EC_MAX_SYNC]; /**< Sync-Manager
Konfigurationen */
const char *vendor_name; /**< vendor name*/
const char *product_name; /**< product name */
const char *description; /**< free description */
ec_special_type_t special; /**< special slave type? */
const ec_sync_t *sync_managers[EC_MAX_SYNC]; /**< sync managers */
}
ec_slave_type_t;
/*****************************************************************************/
/**
Identifikation eines Slave-Typs.
Diese Struktur wird zur 1:n-Zuordnung von Hersteller- und
Produktcodes zu den einzelnen Slave-Typen verwendet.
Slave type identification.
*/
typedef struct slave_ident
typedef struct
{
uint32_t vendor_id; /**< Hersteller-Code */
uint32_t product_code; /**< Herstellerspezifischer Produktcode */
const ec_slave_type_t *type; /**< Zeiger auf den entsprechenden Typ */
uint32_t vendor_id; /**< vendor id */
uint32_t product_code; /**< product code */
const ec_slave_type_t *type; /**< associated slave description object */
}
ec_slave_ident_t;
extern ec_slave_ident_t slave_idents[]; /**< Statisches Array der
Slave-Identifikationen */
extern ec_slave_ident_t slave_idents[]; /**< array with slave descriptions */
/*****************************************************************************/
#endif
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -2,7 +2,7 @@
#
# Makefile
#
# Minimales EtherCAT-Modul
# Minimal EtherCAT module.
#
# $Id$
#
@@ -11,7 +11,7 @@
ifneq ($(KERNELRELEASE),)
#----------------------------------------------------------------
# Kbuild-Abschnitt
# kbuild section
#----------------------------------------------------------------
obj-m := ec_mini.o
@@ -23,7 +23,7 @@ ec_mini-objs := mini.o
else
#----------------------------------------------------------------
# Default-Abschnitt
# default section
#----------------------------------------------------------------
ifneq ($(wildcard ethercat.conf),)

View File

@@ -2,7 +2,7 @@
*
* m i n i . c
*
* Minimalmodul für EtherCAT
* Minimal module for EtherCAT.
*
* $Id$
*
@@ -12,31 +12,28 @@
#include <linux/delay.h>
#include <linux/timer.h>
#include "../include/ecrt.h" // Echtzeitschnittstelle
#include "../include/ecrt.h" // EtherCAT realtime interface
#define ASYNC
#define FREQUENCY 100
/*****************************************************************************/
#define ABTASTFREQUENZ 100
struct timer_list timer;
/*****************************************************************************/
// EtherCAT
ec_master_t *master = NULL;
ec_domain_t *domain1 = NULL;
// Datenfelder
// data fields
//void *r_ssi_input, *r_ssi_status, *r_4102[3];
// Kanäle
// channels
uint32_t k_pos;
uint8_t k_stat;
ec_field_init_t domain1_fields[] = {
{NULL, "1", "Beckhoff", "EL5001", "InputValue", 0},
{NULL, "1", "Beckhoff", "EL5001", "InputValue", 0},
{NULL, "2", "Beckhoff", "EL4132", "OutputValue", 0},
{}
};
@@ -48,22 +45,22 @@ void run(unsigned long data)
static unsigned int counter = 0;
#ifdef ASYNC
// Empfangen
// receive
ecrt_master_async_receive(master);
ecrt_domain_process(domain1);
#else
// Senden und empfangen
// send and receive
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_sync_io(master);
ecrt_domain_process(domain1);
#endif
// Prozessdaten verarbeiten
// process data
//k_pos = EC_READ_U32(r_ssi);
#ifdef ASYNC
// Senden
// send
ecrt_domain_queue(domain1);
ecrt_master_run(master);
ecrt_master_async_send(master);
@@ -73,13 +70,13 @@ void run(unsigned long data)
counter--;
}
else {
counter = ABTASTFREQUENZ;
counter = FREQUENCY;
//printk(KERN_INFO "k_pos = %i\n", k_pos);
//printk(KERN_INFO "k_stat = 0x%02X\n", k_stat);
}
// Timer neu starten
timer.expires += HZ / ABTASTFREQUENZ;
// restart timer
timer.expires += HZ / FREQUENCY;
add_timer(&timer);
}
@@ -153,14 +150,14 @@ int __init init_mini_module(void)
#endif
#ifdef ASYNC
// Einmal senden und warten...
// send once and wait...
ecrt_master_prepare_async_io(master);
#endif
printk("Starting cyclic sample thread.\n");
init_timer(&timer);
timer.function = run;
timer.expires = jiffies + 10; // Das erste Mal sofort feuern
timer.expires = jiffies + 10;
add_timer(&timer);
printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n");
@@ -203,8 +200,3 @@ module_exit(cleanup_mini_module);
/*****************************************************************************/
/* Emacs-Konfiguration
;;; Local Variables: ***
;;; c-basic-offset:4 ***
;;; End: ***
*/

View File

@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#
# Makefile Echtzeitmodule
# Makefile
#
# $Id$
#
@@ -9,7 +9,7 @@
ifneq ($(KERNELRELEASE),)
#------------------------------------------------------------------------------
# Kbuild-Abschnitt
# kbuild section
#------------------------------------------------------------------------------
ifneq ($(wildcard $(src)/rt.conf),)
@@ -44,7 +44,7 @@ EXTRA_CFLAGS := -I$(src)/rt_lib/msr-include -D_SIMULATION \
else
#------------------------------------------------------------------------------
# Default-Abschnitt
# default section
#------------------------------------------------------------------------------
ifneq ($(wildcard rt.conf),)

View File

@@ -2,14 +2,6 @@
#------------------------------------------------------------
#
# (C) Copyright
# Diese Software ist geistiges Eigentum der
# Ingenieurgemeinschaft IgH. Sie darf von
# Toyota Motorsport GmbH
# beliebig kopiert und veraendert werden.
# Die Weitergabe an Dritte ist untersagt.
# Dieser Urhebrrechtshinweis muss erhalten
# bleiben.
#
# Ingenieurgemeinschaft IgH
# Heinz-Baecker-Strasse 34
# D-45356 Essen
@@ -20,13 +12,13 @@
#
#------------------------------------------------------------
#
# Multithreaded Server
# Multithreaded Server
# according to the example from "Programming Perl"
# this code is improved according to the example from
# perldoc perlipc, so now safely being usable under Perl 5.8
# this code is improved according to the example from
# perldoc perlipc, so now safely being usable under Perl 5.8
# (see note (*))
#
# works with read/write on a device-file
# works with read/write on a device-file
#
# $Revision: 1.1 $
# $Date: 2004/10/01 16:00:42 $
@@ -40,9 +32,9 @@ BEGIN { $ENV{PATH} = '/opt/msr/bin:/usr/bin:/bin' }
use Socket;
use Carp;
use FileHandle;
use Getopt::Std;
use Getopt::Std;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Sys::Syslog qw(:DEFAULT setlogsock);
use vars qw (
$self $pid $dolog $port $dev %opts $selfbase
@@ -53,25 +45,25 @@ use vars qw (
# Do logging to local syslogd by unix-domain socket instead of inetd
setlogsock("unix");
setlogsock("unix");
# Prototypes and some little Tools
sub spawn;
sub logmsg {
sub logmsg {
my ($level, $debug, @text) = @_;
syslog("daemon|$level", @text) if $debug > $dolog;
# print STDERR "daemon|$level", @text, "\n" if $dolog;
}
sub out {
my $waitpid = wait;
my $waitpid = wait;
logmsg("notice", 2, "$waitpid exited");
unlink "$selfbase.pid";
exit 0;
}
sub help {
print "\n usage: $0 [-l og] [-h elp] [-p port] [-d device]\n";
exit;
print "\n usage: $0 [-l og] [-h elp] [-p port] [-d device]\n";
exit;
}
# Process Options
@@ -81,7 +73,7 @@ sub help {
"p" => 2345,
"d" => "/dev/msr"
);
getopts("lhp:d:", \%opts);
help if $opts{"h"};
@@ -94,7 +86,7 @@ $port = $opts{"p"};
$dev = $opts{"d"};
$blksize = 1024; # try to write as much bytes
$instdir = "/opt/msr";
$authfile = "$instdir/etc/hosts.auth";
$authfile = "$instdir/etc/hosts.auth";
# Start logging
openlog($self, 'pid');
@@ -127,12 +119,12 @@ setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, pack("l", 1))
or die "setsocketopt: $!";
bind (Server, sockaddr_in($port, INADDR_ANY))
or die "bind: $!";
listen (Server, SOMAXCONN)
listen (Server, SOMAXCONN)
or die "listen: $!";
%authhosts = ();
# get authorized hosts
open (AUTH, $authfile)
open (AUTH, $authfile)
or logmsg ("notice", 2, "Could not read allowed hosts file: $authfile");
while (<AUTH>) {
chomp;
@@ -176,26 +168,26 @@ while ( 1 ) {
my $name = lc gethostbyaddr($iaddr, AF_INET);
my $ipaddr = inet_ntoa($iaddr);
my $n = 0;
# tell about the requesting client
logmsg ("info", 2, "Connection from >$ipaddr< ($name) at port $port");
spawn sub {
my ($head, $hlen, $pos, $pegel, $typ, $siz, $nch, $nrec, $dat, $i, $j, $n, $llen);
my ($watchpegel, $shmpegel);
my ($rin, $rout, $in, $line, $data_requested, $oversample);
my (@channels);
# to use stdio on writing to Client
Client->autoflush();
# Open Device
# Open Device
sysopen (DEV, "$dev", O_RDWR | O_NONBLOCK, 0666) or die("can't open $dev");
# Bitmask to check for input on stdin
$rin = "";
vec($rin, fileno(Client), 1) = 1;
vec($rin, fileno(Client), 1) = 1;
# check for authorized hosts
my $access = 'deny';
$access = 'allow' if $authhosts{$ipaddr};
@@ -208,14 +200,14 @@ while ( 1 ) {
$len -= $written;
$offset += $written;
}
while ( 1 ) {
$in = select ($rout=$rin, undef, undef, 0.0); # poll client
# look for any Input from Client
if ($in) {
# exit on EOF
$len = sysread (Client, $line, $blksize) or exit;
logmsg("info", 0, "got $len bytes: \"$line\"");
logmsg("info", 0, "got $len bytes: \"$line\"");
$offset = 0;
# copy request to device
while ($len) {
@@ -239,11 +231,11 @@ while ( 1 ) {
sub spawn {
my $coderef = shift;
unless (@_ == 0 && $coderef && ref($coderef) eq 'CODE') {
confess "usage: spawn CODEREF";
}
my $pid;
my $pid;
if (!defined($pid = fork)) {
logmsg ("notice", 2, "fork failed: $!");
return;
@@ -258,15 +250,3 @@ sub spawn {
# STDOUT->autoflush();
exit &$coderef();
}