<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:#0563C1;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:#954F72;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hello, everyone.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.
<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I’m using EtherCAT master version 1.5.2 stable.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks in advance for any insights.<o:p></o:p></p>
<p class="MsoNormal">Tom<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-autospace:none"><br>
<span style="font-family:Consolas;color:blue">static</span><span style="font-family:Consolas">
<span style="color:blue">enum</span> hrtimer_restart<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">cyclic_task(<span style="color:blue">struct</span> hrtimer* timer)<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">{<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">struct</span> timeval tv;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">unsigned</span> <span style="color:blue">int</span> sync_ref_counter = 0;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// Increment the system tick counter</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> cts_system_ticks += 1;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">if</span> ( doScan_ )<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// receive process data</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> down(&masterSem_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_master_receive(master_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_domain_process(pgbl_domain);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> up(&masterSem_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// check process data state (optional)</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> check_domain_state();<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">if</span> (counter_) <o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> counter_--;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">else</span> <o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> counter_ = FREQUENCY;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// check for master state</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> check_master_state();<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> updateProcessData();<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">//</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// Tick the interpreter state machine</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">//</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> neoMain_process( &pgbl_neo );
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">if</span> ( doScan_ )<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// send process data</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> down(&masterSem_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// write application time to master</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> tv = ktime_to_timeval(ktime_get());<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> tv.tv_usec += 1000;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">if</span> (tv.tv_usec >= 1000000) <o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> tv.tv_usec -= 1000000;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> tv.tv_sec++;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_master_application_time(master_, EC_TIMEVAL2NANO(tv));<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">if</span> (sync_ref_counter) <o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> sync_ref_counter--;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }
<span style="color:blue">else</span> {<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> sync_ref_counter = 9;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_master_sync_reference_clock(master_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_master_sync_slave_clocks(master_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> /////////////////////////////////////////////////////////<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> //// THIS IS WHERE THE CRASH OCCURS AND THE KERNEL PANICS<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_domain_queue(pgbl_domain);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> ecrt_master_send(master_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> up(&masterSem_);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> /////////////////////////////////////////<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> }
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// </span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// Resart the HR timer</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// note that hrtimer_forward is GPL-only</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">//</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> hrtimer_forward_now(<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> &processTimer_,<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> processTimerNs_ );<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:blue">return</span> HRTIMER_RESTART; <o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Details of hrtimer :<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">// Frequency, in HZ, of the cyclic task</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:blue">#define</span><span style="font-family:Consolas"> FREQUENCY (4000)
<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">// The number of nsecs per sec.</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:blue">#define</span><span style="font-family:Consolas"> NSEC_PER_SEC (1000000000)
<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">// The number of nano seconds between process ticks</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:blue">#define</span><span style="font-family:Consolas"> FREQUENCY_NSEC (NSEC_PER_SEC / FREQUENCY)
<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">//</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">// Create a timer to call the process thread</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">// with nanosecond resolution.</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:green">//</span><span style="font-family:Consolas"><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas;color:blue">static</span><span style="font-family:Consolas">
<span style="color:blue">void</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">createTimer(<span style="color:blue">void</span>)<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">{<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> hrtimer_init(<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> &processTimer_,
<span style="color:green">// instance of process timer</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> CLOCK_MONOTONIC,
<span style="color:green">// Pick a specific clock. CLOCK_MONOTONIC is</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// guaranteed to move forward, no matter what.</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// It's akin to jiffies tick count</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// CLOCK_REALTIME matches the current real-world time</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> HRTIMER_MODE_REL );
<span style="color:green">// Timer mode (HRTIMER_ABS or HRTIMER_REL)</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> processTimer_.function = &cyclic_task;<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> processTimerNs_ = ktime_set(0, FREQUENCY_NSEC);<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">//</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// Start the timer. It will callback the .function</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// when the timer expires.</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">//</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> hrtimer_start(<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> &processTimer_,
<span style="color:green">// instance of process timer</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> processTimerNs_,
<span style="color:green">// time, nanosecconds </span>
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"> HRTIMER_MODE_REL );
<span style="color:green">// HRTIMER_REL indicates that time should be</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// interpreted relative</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// HRTIMER_ABS indicates time is an </span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<span style="color:green">// absolute value</span><o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">
<o:p></o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas"><o:p> </o:p></span></p>
<p class="MsoNormal" style="text-autospace:none"><span style="font-family:Consolas">}<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</body>
</html>