Hello, everyone. I've been successfully using the EtherLAB EtherCAT master for almost a year now and it has been going very well. Typically, I run the master on 2.6.33.7.2-rt30 PREEMPT RT kernel and there's never a problem. Up until this week, I've been developing on the same system, which means the graphics drivers and wireless doesn't work because the RT kernel breaks their drivers.
I tried re-compiling and running the code on a generic kernel instead (both a 2.6 and 3.5 kernel) using the ec_generic driver. The problem occurs in the cyclic task I have being ticked by an hrtimer. I slowed the rate of execution down to 100hz. The section indicated below always causes a crash/kernel panic, but there's no problem at all on the 2.6.33.7.2-rt30 PREEMPT kernel. I'd like to be able to run the kernel module on my day-to-day machine without installing the real-time kernel. I'm curious if the master simply can't be run on a generic kernel, or if it can't be ticked by an hrtimer on generic. I'm using EtherCAT master version 1.5.2 stable. Thanks in advance for any insights. Tom static enum hrtimer_restart cyclic_task(struct hrtimer* timer) { struct timeval tv; unsigned int sync_ref_counter = 0; // Increment the system tick counter cts_system_ticks += 1; if ( doScan_ ) { // receive process data down(&masterSem_); ecrt_master_receive(master_); ecrt_domain_process(pgbl_domain); up(&masterSem_); // check process data state (optional) check_domain_state(); if (counter_) { counter_--; } else { counter_ = FREQUENCY; // check for master state check_master_state(); } updateProcessData(); } // // Tick the interpreter state machine // neoMain_process( &pgbl_neo ); if ( doScan_ ) { // send process data down(&masterSem_); // write application time to master tv = ktime_to_timeval(ktime_get()); tv.tv_usec += 1000; if (tv.tv_usec >= 1000000) { tv.tv_usec -= 1000000; tv.tv_sec++; } ecrt_master_application_time(master_, EC_TIMEVAL2NANO(tv)); if (sync_ref_counter) { sync_ref_counter--; } else { sync_ref_counter = 9; ecrt_master_sync_reference_clock(master_); } ecrt_master_sync_slave_clocks(master_); ///////////////////////////////////////////////////////// //// THIS IS WHERE THE CRASH OCCURS AND THE KERNEL PANICS ecrt_domain_queue(pgbl_domain); ecrt_master_send(master_); up(&masterSem_); ///////////////////////////////////////// } // // Resart the HR timer // note that hrtimer_forward is GPL-only // hrtimer_forward_now( &processTimer_, processTimerNs_ ); return HRTIMER_RESTART; } Details of hrtimer : // Frequency, in HZ, of the cyclic task #define FREQUENCY (4000) // The number of nsecs per sec. #define NSEC_PER_SEC (1000000000) // The number of nano seconds between process ticks #define FREQUENCY_NSEC (NSEC_PER_SEC / FREQUENCY) // // Create a timer to call the process thread // with nanosecond resolution. // static void createTimer(void) { hrtimer_init( &processTimer_, // instance of process timer CLOCK_MONOTONIC, // Pick a specific clock. CLOCK_MONOTONIC is // guaranteed to move forward, no matter what. // It's akin to jiffies tick count // CLOCK_REALTIME matches the current real-world time HRTIMER_MODE_REL ); // Timer mode (HRTIMER_ABS or HRTIMER_REL) processTimer_.function = &cyclic_task; processTimerNs_ = ktime_set(0, FREQUENCY_NSEC); // // Start the timer. It will callback the .function // when the timer expires. // hrtimer_start( &processTimer_, // instance of process timer processTimerNs_, // time, nanosecconds HRTIMER_MODE_REL ); // HRTIMER_REL indicates that time should be // interpreted relative // HRTIMER_ABS indicates time is an // absolute value }
_______________________________________________ etherlab-dev mailing list etherlab-dev@etherlab.org http://lists.etherlab.org/mailman/listinfo/etherlab-dev