[etherlab-dev] Crashing in Generic Kernel
Thomas Bitsky Jr
tbj at automateddesign.com
Wed Jan 8 21:07:50 CET 2014
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
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.etherlab.org/pipermail/etherlab-dev/attachments/20140108/f8a38b02/attachment-0001.html>
More information about the etherlab-dev
mailing list