[etherlab-users] Immediate system crash, when loading realtime module

Erwin Burgstaller ethercat.berknapp at spamgourmet.com
Fri May 16 13:21:31 CEST 2008


I've a problem with the newest EtherCAT master
(ethercat-1.4.0-pre-trunk-r1132). Which I've to use, because version
1.3.2 does not handle the Beckhoff EL6001.

I'm using RTAI and my example code I use for evaluation runs with
version 1.3.2. I've made some changes for to run with version 1.4.0, but
the system crashes immediatly while loading the module. The computer
reboots automatically.

I'm using kernel version 2.6.22 and currently an 8139too compatible
network interface card or an e1000 compatible one.

My RTAI-realtime module may be loaded and runs as long as there's no
write or read request for the ring, which makes not much sense, of
course. ;-) But the 

I've made a simplified version which does just handle a single digital
output Module, a Beckhoff ES2400. It lets the first Output blink.

> lsec
 0    PREOP   EK1100 EtherCAT-Koppler (2A E-Bus)
 1    PREOP   EL2004 4K. Dig. Ausgang 24V, 0,5A

Loaded Modules are:

Module                  Size  Used by
rtai_sem               17536  0 
rtai_fifos             27592  0 
rtai_lxrt              82108  2 rtai_sem,rtai_fifos
rtai_hal               33012  3 rtai_sem,rtai_fifos,rtai_lxrt
ec_e1000              113152  0 
ec_master             124992  1 ec_e1000
8139too                22032  0 
usbhid                 22880  0 
ehci_hcd               41496  0 
uhci_hcd               29592  0 


The code runs perfect as it is and as it should with version 1.3.2 and
crashes the whole system instantly after loading with version 1.4.*

What's wrong?

Thanks in advande,

       Erwin


/*****************************************************************************/
// Linux
#include <linux/module.h>

// RTAI
#include "rtai_sched.h"
#include "rtai_sem.h"

// EtherCAT
#include "../../include/ecrt.h"

/*****************************************************************************/

// RTAI task frequency in Hz
#define FREQUENCY 2000
#define INHIBIT_TIME 20

#define TIMERTICKS (1000000000 / FREQUENCY)

#define PFX "ec_rtai_sample: "

/*****************************************************************************/

#if (ECRT_VER_MAJOR==1 && ECRT_VER_MINOR==3)
#define EC_VERSION_1_3
#define ec_master_state_t ec_master_status_t
#define ecrt_domain_reg_pdo_entry_list ecrt_domain_register_pdo_list
#endif

// RTAI
static RT_TASK task;
static SEM master_sem;
static cycles_t t_last_cycle = 0, t_critical;

// EtherCAT
static ec_master_t *master = NULL;
static ec_domain_t *domain1 = NULL;
static ec_master_state_t master_status, old_status = {};

// data fields
// static unsigned int r_dig_inout[100];
static unsigned int r_dig_out;

#define Beckhoff_EL2004 0x00000002, 0x07D43052
#define Beckhoff_EL2004_PDO_Outputs 0x7000, 0x1
#define Beckhoff_EL2004_Outputs Beckhoff_EL2004, Beckhoff_EL2004_PDO_Outputs 

#ifdef EC_VERSION_1_3
const static ec_pdo_reg_t domain1_pdo_regs[] = {

   {"1",  Beckhoff_EL2004_Outputs,            (void *)&r_dig_out},

   {}
};
#else
const static ec_pdo_entry_reg_t domain1_pdo_regs[] = {

   {0, 1,  Beckhoff_EL2004_Outputs,            &r_dig_out},

   {}
};
#endif

/*****************************************************************************/

