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.

hrtimer problem, AM3517EVM



Hello,

I have a question about hrtimer. I have tried to find answers by search but with no luck.

I took an example from IBM forum (listing below).

It works partially.

When I have HRTIMER_NORESTART, it fires once after 10 seconds, so, everythings can not be wrong. jiffies in init_module and my_hrtimer_callback are different.

When I have HRTIMER_RESTART, it fires first time after 10 seconds. But after that, it fires constantly (that is not after ten seconds again but in milliseconds or microseconds, so very quickly). jiffies in init_module and first my_hrtimer_callback are different, but after that jiffies does not change.

Card is AM3517EVM.


I use AM35x-OMAP35x-PSP-SDK-03.00.00.05, both image and rootfs are from there. In kernel I have high resolution timer support on. Compiler is newest CodeSourcery Lite.

What goes wrong?

Yours truly Antti


module source:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>

MODULE_LICENSE("GPL");

#define MS_TO_NS(x)    (x * 1E6L)

static struct hrtimer hr_timer;

enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
{
  printk( "my_hrtimer_callback called (%ld).\n", jiffies );

  return HRTIMER_RESTART;    //now, trying restart once per 10 seconds
//  return HRTIMER_NORESTART; //original
}

int init_module( void )
{
  ktime_t ktime;
  unsigned long delay_in_ms = 200L;

  printk("HR Timer module installing\n");

//  ktime = ktime_set( 0, MS_TO_NS(delay_in_ms) ); //original
  ktime = ktime_set( 10, 0 );   / /now once per 10 seconds

  hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
 
  hr_timer.function = &my_hrtimer_callback;

  printk( "Starting timer to fire in %ldms (%ld)\n", delay_in_ms, jiffies );

  hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );

  return 0;
}

void cleanup_module( void )
{
  int ret;

  ret = hrtimer_cancel( &hr_timer );
  if (ret) printk("The timer was still in use...\n");

  printk("HR Timer module uninstalling\n");

  return;
}

  • Hello,

    answering to myself. Changed callback to:

     

    enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
    {
          printk( "my_hrtimer_callback called (%ld).\n", jiffies );
          hrtimer_start(timer, ktime_set(1, 0), HRTIMER_MODE_REL);
          return HRTIMER_NORESTART;
    }

    This seems to work. Is this the right way to do this?

    Antti

  • (I haven't tried your example)

    In my understanding, callback must set new expiration before leaving.

    I also see you returning HRTIMER_NORESTART. Have you tried changing it to HRTIMER_RESTART? Does it make any difference?

    You can also look at hrtimer_forward(). It sets expiry after now.