This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x如何使用timer(Kernel 4.4)



我想使用tiemr做一系列事情,不希望使用linux内核提供的timer、hrtimer做定时,而需要绝对精确的独立定时器

设置一个自由定时器测频,通过GPIO中断读取timer_cnt的值

设置另一个timer输出PWM,调节周期和占空比

请问这些操作需要通过什么api实现啊? 我找了一圈文档都没有看到

只有arch/arm/mach-omap2/timer.c里有一些函数,似乎也不足以完成上面的功能

麻烦指点一下,谢谢

  • 自己写驱动,对底层的硬件寄存器进行操作

  • 我从e2e上找到个例子,用的plat/dmtimer.h的API,不知道对不对

    /****************************************************************/
    /* PWM Timer Driver used to trig A/D convert                    */
    /****************************************************************/
    
    int timer_pwm_init(struct as_platform_data *as_data)
    {
        struct omap_dm_timer *timer_pwm_ptr;
    
        int ret = 1;
        int timer_reload;
        struct clk *timer_clk;
    
        if (as_data == NULL)
        {
            printk(KERN_ERR "timer_pwm_init got NULL as_data.\n");
            return(-1);
        }
    
        timer_pwm_ptr = as_data->timer_pwm;
    
        /* Set the Clock source to the System Clock */
        ret = omap_dm_timer_set_source(timer_pwm_ptr, OMAP_TIMER_SRC_SYS_CLK);
    
        /* Determine what IRQ the timer triggers */
        as_data->timer_pwm_irq = omap_dm_timer_get_irq(timer_pwm_ptr);
    
        /* Get the Clock rate in Hz */
        timer_clk = omap_dm_timer_get_fclk(timer_pwm_ptr);
        as_data->timer_pwm_rate = clk_get_rate(timer_clk);
    
        /* calc 50Hz * 512 initial rate */
        as_data->timer_pwm_clks_per_cycle = as_data->timer_pwm_rate / (50 * 512);
        /* calc reload value, maybe +1 is needed if output freq is not accurate */
        timer_reload = 0xFFFFFFFF - as_data->timer_pwm_clks_per_cycle; // +1
    
        /* Setup the Output for the Timer pin */
        /* Setup to toggle on the overflow and the compare match event */
        omap_dm_timer_set_pwm(timer_pwm_ptr, 0, 1, OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE);
    
        /* Enable the Timer */
        /* Needs to be done before we can write to the counter */
        omap_dm_timer_enable(timer_pwm_ptr);
    
        /* Set the initial Count */
        /* According to section 20.1.3.5 Pulse-Width Modulation, an overflow or match be used to toggle when a compare condition occurs*/
        /* Therefore it we will trigger the overflow event almost immediately to ensure our toggle will be generated quickly */
        omap_dm_timer_write_counter(timer_pwm_ptr, (0xFFFFFFFF - 5));
    
        /* Setup the Load Register */
        /* Setup as autoload to set the the counter back to 0 on an overflow */
        omap_dm_timer_set_load(timer_pwm_ptr, 1, timer_reload);
    
        /* Set the the compare register to half of cycle */
        omap_dm_timer_set_match(timer_pwm_ptr, 1, timer_reload + 5);
    
        /* Start the timer */
        ret = omap_dm_timer_start(timer_pwm_ptr);
    
    
        printk(KERN_INFO "PWM timer started. CLK = %u Cycle = %u\n", \
                as_data->timer_pwm_rate, as_data->timer_pwm_clks_per_cycle);
        /*
        * A non 0 returns means the call to init_modules failed; module can't be loaded
        */
        return 0;
    }
    
  • 你好,请问后来你找到解决问题的方法了么?我现在也需要做个硬件的定时器驱动,3.2的内核。可不可以给个指导

  • 请问能不能麻烦你把链接发出来呢,我想查看完整的代码

  • hello, 你好! 有解决吗? 我用hrtimer空闲时还是准的,一旦进入高负载模式(其他的实时任务并行时),差得太离谱了,请知道的大侠指教一下。
  • hrtimer 在高负载的时候不准很正常,就是kernel中的关中断的临界区