Re: clocksource and clockevent confusion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Le 07/04/2011 18:48, Johannes Bauer a écrit :
Hi again,

Thank you for your help Pat!

I figured out to write a driver, thats the code:

static cycle_t read_pit_clk(struct clocksource *cs)
{

	return T0TC;	// returns the actual timer count
}

static struct clocksource pit_clk = {
	.name		= \"pit\",
	.rating		= 175,
	.read		= read_pit_clk,
	.shift		= 28,	//is changed by init code
	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
};


void __init  lpc2xxx_time_init (void)
{
	unsigned char clkSel = 0;
	unsigned long stat = PLLSTAT;
	unsigned long M = stat&  0x7FFFF;
	unsigned long N = (stat>>16)&  0xFF;
	unsigned long Fcco = (2 * (M+1) *CONFIG_LPC22xx_Fosc) / (N+1);
	unsigned long Fcclk = Fcco / ((CCLKCFG&0xFF)+1);
	lpc2xxx_fcclk = Fcclk;
	lpc2xxx_fpclk = Fcclk;

	/*
   	 * Here we assume that the clock is the same for all peripherals
  	 * which of course doesn\'t have to be the case.
	 * We should be using the clk.h interface instead.
	 */
	
	clkSel = (unsigned char)(PCLKSEL0&  0xff);
	if (clkSel == 0x00)
		lpc2xxx_fpclk = lpc2xxx_fcclk / 4;
	else if (clkSel == 0x55)
		lpc2xxx_fpclk = lpc2xxx_fcclk;
	else if (clkSel == 0xAA)
		lpc2xxx_fpclk = lpc2xxx_fcclk / 2;
	else if (clkSel == 0xFF)
		lpc2xxx_fpclk = lpc2xxx_fcclk / 8;

	printk(\"LPC2XXX Clocking Fin=%dHz Fcco=%ldHz M=%ld N=%ld\\n\",
		CONFIG_LPC22xx_Fosc,
		Fcco,
		M,
		N);
	PCLKSEL0&= ~(3<<2);
	PCLKSEL0 |=  (1<<2);
	printk(\"Fcclk=%ld PCLKSEL=%08lx %08lx\\n\",
		Fcclk, PCLKSEL0, PCLKSEL1);
	/*
	 * disable and clear timer 0, set to
	 */
	T0TCR&= ~0x01;
	/* initialize the timer period and prescaler */
With hrtimer implementation, you don't ahve to implement the traditional titck timer. Once you have a clock event, the hrtimer use it. It tries to program the clock event in one shot shot mode (case CLOCK_EVT_MODE_ONESHOT) and you have the hrtimer support enabled. If it cant, then the subsystem is programmed in periodic mode (case CLOCK_EVT_MODE_PERIODIC) like in the traditional mode... no do_timer() ar all...

Cheers,

Pat.
	//counts with 72MHz so compare interrupt every 10ms
	T0MR0 = 720000;
	T0PR = 0;	// prescaler = 0
	T0MCR |= 0x03;			/* generate interrupt when T0MR0 match T0TC and Reset Timer Count*/

	lpc2xxx_timer_irq.handler = lpc2xxx_timer_interrupt;

	/* set up the interrupt vevtor for timer 0 match */
	setup_irq(LPC2xxx_INTERRUPT_TIMER0,&lpc2xxx_timer_irq);
	
	/* enable the timer IRQ */
	lpc22xx_unmask_irq(LPC2xxx_INTERRUPT_TIMER0);

	clocksource_calc_mult_shift(&pit_clk,Fcclk,4);	// minsecvalue =4 no idea why (seen in other codes)

	pit_clk.mask = 71999;				// mask is 71999 so the clk subsystem knows where it overruns (is that correct??)
	clocksource_register(&pit_clk);

	clockevents_calc_mult_shift(&pit_clkevt,Fcclk,4);	// minsecvalue =4 no idea why (seen in other codes)
	pit_clkevt.cpumask = cpumask_of(0);		// uniprocessro system
	clockevents_register_device(&pit_clkevt);

	/* let timer 0 run... */
	T0IR = 0x01; /* reset MR0 interrupt*/
	T0TCR = 0x02;	/* Reset timer count and prescale counter */
	T0TCR = 0x01;	/* enable timer counter and prescale counter */
}

