Re: hrtimer problem on AT91RM9200

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

 



Hi Remy,

Thank you for clarifying the setup.
The TC-block example was just what I was looking for.
I have the timer working so I'll give it a try and see if I
can fit it for our system.

Thank you for your time.

Best regards,
Bo

Remy Bohmer wrote:
Hi,

The Timer counter library sounds interesting - I previously took a look
at the source, but I miss some examples of how to use it. Do you know
anywhere I can find some beside tcb_clksrc.c?

Mailinglist archives?

But here is an example that produces a 400Hz (configurable) interrupt.
-------------------------------------------------------------------------------------
#include <linux/atmel_tc.h>

static struct atmel_tc *tc;
static int              tc_clk_id = 0; /* 0..2 (3 timers per TC-block) */
static int              tc_blk_id = 1; /* 0..1 (2 TC-blocks on rm9200,
0 is used by clocksrc/clockevent */
static int              tc_timer_freq = 400; /* HZ */

static irqreturn_t tc_timer_interrupt(int irq, void *dummy)
{
        void __iomem    *tcaddr = tc->regs;
        unsigned int    sr = __raw_readl(tcaddr + ATMEL_TC_REG(tc_clk_id, SR));

        if (sr & ATMEL_TC_CPCS) {
                wakeup_my_thread(); /* Here you must wakeup your
RT-thread (use wake_up_process() !!! )*/
                return IRQ_HANDLED;
        }
        return IRQ_NONE;
}

static struct irqaction tc_irqaction = {
       .name           = "periodic-tc-timer",
       .flags          = IRQF_NODELAY | IRQF_DISABLED,
       .handler        = tc_timer_interrupt,
};

void install_tc_periodic_interrupt(void)
{
        void __iomem    *tcaddr;
        int             rate;
        int             res;

        /* allocate the timer block */
        tc = atmel_tc_alloc(tc_blk_id, tc_irqaction.name);
        if (!tc) {
                printk(KERN_ERR "can't alloc TC\n");
                return -ENODEV;
        }

        tcaddr = tc->regs;

        res = setup_irq(tc->irq[tc_clk_id], &tc_irqaction);
        if (res) {
                printk(KERN_ERR "%s: Failed to install timer interrupt:%i\n",
                        __func__, res);
                return res;
        }

        clk_enable(tc->clk[tc_clk_id]);

        rate = clk_get_rate(tc->clk[tc_clk_id]);

        /* Stop only the timer we will use */
        __raw_writel(0xff, tcaddr + ATMEL_TC_REG(tc_clk_id, IDR));
        __raw_writel(ATMEL_TC_CLKDIS, tcaddr + ATMEL_TC_REG(tc_clk_id, CCR));

        /* Use MCK/8 (->CLOCK2), count up to RC, then irq and restart */
        __raw_writel(ATMEL_TC_TIMER_CLOCK2
                        | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO,
                        tcaddr + ATMEL_TC_REG(tc_clk_id, CMR));

        __raw_writel((rate/8) / tc_timer_freq,
                                tcaddr + ATMEL_TC_REG(tc_clk_id, RC));

        /* Enable clock and interrupts on RC compare */
        __raw_writel(ATMEL_TC_CPCS, tcaddr + ATMEL_TC_REG(tc_clk_id, IER));

        /* go go gadget! */
        __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG,
                        tcaddr + ATMEL_TC_REG(tc_clk_id, CCR));
        printk(KERN_INFO "TC interrupt source installed.\n");
}
-------------------------------------------------------------------------------------

Correct me if I'm wrong but using TC you still have the RT patch applied,
but just disabled HRT/dynticks?

Yes indeed. We use the RT-patch on these processors without
HRT/dynticks. We only use the OS/Posix-timers for non-realtime
applications, so CONFIG_HZ can be set low to reduce the timer
interrupt load.

Do you have any idea of the overhead of TC@1ms compared with
CONFIG_HZ=1000?

The difference between the 2 is that the kernel does not need to
handle all the elapsed timers on every timer interrupt, but instead
just waking up a single thread.
FYI, I made measurements of it some time ago that shows what happens
on a single timer interrupt on this processor, and I attached a
screenshot to this mail.

Have fun!

Remy
------------------------------------------------------------------------

--
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