[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