1

I have made a simple program using the int main() {} function. It has a delay in it. It is evident the code before the delay is running, but the delay never seems to time out and let the next instructions through. Is this by design?

If I rename the method and call it exactly once from the loop() {} function though, it does work.

Edit:

The code borrowed the 'main()' function and I suppose redefined it:

int main() { 
    Forward();
    delay(3000);
    Reverse();
}

void Forward() {
    //...
}

void Reverse() {
    //... 
}

I can see this redefinition of main() could cause some serious issues based on the answer below.

  • 3
    We would need to see the code in question in order to give a full answer. – Ignacio Vazquez-Abrams Mar 24 '14 at 22:19
  • 2
    main() suggest this isn't normal Arduino. – Cybergibbons Mar 24 '14 at 22:39
  • 1
    Arduino programs don't use main, they use loop – TheDoctor Mar 25 '14 at 0:19
  • What value for delay are you using? delay(999999999999999999999999999999999999999999999999); will cause a fairly large problem (if the variable even is that big). | @Cyber It must be another language/bare C. It's weird that it compiled... – Anonymous Penguin Mar 25 '14 at 0:24
  • First, no, delay can't deadlock, because there are no threads to deadlock on the Arduino. Second, you wouldn't be able to build a sketch containing a redefinition of main (and you don't sound experienced enough to bypass the IDE). Show the simplest code that reproduces the problem. I'm guessing the problem will be very obvious to readers here. – Mud Mar 25 '14 at 4:10
7

You don't seem to use standard Arduino stuff since you defined your own main() which is normally avoided when programming Arduino.

If you take a look at Arduino provided main() (in hardware/cores/arduino/main.cpp), you'll see how it is defined:

#include <Arduino.h>

int main(void)
{
    init();

#if defined(USBCON)
    USBDevice.attach();
#endif

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }

    return 0;
}

Did you notice the init() function call at the beginning?

Its code is defined in hardware/cores/arduino/wiring.c; what it does is setup all timers used by Arduino functions, in particular a timer that is needed by delay().

In the same wiring.c file, you can also find the definition of delay():

void delay(unsigned long ms)
{
    uint16_t start = (uint16_t)micros();

    while (ms > 0) {
        if (((uint16_t)micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

This will turn into an infinite loop if micros() always return the same value, and it does so if init() has never been called before.

This is what happens with your code.

  • This means delay(); won't work with interrupts disabled. – jippie Mar 25 '14 at 6:16
  • @jippie yes, that's why you should never call it from an ISR or a function that has disabled interrupts. – jfpoilpret Mar 25 '14 at 6:17
  • Cheers jfpoilpret, I was actually surprised when I borrowed the name main and found it was recognised same as with general c programs so I ran with it, since, I only wanted this instruction run once anyway. Your answer has given a good hint as to the architecture and I'll be able to work from there. Apologies for taking such a hack approach..! – J Collins Mar 25 '14 at 9:51
  • @JCollins no need to apologize, hacking is part of learning and experience eventually :-) Glad you can proceed from here. – jfpoilpret Mar 25 '14 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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