0

Is it possible to use something like a compiler directive to pad a function with do nothing instructions so that as you add lines of code or take them away it always executes in the same amount of time? I know there is the blink without delay style of writing a loop, but I want something a little more exact.

6
  • 1
    Please take the tour and read "How to Ask", then come back and provide some more bits of information, at least which compiler on which system you are using. Some background why you need this would be nice, too. Oh, and please edit your question, don't add comments, this is not a forum. -- I don't know of any compiler that has such an option; and I know several quite different compilers. Most probably you will need to code this on assembly level by hand. Mar 16, 2020 at 7:08
  • 2
    In avr-gcc you can add a single clock cycle by asm volatile ("nop"); But you cannot measure by code, how many clock cycles the controller already spent in some other ISR. Mar 16, 2020 at 10:52
  • For me that sound like you are trying to shoot sparrows with canons. Why do you need the function to always execute in the same amount of time while still changing it's code? There are other exact methods to trigger the regular execution of a function (via Timers).
    – chrisl
    Mar 16, 2020 at 14:34
  • 1
    you could just take a time snapshot up top, and another one when your code is done, then delay or while before returning, until the duration is acceptable.
    – dandavis
    Mar 17, 2020 at 18:24
  • 1
    @peterh IDK which stack exchange to ask on May 13, 2020 at 21:10

2 Answers 2

1

To the best of my knowledge, there is not. What you speak of is possible, but it must be done manually by counting cycles, and I suspect it wouldn't actually help you. (And then you get into CISC issues where instructions can take different amounts of time to execute, potentially depending on arguments. Arduino (the actual one) is kinda safe from that, but branch instructions still take multiple cycles, for instance. This says nothing about all the boards that work with, but aren't, Arduinos.)

There are two potential routes for this.

  1. If this is for crypto, where you want to avoid side-channel attacks by detecting the length of an authentication or hashing function, it's not a good idea. Use a well-known library to do it instead, since in practicality it's not a good or safe idea to write your own (although if it's for a homemade door lock or safe lock, it's probably not a relevant issue since there are larger and more important security issues that will likely be found first despite your best efforts).
  2. If, as I suspect, you simply want a piece of code to run at very precise time intervals, I suggest you look up something like the FreeRTOS port for Arduino. That will let you schedule a task to run preemptively so that it will always run at intervals. The BWOD sketch is still quite accurate, mind you, and below is a self-correcting version that compensates for any times that it might run a bit late (meaning that it should ALWAYS execute with millisecond precision, repeatably):
  unsigned long currentMillis = millis();//and you could always use micros()

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis += interval;//adjustment for additional accuracy

    //The task you want to run would go below:
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }

The caveat to your stated goal is that any microprocessor WILL NOT execute code exactly when you want. Arduino too is incapable of this, since even a blank sketch runs several interrupts that will take over the processor for short periods of time, causing your hypothetical sketch to be delayed. You HAVE to use a reference method like BWOD or a scheduler like FreeRTOS. These use a reference or set up their own interrupt to make sure that they run on time, with the only interrupts that could be an issue being the ones that run during that instance of the task.

What this means is that they have a bit of overhead to add spacing between tasks so that if one is delayed, it won't cause the next to run late. So do mind that you'll lose a quite small percentage of CPU time to your scheduler, but if that's really an issue, find a better board (like TI TIVA/Energia IDE).

0

You can use a timer with prescaler set to 1 in combination with a counter module. Attach interrupts to the compare and the overflow events. In the corresponding ISRs you handle the counting... I have no example for you and it might be a bit tricky how to implement the ISRs, but it's possible for sure, as long as you count a reasonable amount of clock cycles (firing an interrupt each cycle e.g. will not work as the calculations in the ISR take some time).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.