Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
etherlabmaster
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ICS Control System Infrastructure
etherlabmaster
Commits
dba0224a
Commit
dba0224a
authored
19 years ago
by
Florian Pose
Browse files
Options
Downloads
Patches
Plain Diff
Restliche EEPROM-Daten ausgelesen.
parent
bdea1a43
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
master/slave.c
+173
-62
173 additions, 62 deletions
master/slave.c
master/slave.h
+79
-13
79 additions, 13 deletions
master/slave.h
with
252 additions
and
75 deletions
master/slave.c
+
173
−
62
View file @
dba0224a
...
...
@@ -21,10 +21,8 @@
int
ec_slave_fetch_categories
(
ec_slave_t
*
);
int
ec_slave_fetch_strings
(
ec_slave_t
*
,
const
uint8_t
*
);
int
ec_slave_fetch_general
(
ec_slave_t
*
,
const
uint8_t
*
);
void
ec_slave_fetch_fmmu
(
ec_slave_t
*
,
const
uint8_t
*
);
void
ec_slave_fetch_sync
(
ec_slave_t
*
,
const
uint8_t
*
);
void
ec_slave_fetch_txpdo
(
ec_slave_t
*
,
const
uint8_t
*
);
void
ec_slave_fetch_rxpdo
(
ec_slave_t
*
,
const
uint8_t
*
);
int
ec_slave_fetch_sync
(
ec_slave_t
*
,
const
uint8_t
*
,
size_t
);
int
ec_slave_fetch_pdo
(
ec_slave_t
*
,
const
uint8_t
*
,
size_t
,
ec_pdo_type_t
);
int
ec_slave_locate_string
(
ec_slave_t
*
,
unsigned
int
,
char
**
);
/*****************************************************************************/
...
...
@@ -53,11 +51,12 @@ void ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */
slave
->
type
=
NULL
;
slave
->
registered
=
0
;
slave
->
fmmu_count
=
0
;
INIT_LIST_HEAD
(
&
slave
->
eeprom_strings
);
slave
->
eeprom_name
=
NULL
;
slave
->
eeprom_group
=
NULL
;
slave
->
eeprom_desc
=
NULL
;
INIT_LIST_HEAD
(
&
slave
->
eeprom_strings
);
INIT_LIST_HEAD
(
&
slave
->
eeprom_syncs
);
INIT_LIST_HEAD
(
&
slave
->
eeprom_pdos
);
}
/*****************************************************************************/
...
...
@@ -68,14 +67,38 @@ void ec_slave_init(ec_slave_t *slave, /**< EtherCAT-Slave */
void
ec_slave_clear
(
ec_slave_t
*
slave
/**< EtherCAT-Slave */
)
{
ec_slave_string_t
*
string
,
*
next
;
ec_eeprom_string_t
*
string
,
*
next_str
;
ec_eeprom_sync_t
*
sync
,
*
next_sync
;
ec_eeprom_pdo_t
*
pdo
,
*
next_pdo
;
ec_eeprom_pdo_entry_t
*
entry
,
*
next_ent
;
// Alle Strings freigeben
list_for_each_entry_safe
(
string
,
next
,
&
slave
->
eeprom_strings
,
list
)
{
list_for_each_entry_safe
(
string
,
next
_str
,
&
slave
->
eeprom_strings
,
list
)
{
list_del
(
&
string
->
list
);
kfree
(
string
);
}
// Alle Sync-Manager freigeben
list_for_each_entry_safe
(
sync
,
next_sync
,
&
slave
->
eeprom_syncs
,
list
)
{
list_del
(
&
sync
->
list
);
kfree
(
sync
);
}
// Alle PDOs freigeben
list_for_each_entry_safe
(
pdo
,
next_pdo
,
&
slave
->
eeprom_pdos
,
list
)
{
list_del
(
&
pdo
->
list
);
if
(
pdo
->
name
)
kfree
(
pdo
->
name
);
// Alle Entries innerhalb eines PDOs freigeben
list_for_each_entry_safe
(
entry
,
next_ent
,
&
pdo
->
entries
,
list
)
{
list_del
(
&
entry
->
list
);
if
(
entry
->
name
)
kfree
(
entry
->
name
);
kfree
(
entry
);
}
kfree
(
pdo
);
}
if
(
slave
->
eeprom_name
)
kfree
(
slave
->
eeprom_name
);
if
(
slave
->
eeprom_group
)
kfree
(
slave
->
eeprom_group
);
if
(
slave
->
eeprom_desc
)
kfree
(
slave
->
eeprom_desc
);
...
...
@@ -299,7 +322,7 @@ int ec_slave_sii_write(ec_slave_t *slave,
int
ec_slave_fetch_categories
(
ec_slave_t
*
slave
/**< EtherCAT-Slave */
)
{
uint16_t
word_offset
,
header
,
word_count
;
uint16_t
word_offset
,
cat_type
,
word_count
;
uint32_t
value
;
uint8_t
*
cat_data
;
unsigned
int
i
;
...
...
@@ -314,16 +337,16 @@ int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
}
while
(
1
)
{
// read category
header
// read category
type
if
(
ec_slave_sii_read
(
slave
,
word_offset
,
&
value
))
{
EC_ERR
(
"Unable to read category header
and size
.
\n
"
);
EC_ERR
(
"Unable to read category header.
\n
"
);
goto
out_free
;
}
// Last category?
if
((
value
&
0xFFFF
)
==
0xFFFF
)
break
;
header
=
value
&
0x7FFF
;
cat_type
=
value
&
0x7FFF
;
word_count
=
(
value
>>
16
)
&
0xFFFF
;
// Fetch category data
...
...
@@ -344,36 +367,33 @@ int ec_slave_fetch_categories(ec_slave_t *slave /**< EtherCAT-Slave */)
}
}
switch
(
header
)
switch
(
cat_type
)
{
case
0x000A
:
if
(
ec_slave_fetch_strings
(
slave
,
cat_data
))
goto
out_free
;
break
;
case
0x001E
:
case
0x0001
:
if
(
ec_slave_fetch_general
(
slave
,
cat_data
))
goto
out_free
;
break
;
case
0x0028
:
case
0x0002
:
ec_slave_fetch_fmmu
(
slave
,
cat_data
);
break
;
case
0x0029
:
case
0x0003
:
ec_slave_fetch_sync
(
slave
,
cat_data
)
;
if
(
ec_slave_fetch_sync
(
slave
,
cat_data
,
word_count
))
goto
out_free
;
break
;
case
0x0032
:
case
0x0004
:
ec_slave_fetch_txpdo
(
slave
,
cat_data
)
;
if
(
ec_slave_fetch_pdo
(
slave
,
cat_data
,
word_count
,
EC_TX_PDO
))
goto
out_free
;
break
;
case
0x0033
:
case
0x0005
:
ec_slave_fetch_rxpdo
(
slave
,
cat_data
)
;
if
(
ec_slave_fetch_pdo
(
slave
,
cat_data
,
word_count
,
EC_RX_PDO
))
goto
out_free
;
break
;
default:
EC_WARN
(
"Unknown category
header
0x%04X in slave %i.
\n
"
,
header
,
slave
->
ring_position
);
EC_WARN
(
"Unknown category
type
0x%04X in slave %i.
\n
"
,
cat_type
,
slave
->
ring_position
);
}
word_offset
+=
2
+
word_count
;
...
...
@@ -402,21 +422,20 @@ int ec_slave_fetch_strings(ec_slave_t *slave, /**< EtherCAT-Slave */
unsigned
int
string_count
,
i
;
size_t
size
;
off_t
offset
;
ec_
slave
_string_t
*
string
;
ec_
eeprom
_string_t
*
string
;
string_count
=
data
[
0
];
offset
=
1
;
for
(
i
=
0
;
i
<
string_count
;
i
++
)
{
size
=
data
[
offset
];
// Speicher fr String-Objekt und Daten in einem Rutsch allozieren
if
(
!
(
string
=
(
ec_slave_string_t
*
)
kmalloc
(
sizeof
(
ec_slave_string_t
)
+
size
+
1
,
GFP_KERNEL
)))
{
if
(
!
(
string
=
(
ec_eeprom_string_t
*
)
kmalloc
(
sizeof
(
ec_eeprom_string_t
)
+
size
+
1
,
GFP_KERNEL
)))
{
EC_ERR
(
"Failed to allocate string memory.
\n
"
);
return
-
1
;
}
string
->
size
=
size
;
string
->
data
=
(
char
*
)
string
+
sizeof
(
ec_
slave
_string_t
);
string
->
data
=
(
char
*
)
string
+
sizeof
(
ec_
eeprom
_string_t
);
memcpy
(
string
->
data
,
data
+
offset
+
1
,
size
);
string
->
data
[
size
]
=
0x00
;
list_add_tail
(
&
string
->
list
,
&
slave
->
eeprom_strings
);
...
...
@@ -449,25 +468,36 @@ int ec_slave_fetch_general(ec_slave_t *slave, /**< EtherCAT-Slave */
/*****************************************************************************/
/**
Holt die Daten einer
FMMU
-Kategorie.
Holt die Daten einer
Sync-Manager
-Kategorie.
*/
void
ec_slave_fetch_fmmu
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
/**< Kategorie-Daten */
)
int
ec_slave_fetch_sync
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
,
/**< Kategorie-Daten */
size_t
word_count
/**< Anzahl Words */
)
{
}
unsigned
int
sync_count
,
i
;
ec_eeprom_sync_t
*
sync
;
/*****************************************************************************/
sync_count
=
word_count
/
4
;
// Sync-Manager-Strunktur ist 4 Worte lang
/**
Holt die Daten einer Sync-Manager-Kategorie.
*/
for
(
i
=
0
;
i
<
sync_count
;
i
++
,
data
+=
8
)
{
if
(
!
(
sync
=
(
ec_eeprom_sync_t
*
)
kmalloc
(
sizeof
(
ec_eeprom_sync_t
),
GFP_KERNEL
)))
{
EC_ERR
(
"Failed to allocate Sync-Manager memory.
\n
"
);
return
-
1
;
}
void
ec_slave_fetch_sync
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
/**< Kategorie-Daten */
)
{
sync
->
index
=
i
;
sync
->
physical_start_address
=
*
((
uint16_t
*
)
(
data
+
0
));
sync
->
length
=
*
((
uint16_t
*
)
(
data
+
2
));
sync
->
control_register
=
data
[
4
];
sync
->
enable
=
data
[
6
];
list_add_tail
(
&
sync
->
list
,
&
slave
->
eeprom_syncs
);
}
return
0
;
}
/*****************************************************************************/
...
...
@@ -476,22 +506,58 @@ void ec_slave_fetch_sync(ec_slave_t *slave, /**< EtherCAT-Slave */
Holt die Daten einer TXPDO-Kategorie.
*/
void
ec_slave_fetch_txpdo
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
/**< Kategorie-Daten */
)
int
ec_slave_fetch_pdo
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
,
/**< Kategorie-Daten */
size_t
word_count
,
/**< Anzahl Worte */
ec_pdo_type_t
pdo_type
/**< PDO-Typ */
)
{
}
ec_eeprom_pdo_t
*
pdo
;
ec_eeprom_pdo_entry_t
*
entry
;
unsigned
int
entry_count
,
i
;
while
(
word_count
>=
4
)
{
if
(
!
(
pdo
=
(
ec_eeprom_pdo_t
*
)
kmalloc
(
sizeof
(
ec_eeprom_pdo_t
),
GFP_KERNEL
)))
{
EC_ERR
(
"Failed to allocate PDO memory.
\n
"
);
return
-
1
;
}
/*****************************************************************************/
INIT_LIST_HEAD
(
&
pdo
->
entries
);
pdo
->
type
=
pdo_type
;
/**
Holt die Daten einer RXPDO-Kategorie.
*/
pdo
->
index
=
*
((
uint16_t
*
)
data
);
entry_count
=
data
[
2
];
pdo
->
sync_manager
=
data
[
3
];
pdo
->
name
=
NULL
;
ec_slave_locate_string
(
slave
,
data
[
5
],
&
pdo
->
name
);
void
ec_slave_fetch_rxpdo
(
ec_slave_t
*
slave
,
/**< EtherCAT-Slave */
const
uint8_t
*
data
/**< Kategorie-Daten */
)
{
list_add_tail
(
&
pdo
->
list
,
&
slave
->
eeprom_pdos
);
word_count
-=
4
;
data
+=
8
;
for
(
i
=
0
;
i
<
entry_count
;
i
++
)
{
if
(
!
(
entry
=
(
ec_eeprom_pdo_entry_t
*
)
kmalloc
(
sizeof
(
ec_eeprom_pdo_entry_t
),
GFP_KERNEL
)))
{
EC_ERR
(
"Failed to allocate PDO entry memory.
\n
"
);
return
-
1
;
}
entry
->
index
=
*
((
uint16_t
*
)
data
);
entry
->
subindex
=
data
[
2
];
entry
->
name
=
NULL
;
ec_slave_locate_string
(
slave
,
data
[
3
],
&
entry
->
name
);
entry
->
bit_length
=
data
[
5
];
list_add_tail
(
&
entry
->
list
,
&
pdo
->
entries
);
word_count
-=
4
;
data
+=
8
;
}
}
return
0
;
}
/*****************************************************************************/
...
...
@@ -502,26 +568,40 @@ void ec_slave_fetch_rxpdo(ec_slave_t *slave, /**< EtherCAT-Slave */
int
ec_slave_locate_string
(
ec_slave_t
*
slave
,
unsigned
int
index
,
char
**
ptr
)
{
ec_slave_string_t
*
string
;
ec_eeprom_string_t
*
string
;
char
*
err_string
;
// Erst alten Speicher freigeben
if
(
*
ptr
)
{
kfree
(
*
ptr
);
*
ptr
=
NULL
;
}
// Index 0 bedeutet "nicht belegt"
if
(
!
index
)
return
0
;
// EEPROM-String mit Index finden und kopieren
list_for_each_entry
(
string
,
&
slave
->
eeprom_strings
,
list
)
{
if
(
!
(
--
index
))
{
if
(
!
(
*
ptr
=
(
char
*
)
kmalloc
(
string
->
size
+
1
,
GFP_KERNEL
)))
{
EC_ERR
(
"Unable to allocate string memory.
\n
"
);
return
-
1
;
}
memcpy
(
*
ptr
,
string
->
data
,
string
->
size
+
1
);
break
;
if
(
--
index
)
continue
;
if
(
!
(
*
ptr
=
(
char
*
)
kmalloc
(
string
->
size
+
1
,
GFP_KERNEL
)))
{
EC_ERR
(
"Unable to allocate string memory.
\n
"
);
return
-
1
;
}
memcpy
(
*
ptr
,
string
->
data
,
string
->
size
+
1
);
return
0
;
}
EC_WARN
(
"String %i not found in slave %i.
\n
"
,
index
,
slave
->
ring_position
);
err_string
=
"(string not found)"
;
if
(
!
(
*
ptr
=
(
char
*
)
kmalloc
(
strlen
(
err_string
)
+
1
,
GFP_KERNEL
)))
{
EC_ERR
(
"Unable to allocate string memory.
\n
"
);
return
-
1
;
}
memcpy
(
*
ptr
,
err_string
,
strlen
(
err_string
)
+
1
);
return
0
;
}
...
...
@@ -704,6 +784,10 @@ int ec_slave_set_fmmu(ec_slave_t *slave, /**< EtherCAT-Slave */
void
ec_slave_print
(
const
ec_slave_t
*
slave
/**< EtherCAT-Slave */
)
{
ec_eeprom_sync_t
*
sync
;
ec_eeprom_pdo_t
*
pdo
;
ec_eeprom_pdo_entry_t
*
entry
;
EC_INFO
(
"x-- EtherCAT slave information ---------------
\n
"
);
if
(
slave
->
type
)
{
...
...
@@ -725,19 +809,46 @@ void ec_slave_print(const ec_slave_t *slave /**< EtherCAT-Slave */)
slave
->
base_fmmu_count
,
slave
->
base_sync_count
);
EC_INFO
(
"| EEPROM data:
\n
"
);
if
(
slave
->
sii_alias
)
EC_INFO
(
"| Configured station alias: 0x%04X (%i)
\n
"
,
slave
->
sii_alias
,
slave
->
sii_alias
);
EC_INFO
(
"| Vendor-ID: 0x%08X, Product code: 0x%08X
\n
"
,
slave
->
sii_vendor_id
,
slave
->
sii_product_code
);
EC_INFO
(
"| Revision number: 0x%08X, Serial number: 0x%08X
\n
"
,
slave
->
sii_revision_number
,
slave
->
sii_serial_number
);
if
(
slave
->
eeprom_name
)
EC_INFO
(
"| Name: %s
\n
"
,
slave
->
eeprom_name
);
if
(
slave
->
eeprom_group
)
EC_INFO
(
"| Group: %s
\n
"
,
slave
->
eeprom_group
);
if
(
slave
->
eeprom_desc
)
EC_INFO
(
"| Description: %s
\n
"
,
slave
->
eeprom_desc
);
if
(
!
list_empty
(
&
slave
->
eeprom_syncs
))
{
EC_INFO
(
"| Sync-Managers:
\n
"
);
list_for_each_entry
(
sync
,
&
slave
->
eeprom_syncs
,
list
)
{
EC_INFO
(
"| %i: 0x%04X, length %i, control 0x%02X, %s
\n
"
,
sync
->
index
,
sync
->
physical_start_address
,
sync
->
length
,
sync
->
control_register
,
sync
->
enable
?
"enable"
:
"disable"
);
}
}
list_for_each_entry
(
pdo
,
&
slave
->
eeprom_pdos
,
list
)
{
EC_INFO
(
"| %s
\"
%s
\"
(0x%04X), -> Sync-Manager %i
\n
"
,
pdo
->
type
==
EC_RX_PDO
?
"RXPDO"
:
"TXPDO"
,
pdo
->
name
?
pdo
->
name
:
"???"
,
pdo
->
index
,
pdo
->
sync_manager
);
list_for_each_entry
(
entry
,
&
pdo
->
entries
,
list
)
{
EC_INFO
(
"|
\"
%s
\"
0x%04X:%X, %i Bit
\n
"
,
entry
->
name
?
entry
->
name
:
"???"
,
entry
->
index
,
entry
->
subindex
,
entry
->
bit_length
);
}
}
EC_INFO
(
"x---------------------------------------------
\n
"
);
}
...
...
This diff is collapsed.
Click to expand it.
master/slave.h
+
79
−
13
View file @
dba0224a
...
...
@@ -21,17 +21,18 @@
typedef
enum
{
EC_SLAVE_STATE_UNKNOWN
=
0x00
,
/**< Status unbekannt */
EC_SLAVE_STATE_INIT
=
0x01
,
/**< Init-Zustand (Keine Mailbox-
Kommunikation, Kein I/O) */
EC_SLAVE_STATE_PREOP
=
0x02
,
/**< Pre-Operational (Mailbox-
Kommunikation, Kein I/O) */
EC_SLAVE_STATE_SAVEOP
=
0x04
,
/**< Save-Operational (Mailbox-
Kommunikation und Input Update) */
EC_SLAVE_STATE_OP
=
0x08
,
/**< Operational, (Mailbox-
Kommunikation und Input/Output Update) */
EC_ACK
=
0x10
/**< Acknoledge-Bit beim Zustandswechsel
(dies ist kein eigener Zustand) */
EC_SLAVE_STATE_UNKNOWN
=
0x00
,
/**< Status unbekannt */
EC_SLAVE_STATE_INIT
=
0x01
,
/**< Init-Zustand (Keine Mailbox-Kommunikation, Kein I/O) */
EC_SLAVE_STATE_PREOP
=
0x02
,
/**< Pre-Operational (Mailbox-Kommunikation, Kein I/O) */
EC_SLAVE_STATE_SAVEOP
=
0x04
,
/**< Save-Operational (Mailbox-Kommunikation und Input Update) */
EC_SLAVE_STATE_OP
=
0x08
,
/**< Operational, (Mailbox-Kommunikation und Input/Output Update) */
EC_ACK
=
0x10
/**< Acknoledge-Bit beim Zustandswechsel (kein eigener Zustand) */
}
ec_slave_state_t
;
...
...
@@ -52,7 +53,7 @@ ec_fmmu_t;
/*****************************************************************************/
/**
EEPROM-String
.
String im EEPROM eines EtherCAT-Slaves
.
*/
typedef
struct
...
...
@@ -61,7 +62,70 @@ typedef struct
size_t
size
;
char
*
data
;
}
ec_slave_string_t
;
ec_eeprom_string_t
;
/*****************************************************************************/
/**
Sync-Manager-Konfiguration laut 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
;
}
ec_eeprom_sync_t
;
/*****************************************************************************/
/**
PDO-Typ.
*/
typedef
enum
{
EC_RX_PDO
,
EC_TX_PDO
}
ec_pdo_type_t
;
/*****************************************************************************/
/**
PDO-Beschreibung im 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
;
}
ec_eeprom_pdo_t
;
/*****************************************************************************/
/**
PDO-Entry-Beschreibung im EEPROM.
*/
typedef
struct
{
struct
list_head
list
;
uint16_t
index
;
uint8_t
subindex
;
char
*
name
;
uint8_t
bit_length
;
}
ec_eeprom_pdo_entry_t
;
/*****************************************************************************/
...
...
@@ -100,6 +164,8 @@ struct ec_slave
uint8_t
fmmu_count
;
/**< Wieviele FMMUs schon benutzt sind. */
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 */
char
*
eeprom_name
;
/**< Slave-Name laut Hersteller */
char
*
eeprom_group
;
/**< Slave-Beschreibung laut Hersteller */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment