[etherlab-dev] sync manager problem
chg at alpenjodel.de
chg at alpenjodel.de
Fri Dec 5 17:07:13 CET 2008
Hi,
i am trying to get the master 1.4.0.rc3 running on a Pentium 4 1,8Ghz with an Intell Gigabit nic. The Kernelversion is 2.6.24-21. The thing is that i am not able to get the slave to safeop or op state. Looking for the reason i found out the there is a problem with the sync manager configuration. It recognizes the two first sync managers and the other two sync managers für TX and RX stay unconigured. All the bytes in the configuration area are 0.
The EEPROM Content looks ok. The output of sii_read -v is:
SII Area:
08 0c 00 cc 00 00 00 00 00 00 00 00 00 00 13 00
0f 05 00 00 01 00 53 44 00 00 01 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 10 00 02 00 12 00 02 04 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 0f 00 01 00
SII Category 0x000a (STRINGS), 54 words
08 17 64 53 50 41 43 45 5f 45 74 68 65 72 43 41
54 5f 53 6c 61 76 65 5f 31 06 64 53 50 41 43 45
08 53 79 6e 63 68 72 6f 6e 0f 44 69 73 74 72 69
62 75 74 65 64 20 43 6c 6f 07 54 78 50 44 4f 20
31 12 4d 6f 64 65 6c 20 4f 75 74 70 75 74 73 20
52 45 41 4c 07 52 78 50 44 4f 20 31 0f 50 61 72
61 6d 65 74 65 72 20 55 73 61 67 65
SII Category 0x001e (General), 16 words
02 00 01 01 01 21 00 00 00 00 00 00 00 00 02 00
11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
SII Category 0x0028 (FMMU), 2 words
03 01 02 ff
SII Category 0x0029 (SyncM), 16 words
00 10 00 02 26 00 01 01 00 12 00 02 22 00 01 02
01 14 01 00 24 00 01 03 04 14 04 00 20 00 01 04
SII Category 0x002a (unknown), 6 words
f8 ff 00 00 fa ff 02 00 fa ff 03 00
SII Category 0x0032 (TXPDO), 8 words
00 1a 01 03 00 05 11 00 00 70 00 06 08 20 00 00
SII Category 0x0033 (RXPDO), 8 words
00 16 01 02 00 07 10 00 00 60 00 08 05 08 00 00
SII Category 0x003c (DC), 36 words
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
01 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 03 01 00 04 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07
01 00 04 00 00 00 00 00
The Frames that ar sent looks like this. I don´t know how to export the analysed frame in a better readable way from wireshark. Sorry for this.
0000 ff ff ff ff ff ff 00 1b 21 2a 01 ae 88 a4 2c 10 ........!*....,.
0010 05 cc 01 00 00 08 20 00 00 00 00 10 00 02 26 00 ...... .......&.
0020 01 00 00 12 00 02 22 00 01 00 00 00 00 00 00 00 ......".........
0030 00 00 00 00 00 00 00 00 00 00 00 00 ............
As you can see. The first to sync managers are configured and then the rest of the syncmanager code is 0.
The example program i am using looks like below. It is quite similar to the mini example without rtai:
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include "../../include/ecrt.h" // EtherCAT realtime interface
/*****************************************************************************/
// Module parameters
#define FREQUENCY 100
// Optional features
#define CONFIGURE_PDOS 1
#define EL3152_ALT_PDOS 0
#define EXTERNAL_MEMORY 1
#define SDO_ACCESS 0
#define PFX "ec_mini: "
/*****************************************************************************/
// EtherCAT
static ec_master_t *master = NULL;
static ec_master_state_t master_state = {};
spinlock_t master_lock = SPIN_LOCK_UNLOCKED;
static ec_domain_t *domain1 = NULL;
static ec_domain_state_t domain1_state = {};
static ec_slave_config_t *sc_ana_in = NULL;
static ec_slave_config_state_t sc_ana_in_state = {};
// Timer
static struct timer_list timer;
/*****************************************************************************/
// process data
static uint8_t *domain1_pd; // process data memory
#define Slave_1Pos 0,1
#define Slave_1 0x0000050f, 0x44530001
// offsets for Pdo entries
static unsigned int off_Slave_1;
const static ec_pdo_entry_reg_t domain1_regs[] = {
{Slave_1Pos, Slave_1, 0x6000,1,&off_Slave_1},//{alias address, slave Position, Vendor ID, Product ID, PDO entry Index,
//PDO Entry Subindex, *Byteoffset in den Prozessdaten, *Bit-Position}
{}
};
static unsigned int counter = 0;
static unsigned int blink = 0;
/*****************************************************************************/
#if CONFIGURE_PDOS
static ec_pdo_entry_info_t Slave1_pdo_entries [] = {
{0x6000,1,8},//{pdo entry index,pdo entry subindex, size of pdo entry in bit}
{0x7000,1,32}
};
static ec_pdo_info_t Slave_pdos [] = {
{0x1600,1,Slave1_pdo_entries},//{pdo index, Number of pdo entries to map 0=default mapping,Array of pdo entries to map}
{0x1a00,1,Slave1_pdo_entries+1}
};
static ec_sync_info_t Slave_syncs [] ={
{2,EC_DIR_OUTPUT,1,Slave_pdos },//{Sync manager Index, direction, number of pdos, array with pdos to assign}
{3,EC_DIR_INPUT},
{0xff}
};
#endif
/*****************************************************************************/
#if SDO_ACCESS
static ec_sdo_request_t *sdo;
#endif
/*****************************************************************************/
void check_domain1_state(void)
{
ec_domain_state_t ds;
spin_lock(&master_lock);
ecrt_domain_state(domain1, &ds);
spin_unlock(&master_lock);
if (ds.working_counter != domain1_state.working_counter)
printk(KERN_INFO PFX "Domain1: WC %u.\n", ds.working_counter);
if (ds.wc_state != domain1_state.wc_state)
printk(KERN_INFO PFX "Domain1: State %u.\n", ds.wc_state);
domain1_state = ds;
}
/*****************************************************************************/
void check_master_state(void)
{
ec_master_state_t ms;
spin_lock(&master_lock);
ecrt_master_state(master, &ms);
spin_unlock(&master_lock);
if (ms.slaves_responding != master_state.slaves_responding)
printk(KERN_INFO PFX "%u slave(s).\n", ms.slaves_responding);
if (ms.al_states != master_state.al_states)
printk(KERN_INFO PFX "AL states: 0x%02X.\n", ms.al_states);
if (ms.link_up != master_state.link_up)
printk(KERN_INFO PFX "Link is %s.\n", ms.link_up ? "up" : "down");
master_state = ms;
}
/*****************************************************************************/
void check_slave_config_states(void)
{
ec_slave_config_state_t s;
spin_lock(&master_lock);
ecrt_slave_config_state(sc_ana_in, &s);
spin_unlock(&master_lock);
if (s.al_state != sc_ana_in_state.al_state)
printk(KERN_INFO PFX "AnaIn: State 0x%02X.\n", s.al_state);
if (s.online != sc_ana_in_state.online)
printk(KERN_INFO PFX "AnaIn: %s.\n", s.online ? "online" : "offline");
if (s.operational != sc_ana_in_state.operational)
printk(KERN_INFO PFX "AnaIn: %soperational.\n",
s.operational ? "" : "Not ");
sc_ana_in_state = s;
}
/*****************************************************************************/
#if SDO_ACCESS
void read_sdo(void)
{
switch (ecrt_sdo_request_state(sdo)) {
case EC_SDO_REQUEST_UNUSED: // request was not used yet
ecrt_sdo_request_read(sdo); // trigger first read
break;
case EC_SDO_REQUEST_BUSY:
printk(KERN_INFO PFX "Still busy...\n");
break;
case EC_SDO_REQUEST_SUCCESS:
printk(KERN_INFO PFX "Sdo value: 0x%04X\n",
EC_READ_U16(ecrt_sdo_request_data(sdo)));
ecrt_sdo_request_read(sdo); // trigger next read
break;
case EC_SDO_REQUEST_ERROR:
printk(KERN_INFO PFX "Failed to read Sdo!\n");
ecrt_sdo_request_read(sdo); // retry reading
break;
}
}
#endif
/*****************************************************************************/
void cyclic_task(unsigned long data)
{
// receive process data
spin_lock(&master_lock);
ecrt_master_receive(master);
ecrt_domain_process(domain1);
spin_unlock(&master_lock);
// check process data state (optional)
check_domain1_state();
if (counter) {
counter--;
} else { // do this at 1 Hz
counter = FREQUENCY;
// calculate new process data
blink = !blink;
// check for master state (optional)
check_master_state();
// check for islave configuration state(s) (optional)
check_slave_config_states();
#if SDO_ACCESS
// read process data Sdo
read_sdo();
#endif
}
// write process data
EC_WRITE_U8(domain1_pd + off_dSPACE_Slave_1, blink ? 0x06 : 0x09);
// send process data
spin_lock(&master_lock);
ecrt_domain_queue(domain1);
ecrt_master_send(master);
spin_unlock(&master_lock);
// restart timer
timer.expires += HZ / FREQUENCY;
add_timer(&timer);
}
/*****************************************************************************/
int request_lock(void *data)
{
spin_lock(&master_lock);
return 0; // access allowed
}
/*****************************************************************************/
void release_lock(void *data)
{
spin_unlock(&master_lock);
}
/*****************************************************************************/
int __init init_mini_module(void)
{
#if CONFIGURE_PDOS
ec_slave_config_t *sc;
#endif
#if EXTERNAL_MEMORY
unsigned int size;
#endif
printk(KERN_INFO PFX "Starting...\n");
if (!(master = ecrt_request_master(0))) {
printk(KERN_ERR PFX "Requesting master 0 failed!\n");
goto out_return;
}
ecrt_master_callbacks(master, request_lock, release_lock, NULL);
printk(KERN_INFO PFX "Registering domain...\n");
if (!(domain1 = ecrt_master_create_domain(master))) {
printk(KERN_ERR PFX "Domain creation failed!\n");
goto out_release_master;
}
if (!(sc_ana_in = ecrt_master_slave_config(
master, Slave_1Pos, Slave_1))) {
printk(KERN_ERR PFX "Failed to get slave configuration.\n");
goto out_release_master;
}
#if CONFIGURE_PDOS
printk(KERN_INFO PFX "Configuring Pdos...\n");
if (ecrt_slave_config_pdos(sc_ana_in, EC_END, Slave_syncs)) {
printk(KERN_ERR PFX "Failed to configure Pdos.\n");
goto out_release_master;
}
#endif
#if SDO_ACCESS
printk(KERN_INFO PFX "Creating Sdo requests...\n");
if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x3102, 2, 2))) {
printk(KERN_ERR PFX "Failed to create Sdo request.\n");
goto out_release_master;
}
ecrt_sdo_request_timeout(sdo, 500); // ms
#endif
printk(KERN_INFO PFX "Registering Pdo entries...\n");
if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
printk(KERN_ERR PFX "Pdo entry registration failed!\n");
goto out_release_master;
}
#if EXTERNAL_MEMORY
if ((size = ecrt_domain_size(domain1))) {
if (!(domain1_pd = (uint8_t *) kmalloc(size, GFP_KERNEL))) {
printk(KERN_ERR PFX "Failed to allocate %u bytes of process data"
" memory!\n", size);
goto out_release_master;
}
ecrt_domain_external_memory(domain1, domain1_pd);
}
#endif
printk(KERN_INFO PFX "Activating master...\n");
if (ecrt_master_activate(master)) {
printk(KERN_ERR PFX "Failed to activate master!\n");
#if EXTERNAL_MEMORY
goto out_free_process_data;
#else
goto out_release_master;
#endif
}
#if !EXTERNAL_MEMORY
// Get internal process data for domain
domain1_pd = ecrt_domain_data(domain1);
#endif
printk(KERN_INFO PFX "Starting cyclic sample thread.\n");
init_timer(&timer);
timer.function = cyclic_task;
timer.expires = jiffies + 10;
add_timer(&timer);
printk(KERN_INFO PFX "Started.\n");
return 0;
#if EXTERNAL_MEMORY
out_free_process_data:
kfree(domain1_pd);
#endif
out_release_master:
printk(KERN_ERR PFX "Releasing master...\n");
ecrt_release_master(master);
out_return:
printk(KERN_ERR PFX "Failed to load. Aborting.\n");
return -1;
}
/*****************************************************************************/
void __exit cleanup_mini_module(void)
{
printk(KERN_INFO PFX "Stopping...\n");
del_timer_sync(&timer);
#if EXTERNAL_MEMORY
kfree(domain1_pd);
#endif
printk(KERN_INFO PFX "Releasing master...\n");
ecrt_release_master(master);
printk(KERN_INFO PFX "Unloading.\n");
}
/*****************************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Florian Pose <fp at igh-essen.com>");
MODULE_DESCRIPTION("EtherCAT minimal test environment");
module_init(init_mini_module);
module_exit(cleanup_mini_module);
/*****************************************************************************/
Does anybody know where to look for the mistake, or has had similar problems.
Thanks for any help
Best Regards
Christian
--
Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger
More information about the etherlab-dev
mailing list