Speed of Interrupts (BL4S200)

Hi,

I've been working with the BL2500 for a while now, with none time-critical applications. Now I just bought a BL4S200 for a time-critical purpose. 

Situation :
I do have an encoder (on conveyor) that pulses at 10kHz and between pulses I need to do some stuff. So 1 cycle (between 2 encoder ticks) is about 100us.

Question :
How quick can the interrupt respond to an input.

Debug :
I’m trying to do a basic interrupt that does :
++i;
digOut(2, i % 2);

When receiving the Input on channel 0 (interrupt on falling edge).

With my scope, I can see that between the falling edge of the encoder and my output signal, I do have 60us ! I did several tests and the best performance I can get is 40us !!! Seems to me VERY SLOW. 40us to receive input and send output.

Am I missing something here ?

Problem :
As I said, my cycles are 100us, and during them I configured the RIO’s registers in “double-buffering” so I can generate kind of homemade PWM… But if the interrupt to start the sequence use 40us, I lose like half my cycle :s

Thanks,

-Yannick.

1 Like

There are a few of things to note here:

  1. defining the macro BL_LIMIT_ERRORS will remove checking code from digOut() which will speed things a bit.
  2. digOut is a wrapper around _riosbc_set_pin() so calling the function directly will remove another layer of delay
  3. _riosbc_set_pin has a certain amount of overhead which will add to the delays.
  4. i % 2 might be better written as i & 1 (I’d look at the listing file to see if it produces better code)

If I was looking to get the maximum performance for this interrupt, I’d deconstruct the riosbc_set_pin code and use only the essentials in your ISR.

Regards,
Peter

Hi petermcs,

 [s]Yeah, first things first. I'll try to optimise my interrupt, I know that the code I put in there was far from being optimised but 40us really ?! When I saw that number, I didn't even consider optimising the few calls to win 5us... I was thinking more of optimising a flag, a priority or something to cut that time by alot, otherwise I'm screwed :p[/s]

But I’ll check what I get by optimising those calls, I’ll post the timing this afternoon.

As I expected, I can save few us by having :

root interrupt void EncoderTick()
{
   // Start Cycle !
   _riosbc_set_pin(pPINInternalOut, iCounter & 1);

   ++iCounter;

   // Reset Interrupt.
   RSB_CLEAR_ALL_IRQ(Interrupt_EncoderTick);
}

So even if a deconstruct the _riosbc_set_pin(), I may still save 4-5 us, but i’ll still be about 40us (I was something like 48, now i’m like 42)…

Thanks for your suggestions.

-Yannick.

Hi Yannick,

Looking at the RIO lib there is quite a bit happens before your interrupt service routine gets called. This is because the library is a very general purpose lib and provides a general mechanism for setting up and controlling the interrupt sources for the RIO.

The current code has various tables and loops through them which adds a lot of overhead and also means that the number and order of interrupt handlers etc will alter the timings.

If you have a very small number of interrupts to set up for your application, it would probably make sense to replace the ISR handling with a more tailored version which does not check for all the interrupts that can theoretically (sp?) happen and allow dynamic setting of interrupt handlers etc.

Regards,
Peter

Hi Petermcs,

This interrupt will, I believe, be the only one… Lots of thing will be happening but I don’t need them to interrupt the system, the only one is that one. Which is very critical.

Do you think that rewritting the ISR handling could save me like 30us ?! I need something about 10us.

Thanks again,

-Yannick.

Hi Yannick,

I would think so. You could get some idea of the timing from interrupt trigger to actual selection of your ISR by putting some code into the existing ISR to toggle an I/O pin and chscking with the scope.

From what I can see with a quick look, the _riobc_init routine installs the actual ISR which is triggered by any RIO interrupt. This ISR then uses the table of ISR handlers to match potential interrupts to their service routine. If you replace this code with something simpler you should be able to get much faster response times.

You will need to check to see if there are any other libraries in the BL4S200 that use the RIO interrupts to be on the safe side.

Regards,
Peter