void run(long data)
{
    static unsigned int blink = 0;
    static unsigned int counter = 0;

    while (1) {
        t_last_cycle = get_cycles();

        rt_sem_wait(&master_sem);
        ecrt_master_receive(master);
        ecrt_domain_process(domain1);
        rt_sem_signal(&master_sem);

	EC_WRITE_BIT(r_dig_out, 0, blink ? 0x01 : 0x00);

        rt_sem_wait(&master_sem);
        ecrt_domain_queue(domain1);
        ecrt_master_send(master);
        rt_sem_signal(&master_sem);
		
        if (counter) {
            counter--;
        }
        else {
            counter = FREQUENCY;
            blink = !blink;

            rt_sem_wait(&master_sem);
#ifdef EC_VERSION_1_3
	    ecrt_master_get_status(master, &master_status);
#else
            ecrt_master_state(master, &master_status);
#endif
            rt_sem_signal(&master_sem);

            if (master_status.slaves_responding !=
		old_status.slaves_responding) {
	       printk(KERN_INFO PFX "slaves_responding changed to %u.\n",
		      master_status.slaves_responding);
            }

            old_status = master_status;
        }
	
        rt_task_wait_period();
    }
}

/*****************************************************************************/

int request_lock(void *data)
{
    // too close to the next real time cycle: deny access...
    if (get_cycles() - t_last_cycle > t_critical) return -1;

    // allow access
    rt_sem_wait(&master_sem);
    return 0;
}

/*****************************************************************************/

void release_lock(void *data)
{
    rt_sem_signal(&master_sem);
}

/*****************************************************************************/

int __init init_mod(void)
{
    RTIME tick_period, requested_ticks, now;

    printk(KERN_INFO PFX "Starting...\n");

    rt_sem_init(&master_sem, 1);

    t_critical = cpu_khz * 1000 / FREQUENCY - cpu_khz * INHIBIT_TIME / 1000;

    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 "Creating domain...\n");
    if (!(domain1 = ecrt_master_create_domain(master))) {
        printk(KERN_ERR PFX "Domain creation failed!\n");
        goto out_release_master;
    }

    printk(KERN_INFO PFX "Registering Pdos...\n");
    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_pdo_regs)) {
        printk(KERN_ERR PFX "Pdo registration failed!\n");
        goto out_release_master;
    }

    printk(KERN_INFO PFX "Activating master...\n");
    if (ecrt_master_activate(master)) {
        printk(KERN_ERR PFX "Failed to activate master!\n");
        goto out_release_master;
    }

    printk(KERN_INFO PFX "Starting cyclic sample thread...\n");
    requested_ticks = nano2count(TIMERTICKS);
    tick_period = start_rt_timer(requested_ticks);
    printk(KERN_INFO PFX "RT timer started with %i/%i ticks.\n",
           (int) tick_period, (int) requested_ticks);

    if (rt_task_init(&task, run, 0, 2000, 0, 1, NULL)) {
        printk(KERN_ERR PFX "Failed to init RTAI task!\n");
        goto out_stop_timer;
    }

    now = rt_get_time();
    if (rt_task_make_periodic(&task, now + tick_period, tick_period)) {
        printk(KERN_ERR PFX "Failed to run RTAI task!\n");
        goto out_stop_task;
    }

    printk(KERN_INFO PFX "Initialized.\n");
    return 0;

 out_stop_task:
    rt_task_delete(&task);
 out_stop_timer:
    stop_rt_timer();
 out_release_master:
    printk(KERN_ERR PFX "Releasing master...\n");
    ecrt_release_master(master);
 out_return:
    rt_sem_delete(&master_sem);
    printk(KERN_ERR PFX "Failed to load. Aborting.\n");
    return -1;
}

/*****************************************************************************/

void __exit cleanup_mod(void)
{
    printk(KERN_INFO PFX "Stopping...\n");

    rt_task_delete(&task);
    stop_rt_timer();
    ecrt_release_master(master);
    rt_sem_delete(&master_sem);

    printk(KERN_INFO PFX "Unloading.\n");
}

/*****************************************************************************/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Florian Pose <fp at igh-essen.com>");
MODULE_DESCRIPTION("EtherCAT RTAI sample module");

module_init(init_mod);
module_exit(cleanup_mod);

/*****************************************************************************/



More information about the Etherlab-users mailing list