ICU callback missed @ 5KHz?

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

ICU callback missed @ 5KHz?

Post by russian »

I believe that some of my period callbacks on ICU driver are getting dropped with a square 50% wave 5KHz signal.

Code: Select all

static void shaft_icu_width_callback(ICUDriver *icup) {
   hwHandleShaftSignal(SHAFT_PRIMARY_UP);
}

static void shaft_icu_period_callback(ICUDriver *icup) {
   hwHandleShaftSignal(SHAFT_PRIMARY_DOWN);
}

void handleShaftSignal(trigger_event_e signal) {
    isMismatch  = (curSignal == prevSignal);
   if (isMismatch)
      orderingErrorCounter++;
   prevSignal = curSignal;
   curSignal = signal;

      uint64_t nowNt = getTimeNowNt();
      curDuration = prevTime - nowNt ;
      prevTime = curDuration;
}


curDuration is usually about 17000 native ticks which is the expected value considering 100uS event period and 168 ticks per uS. More or less once per 80 wave cycles on average I am getting two consecutive icu_width_callback which are ~34000 ticks apart. This looks like a missed period callback.

I am not getting missed callbacks with a 500Hz signal. I've checked and I am not getting reentrant ICU callbacks.

What could I be doing wrong? Are there any error or status registers related to this?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ICU callback missed @ 5KHz?

Post by Giovanni »

Do you have large critical zones? that could be a reason for that. The F4 should be able to handle interrupts in the range of few uS.

Giovanni
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

Re: ICU callback missed @ 5KHz?

Post by russian »

Giovanni wrote:Do you have large critical zones? that could be a reason for that. The F4 should be able to handle interrupts in the range of few uS.

I am doing all I can to reduce the kernel lock mode zones, is that a synonym?

Are you saying that this is expected behavior that my IRQs are dropped? Can I at least know if/how many are being dropped? How do I guarantee IRQ handling since theoretically even a smallest kernel lock zone might happen at the wrong moment?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ICU callback missed @ 5KHz?

Post by Giovanni »

It is a symptom or something wrong, it could be a lock zone.

Note that IRQs are not "lost" when triggered during a critical zone, just delayed until the end of the critical zone, the only way to lose an interrupt is if the IRQ source is triggered again before the previous interrupts has been served.

Basically you need 2 instances of the same IRQ occurring during the same critical zone.

Another consequence is that it is not important to reduce the number of critical zones, you need to reduce the duration of the LARGEST one.

The ChibiOS 3.0 debug plugin is able to tell you the duration of the largest critical zone but currently is broken because changes I did in the kernel yesterday... you could use a previous SVN revision if you want to give it a try.

Giovanni
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

Re: ICU callback missed @ 5KHz?

Post by russian »

Gotcha. Let me figure out the duration of the longest kernel lock mode zone and get back to you on this.

Are you using hal_lld_get_counter_value for these measurements in 3.0? How do you handle 32 bit overflow for that register - do you track overflow & track your own 64 bit version of this counter?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: ICU callback missed @ 5KHz?

Post by Giovanni »

3.0 has a statistics subsystems that uses the RT counter, it is not important if it overflows, differences are calculated correctly even if the counter overflowed.

Giovanni
User avatar
russian
Posts: 368
Joined: Mon Oct 29, 2012 3:17 am
Has thanked: 16 times
Been thanked: 14 times

Re: ICU callback missed @ 5KHz?

Post by russian »

Giovanni wrote:Basically you need 2 instances of the same IRQ occurring during the same critical zone.

Another consequence is that it is not important to reduce the number of critical zones, you need to reduce the duration of the LARGEST one.


Looks like this was my issue exactly. I've discovered that one of my critical zones was about 32K ticks (strlen + strcpy for a 8k logging buffer), once I've changed the implementation to eliminate this things have improved. Thank you for the hint what to look at :)

I've spend some time looking what sections of my code are taking how many ticks and I was surprised that for example 'strlen' invocation for a string of just three chars costs a bit over 100 ticks. Maybe one day I will find an explanation to that - is it the cost of branching, method invocation or debugger magic around method invocation.
Post Reply