struct sys_timer lpc22xx_timer = {
	.init		= lpc2xxx_time_init,
};



The problem is that after a minute or so the kernel freezes and hangs in the cpu_idle() function in arch/arm/kernel/process.c

the board stays in this whileloop in the else condition forever:

while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
			if (cpu_is_offline(smp_processor_id()))
				cpu_die();
#endif

			local_irq_disable();
			if (hlt_counter) {
				local_irq_enable();
				cpu_relax();
			} else {
				stop_critical_timings();
				pm_idle();
				start_critical_timings();
				/*
				 * This will eventually be removed - pm_idle
				 * functions should always return with IRQs
				 * enabled.
				 */
				WARN_ON(irqs_disabled());
				local_irq_enable();
			}
		}

i dont know what exactly the problem is...
Do i have to implement a sched_clock routine myself as is saw it in a few implemetations.
When i do a cat \"/proc/timer_list\" i can see folowing:

cat timer_list
Timer List Version: v0.5
HRTIMER_MAX_CLOCK_BASES: 2
now at 960971480 nsecs

cpu: 0
  clock 0:
   .base:       a031c560
   .index:      0
   .resolution: 10000000 nsecs
   .get_time:   ktime_get_real
   .offset:     0 nsecs
active timers:
  clock 1:
   .base:       a031c594
   .index:      1
   .resolution: 10000000 nsecs
   .get_time:   ktime_get
   .offset:     0 nsecs
active timers:
  #0: def_rt_bandwidth, sched_rt_period_timer, S:01, __enqueue_rt_entity, sirq-timer/0/4
  # expires at 1000000000-1000000000 nsecs [in 39028520 to 39028520 nsecs]
  #1:<a12fda88>, hrtimer_wakeup, S:01, hrtimer_start_range_ns, inetd/170
  # expires at 1960997774-1961997798 nsecs [in 1000026294 to 1001026318 nsecs]
   .expires_next   : 2147483646999999999 nsecs
   .hres_active    : 0
   .nr_events      : 0
   .nr_retries     : 0
   .nr_hangs       : 0
   .max_hang_time  : 0 nsecs
   .nohz_mode      : 0
   .idle_tick      : 0 nsecs
   .tick_stopped   : 0
   .idle_jiffies   : 0
   .idle_calls     : 0
   .idle_sleeps    : 0
   .idle_entrytime : 960913921 nsecs
   .idle_waketime  : 0 nsecs
   .idle_exittime  : 0 nsecs
   .idle_sleeptime : 77532270 nsecs
   .last_jiffies   : 0
   .next_jiffies   : 0
   .idle_expires   : 0 nsecs
jiffies: 4294941108


Tick Device: mode:     0
Per CPU device: 0
Clock Event Device: pit
  max_delta_ns:   0
  min_delta_ns:   0
  mult:           309237645
  shift:          32
  mode:           2
  next_event:     2147483646999999999 nsecs
  set_next_event:<(null)>
  set_mode:       pit_clkevt_mode
  event_handler:  tick_handle_periodic


I enabled some tracing and debuging in the kernel and then the following message was printed when the processor froze:

\"sched: RT throttling activated\"

What does it mean? IS it a problem of my timer implementation or is something else wrong with the system?

I hope somebody can help me on this.

Kind regards
Johannes Bauer

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



--
Patrice Kadionik. F6KQH / F4CUQ
-----------

+----------------------------------------------------------------------+
+"Tout doit etre aussi simple que possible, pas seulement plus simple" +
+----------------------------------------------------------------------+
+ Patrice Kadionik             http://www.enseirb-matmeca.fr/~kadionik +
+ IMS Laboratory               http://www.ims-bordeaux.fr/             +
+ ENSEIRB-MATMECA              http://www.enseirb-matmeca.fr           +
+ PO BOX 99                    fax   : +33 5.56.37.20.23               +
+ 33402 TALENCE Cedex          voice : +33 5.56.84.23.47               +
+ FRANCE                       mailto:patrice.kadionik@xxxxxxxxxxxxxxx +
+----------------------------------------------------------------------+

--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux