What's the maximum time an interrupt service routine can take to execute on atmega328p?Interrupt Service Routine in C - function at specific addressAVR interrupt service routine not executing as fast as expected (instruction overhead?)Use PWM and ISR at same time on AVRAVR ISR causes unexpected behaviorWhat's the difference between all of the Atmega328p clocking options?how to use interrupt service routine without interrupt.h file in avr?Questions for a personal LED/ATmega328P-PU projectPIC32 GPIO pins Hardware Abstraction Layer questionwill For loop in MikroC for dspic block the interrupt service routine?Atmega328p - Program works with 2.7V power supply but doesnt with 3.3V

What explains 9 speed cassettes price differences?

Book where the stars go black due to aliens stopping human observation collapsing quantum possibilities

How would my creatures handle groups without a strong concept of numbers?

Parse source code of the RAPID robot-automation language

Single word for "refusing to move to next activity unless present one is completed."

Managing and organizing the massively increased number of classes after switching to SOLID?

Was the Ford Model T black because of the speed black paint dries?

Can I play a first turn Simic Growth Chamber to have 3 mana available in the second turn?

Is "take care'n of" correct?

How did the hit man miss?

The monorail explodes before I can get on it

During copyediting, journal disagrees about spelling of paper's main topic

Robbers: The Hidden OEIS Substring

A pyramid from a square

Why isn't there research to build a standard lunar, or Martian mobility platform?

How can an advanced civilization forget how to manufacture its technology?

For a hashing function like MD5, how similar can two plaintext strings be and still generate the same hash?

How to tell someone I'd like to become friends without causing them to think I'm romantically interested in them?

Is there a word for a message that is intended to be intercepted by an adversary?

Why was hardware diversification an asset for the IBM PC ecosystem?

Can fluent English speakers distinguish “steel”, “still” and “steal”?

Who has taken "my" Managed package namespace? Can we find out?

Why do people keep referring to Leia as Princess Leia, even after the destruction of Alderaan?

How to know whether a Tamron lens is compatible with Canon EOS 60D?



What's the maximum time an interrupt service routine can take to execute on atmega328p?


Interrupt Service Routine in C - function at specific addressAVR interrupt service routine not executing as fast as expected (instruction overhead?)Use PWM and ISR at same time on AVRAVR ISR causes unexpected behaviorWhat's the difference between all of the Atmega328p clocking options?how to use interrupt service routine without interrupt.h file in avr?Questions for a personal LED/ATmega328P-PU projectPIC32 GPIO pins Hardware Abstraction Layer questionwill For loop in MikroC for dspic block the interrupt service routine?Atmega328p - Program works with 2.7V power supply but doesnt with 3.3V






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2












$begingroup$


I have an atmega328p that checks if a button was pressed via pin change interrupts. Now, I want to turn on an led for 200ms.
Can i just turn the led on, wait 200ms and turn it back off in the ISR like so?



ISR(PCINT1_vect)

if(PINB & 0b1)

PORT = 0b10;
_delay_ms(200);
PORT = 0;




In a few forum posts on AVRfreaks, I've read that you shouldn't spend much time in an ISR, but I've never seen any exact numbers. I sadly can't find those posts anymore, so I cant link them. As far as I can remember, they all said, that if you spent to much time in the ISR, the µC might crash.
Is that true? And if so, is there an exact time limit after that this might happen?










share|improve this question







New contributor



thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$


















    2












    $begingroup$


    I have an atmega328p that checks if a button was pressed via pin change interrupts. Now, I want to turn on an led for 200ms.
    Can i just turn the led on, wait 200ms and turn it back off in the ISR like so?



    ISR(PCINT1_vect)

    if(PINB & 0b1)

    PORT = 0b10;
    _delay_ms(200);
    PORT = 0;




    In a few forum posts on AVRfreaks, I've read that you shouldn't spend much time in an ISR, but I've never seen any exact numbers. I sadly can't find those posts anymore, so I cant link them. As far as I can remember, they all said, that if you spent to much time in the ISR, the µC might crash.
    Is that true? And if so, is there an exact time limit after that this might happen?










    share|improve this question







    New contributor



    thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






    $endgroup$














      2












      2








      2





      $begingroup$


      I have an atmega328p that checks if a button was pressed via pin change interrupts. Now, I want to turn on an led for 200ms.
      Can i just turn the led on, wait 200ms and turn it back off in the ISR like so?



      ISR(PCINT1_vect)

      if(PINB & 0b1)

      PORT = 0b10;
      _delay_ms(200);
      PORT = 0;




      In a few forum posts on AVRfreaks, I've read that you shouldn't spend much time in an ISR, but I've never seen any exact numbers. I sadly can't find those posts anymore, so I cant link them. As far as I can remember, they all said, that if you spent to much time in the ISR, the µC might crash.
      Is that true? And if so, is there an exact time limit after that this might happen?










      share|improve this question







      New contributor



      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      $endgroup$




      I have an atmega328p that checks if a button was pressed via pin change interrupts. Now, I want to turn on an led for 200ms.
      Can i just turn the led on, wait 200ms and turn it back off in the ISR like so?



      ISR(PCINT1_vect)

      if(PINB & 0b1)

      PORT = 0b10;
      _delay_ms(200);
      PORT = 0;




      In a few forum posts on AVRfreaks, I've read that you shouldn't spend much time in an ISR, but I've never seen any exact numbers. I sadly can't find those posts anymore, so I cant link them. As far as I can remember, they all said, that if you spent to much time in the ISR, the µC might crash.
      Is that true? And if so, is there an exact time limit after that this might happen?







      microcontroller avr atmega atmega328p






      share|improve this question







      New contributor



      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.










      share|improve this question







      New contributor



      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      share|improve this question




      share|improve this question






      New contributor



      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.








      asked 9 hours ago









      thebear8thebear8

      132 bronze badges




      132 bronze badges




      New contributor



      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.




      New contributor




      thebear8 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          4 Answers
          4






          active

          oldest

          votes


















          9












          $begingroup$

          If nothing else is running in the MCU, then you are free to take as long as you like in the ISR. BUT, this is a bad habit to get into, and it means that if you want to do anything else, you'll likely have to rework the code.



          A particular case is if the MCU is using a serial library, that expects interrupts to be working often enough to service individual characters received. At 115200 baud (a high serial speed often used to minimise download time), there is less than 100uS between characters. If you block the interrupts for longer than that, you risk losing input characters.



          As a general rule, do the absolute minimum in an ISR. In your application, a reasonable design would be to have an interrupt every mS, which increments and checks a counter value. I'm sure you can work out some suitable logic to set and test the counter to get 200mS between turn on and turn off events.






          share|improve this answer









          $endgroup$




















            4












            $begingroup$

            While the practice is to allocate the minimum possible execution cycles inside an interruption, and beside other general hardware specifications, there are not technical limitations for increasing them, if there are not any other interruption to be executed.



            At attachInterrupt() Arduino Reference:




            Generally, an ISR should be as short and fast as possible. If your
            sketch uses multiple ISRs, only one can run at a time, other
            interrupts will be executed after the current one finishes in an order
            that depends on the priority they have. millis() relies on interrupts
            to count, so it will never increment inside an ISR. Since delay()
            requires interrupts to work, it will not work if called inside an ISR.
            micros() works initially but will start behaving erratically after 1-2
            ms. delayMicroseconds() does not use any counter, so it will work as
            normal.




            Having 25 possible interruptions in this processor family, it is encouraged to deal with them like punctual events, for allowing other interruptions to happen.






            share|improve this answer











            $endgroup$








            • 1




              $begingroup$
              While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
              $endgroup$
              – Chris Stratton
              8 hours ago



















            2












            $begingroup$

            In the worst case, an ISR can run until the next interrupt of the same type occurs again.



            But in general, it's poor design practice to spend more time in an ISR than absolutely necessary, because it prevents all other code from running at all. This is a big issue for anything other than trivial programs.






            share|improve this answer









            $endgroup$




















              0












              $begingroup$

              You have a single-core, single-threaded CPU. This means that at any given time, it's doing exactly one thing. If your application requires it to do several things, then the code has to be designed to switch between all of them. This can be as trivial or as complex as you like.



              Normally, the CPU putters around the main loop, doing whatever is in there, and that's all well and good until an interrupt occurs. The interrupt hardware basically forces a function call to the appropriate ISR, even though there's no call instruction for it in the main loop. This unpredictability is where most of the rules come from for writing ISR's.



              Whatever time you spend in an ISR is time that the main loop is paused, waiting for the ISR to return. If the main loop is the only one to reset an active watchdog timer (very good practice), then the watchdog will not be reset during that time. If the watchdog times out, it gives you a hard reset. Just like the external reset, but with different flags that you can check on startup. This is probably the "crash" that you heard of.




              It's very good practice to use the watchdog, and to only reset it once each trip around the main loop. This forces you to write code that stays responsive. If you need to wait for something, you can set up an event (timer finished, next character received, etc.), and move on. Check periodically for that event or set another interrupt for its completion, and get back to it then. Meanwhile, you continue with whatever else you were doing.



              My main structure is typically something like this:



              #include "module1.h"
              #include "module2.h"

              void main(void)

              //overall
              //chip
              //setup

              mod1_init();
              mod2_init();

              //clear interrupt flags
              //global interrupt enable

              while(1)

              //clear watchdog

              mod1_run();
              mod2_run();




              And my modules are like this:



              void modX_init(void)

              //hardware and variable init for this module only
              //don't use interrupts if polling is good enough


              void modX_run(void)

              if (POLLED_INTERRUPT_FLAG)

              POLLED_INTERRUPT_FLAG = 0;

              //non-blocking "ISR" code



              void ISR modX_ISR(void)

              //okay, this does require an *immediate* response
              //spend the absolute minimum time here and get out



              The function signatures don't have to be void, but most of them are. Sometimes I'll have some broad timing in one module that is also used by another, and it's handy to use the return value of one modX_run() and the arguments of another (or some basic logic) to make that connection. For example:



              if (DMX_run()) //includes its own timing, and returns true at the start of each 30Hz interval, otherwise false

              I2C_start(); //I2C frames are sync'ed to DMX

              I2C_run(); //once started, an I2C frame runs freely until finished



              If you study the datasheet, you may also find that the hardware peripherals can be massaged to do what you want without any CPU intervention at all.



              Output pulse generation, for example, is a common one. Turn it on, set the peripheral to turn it off some time later, and forget about it. It's typically in the same general area as PWM.






              share|improve this answer









              $endgroup$















                Your Answer






                StackExchange.ifUsing("editor", function ()
                return StackExchange.using("schematics", function ()
                StackExchange.schematics.init();
                );
                , "cicuitlab");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "135"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: false,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: null,
                bindNavPrevention: true,
                postfix: "",
                imageUploader:
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                ,
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );






                thebear8 is a new contributor. Be nice, and check out our Code of Conduct.









                draft saved

                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f447850%2fwhats-the-maximum-time-an-interrupt-service-routine-can-take-to-execute-on-atme%23new-answer', 'question_page');

                );

                Post as a guest















                Required, but never shown

























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                9












                $begingroup$

                If nothing else is running in the MCU, then you are free to take as long as you like in the ISR. BUT, this is a bad habit to get into, and it means that if you want to do anything else, you'll likely have to rework the code.



                A particular case is if the MCU is using a serial library, that expects interrupts to be working often enough to service individual characters received. At 115200 baud (a high serial speed often used to minimise download time), there is less than 100uS between characters. If you block the interrupts for longer than that, you risk losing input characters.



                As a general rule, do the absolute minimum in an ISR. In your application, a reasonable design would be to have an interrupt every mS, which increments and checks a counter value. I'm sure you can work out some suitable logic to set and test the counter to get 200mS between turn on and turn off events.






                share|improve this answer









                $endgroup$

















                  9












                  $begingroup$

                  If nothing else is running in the MCU, then you are free to take as long as you like in the ISR. BUT, this is a bad habit to get into, and it means that if you want to do anything else, you'll likely have to rework the code.



                  A particular case is if the MCU is using a serial library, that expects interrupts to be working often enough to service individual characters received. At 115200 baud (a high serial speed often used to minimise download time), there is less than 100uS between characters. If you block the interrupts for longer than that, you risk losing input characters.



                  As a general rule, do the absolute minimum in an ISR. In your application, a reasonable design would be to have an interrupt every mS, which increments and checks a counter value. I'm sure you can work out some suitable logic to set and test the counter to get 200mS between turn on and turn off events.






                  share|improve this answer









                  $endgroup$















                    9












                    9








                    9





                    $begingroup$

                    If nothing else is running in the MCU, then you are free to take as long as you like in the ISR. BUT, this is a bad habit to get into, and it means that if you want to do anything else, you'll likely have to rework the code.



                    A particular case is if the MCU is using a serial library, that expects interrupts to be working often enough to service individual characters received. At 115200 baud (a high serial speed often used to minimise download time), there is less than 100uS between characters. If you block the interrupts for longer than that, you risk losing input characters.



                    As a general rule, do the absolute minimum in an ISR. In your application, a reasonable design would be to have an interrupt every mS, which increments and checks a counter value. I'm sure you can work out some suitable logic to set and test the counter to get 200mS between turn on and turn off events.






                    share|improve this answer









                    $endgroup$



                    If nothing else is running in the MCU, then you are free to take as long as you like in the ISR. BUT, this is a bad habit to get into, and it means that if you want to do anything else, you'll likely have to rework the code.



                    A particular case is if the MCU is using a serial library, that expects interrupts to be working often enough to service individual characters received. At 115200 baud (a high serial speed often used to minimise download time), there is less than 100uS between characters. If you block the interrupts for longer than that, you risk losing input characters.



                    As a general rule, do the absolute minimum in an ISR. In your application, a reasonable design would be to have an interrupt every mS, which increments and checks a counter value. I'm sure you can work out some suitable logic to set and test the counter to get 200mS between turn on and turn off events.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 9 hours ago









                    Neil_UKNeil_UK

                    83.2k2 gold badges85 silver badges192 bronze badges




                    83.2k2 gold badges85 silver badges192 bronze badges























                        4












                        $begingroup$

                        While the practice is to allocate the minimum possible execution cycles inside an interruption, and beside other general hardware specifications, there are not technical limitations for increasing them, if there are not any other interruption to be executed.



                        At attachInterrupt() Arduino Reference:




                        Generally, an ISR should be as short and fast as possible. If your
                        sketch uses multiple ISRs, only one can run at a time, other
                        interrupts will be executed after the current one finishes in an order
                        that depends on the priority they have. millis() relies on interrupts
                        to count, so it will never increment inside an ISR. Since delay()
                        requires interrupts to work, it will not work if called inside an ISR.
                        micros() works initially but will start behaving erratically after 1-2
                        ms. delayMicroseconds() does not use any counter, so it will work as
                        normal.




                        Having 25 possible interruptions in this processor family, it is encouraged to deal with them like punctual events, for allowing other interruptions to happen.






                        share|improve this answer











                        $endgroup$








                        • 1




                          $begingroup$
                          While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                          $endgroup$
                          – Chris Stratton
                          8 hours ago
















                        4












                        $begingroup$

                        While the practice is to allocate the minimum possible execution cycles inside an interruption, and beside other general hardware specifications, there are not technical limitations for increasing them, if there are not any other interruption to be executed.



                        At attachInterrupt() Arduino Reference:




                        Generally, an ISR should be as short and fast as possible. If your
                        sketch uses multiple ISRs, only one can run at a time, other
                        interrupts will be executed after the current one finishes in an order
                        that depends on the priority they have. millis() relies on interrupts
                        to count, so it will never increment inside an ISR. Since delay()
                        requires interrupts to work, it will not work if called inside an ISR.
                        micros() works initially but will start behaving erratically after 1-2
                        ms. delayMicroseconds() does not use any counter, so it will work as
                        normal.




                        Having 25 possible interruptions in this processor family, it is encouraged to deal with them like punctual events, for allowing other interruptions to happen.






                        share|improve this answer











                        $endgroup$








                        • 1




                          $begingroup$
                          While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                          $endgroup$
                          – Chris Stratton
                          8 hours ago














                        4












                        4








                        4





                        $begingroup$

                        While the practice is to allocate the minimum possible execution cycles inside an interruption, and beside other general hardware specifications, there are not technical limitations for increasing them, if there are not any other interruption to be executed.



                        At attachInterrupt() Arduino Reference:




                        Generally, an ISR should be as short and fast as possible. If your
                        sketch uses multiple ISRs, only one can run at a time, other
                        interrupts will be executed after the current one finishes in an order
                        that depends on the priority they have. millis() relies on interrupts
                        to count, so it will never increment inside an ISR. Since delay()
                        requires interrupts to work, it will not work if called inside an ISR.
                        micros() works initially but will start behaving erratically after 1-2
                        ms. delayMicroseconds() does not use any counter, so it will work as
                        normal.




                        Having 25 possible interruptions in this processor family, it is encouraged to deal with them like punctual events, for allowing other interruptions to happen.






                        share|improve this answer











                        $endgroup$



                        While the practice is to allocate the minimum possible execution cycles inside an interruption, and beside other general hardware specifications, there are not technical limitations for increasing them, if there are not any other interruption to be executed.



                        At attachInterrupt() Arduino Reference:




                        Generally, an ISR should be as short and fast as possible. If your
                        sketch uses multiple ISRs, only one can run at a time, other
                        interrupts will be executed after the current one finishes in an order
                        that depends on the priority they have. millis() relies on interrupts
                        to count, so it will never increment inside an ISR. Since delay()
                        requires interrupts to work, it will not work if called inside an ISR.
                        micros() works initially but will start behaving erratically after 1-2
                        ms. delayMicroseconds() does not use any counter, so it will work as
                        normal.




                        Having 25 possible interruptions in this processor family, it is encouraged to deal with them like punctual events, for allowing other interruptions to happen.







                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited 9 hours ago

























                        answered 9 hours ago









                        BrethloszeBrethlosze

                        4962 silver badges17 bronze badges




                        4962 silver badges17 bronze badges







                        • 1




                          $begingroup$
                          While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                          $endgroup$
                          – Chris Stratton
                          8 hours ago













                        • 1




                          $begingroup$
                          While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                          $endgroup$
                          – Chris Stratton
                          8 hours ago








                        1




                        1




                        $begingroup$
                        While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                        $endgroup$
                        – Chris Stratton
                        8 hours ago





                        $begingroup$
                        While delay in an ISR is generally a bad idea, the question uses what appears to be avr-gcc's _delay_ms() which is cycles based unlike the Arduino delay() function which relies on the timer interrupt.
                        $endgroup$
                        – Chris Stratton
                        8 hours ago












                        2












                        $begingroup$

                        In the worst case, an ISR can run until the next interrupt of the same type occurs again.



                        But in general, it's poor design practice to spend more time in an ISR than absolutely necessary, because it prevents all other code from running at all. This is a big issue for anything other than trivial programs.






                        share|improve this answer









                        $endgroup$

















                          2












                          $begingroup$

                          In the worst case, an ISR can run until the next interrupt of the same type occurs again.



                          But in general, it's poor design practice to spend more time in an ISR than absolutely necessary, because it prevents all other code from running at all. This is a big issue for anything other than trivial programs.






                          share|improve this answer









                          $endgroup$















                            2












                            2








                            2





                            $begingroup$

                            In the worst case, an ISR can run until the next interrupt of the same type occurs again.



                            But in general, it's poor design practice to spend more time in an ISR than absolutely necessary, because it prevents all other code from running at all. This is a big issue for anything other than trivial programs.






                            share|improve this answer









                            $endgroup$



                            In the worst case, an ISR can run until the next interrupt of the same type occurs again.



                            But in general, it's poor design practice to spend more time in an ISR than absolutely necessary, because it prevents all other code from running at all. This is a big issue for anything other than trivial programs.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 9 hours ago









                            Dave TweedDave Tweed

                            130k10 gold badges164 silver badges278 bronze badges




                            130k10 gold badges164 silver badges278 bronze badges





















                                0












                                $begingroup$

                                You have a single-core, single-threaded CPU. This means that at any given time, it's doing exactly one thing. If your application requires it to do several things, then the code has to be designed to switch between all of them. This can be as trivial or as complex as you like.



                                Normally, the CPU putters around the main loop, doing whatever is in there, and that's all well and good until an interrupt occurs. The interrupt hardware basically forces a function call to the appropriate ISR, even though there's no call instruction for it in the main loop. This unpredictability is where most of the rules come from for writing ISR's.



                                Whatever time you spend in an ISR is time that the main loop is paused, waiting for the ISR to return. If the main loop is the only one to reset an active watchdog timer (very good practice), then the watchdog will not be reset during that time. If the watchdog times out, it gives you a hard reset. Just like the external reset, but with different flags that you can check on startup. This is probably the "crash" that you heard of.




                                It's very good practice to use the watchdog, and to only reset it once each trip around the main loop. This forces you to write code that stays responsive. If you need to wait for something, you can set up an event (timer finished, next character received, etc.), and move on. Check periodically for that event or set another interrupt for its completion, and get back to it then. Meanwhile, you continue with whatever else you were doing.



                                My main structure is typically something like this:



                                #include "module1.h"
                                #include "module2.h"

                                void main(void)

                                //overall
                                //chip
                                //setup

                                mod1_init();
                                mod2_init();

                                //clear interrupt flags
                                //global interrupt enable

                                while(1)

                                //clear watchdog

                                mod1_run();
                                mod2_run();




                                And my modules are like this:



                                void modX_init(void)

                                //hardware and variable init for this module only
                                //don't use interrupts if polling is good enough


                                void modX_run(void)

                                if (POLLED_INTERRUPT_FLAG)

                                POLLED_INTERRUPT_FLAG = 0;

                                //non-blocking "ISR" code



                                void ISR modX_ISR(void)

                                //okay, this does require an *immediate* response
                                //spend the absolute minimum time here and get out



                                The function signatures don't have to be void, but most of them are. Sometimes I'll have some broad timing in one module that is also used by another, and it's handy to use the return value of one modX_run() and the arguments of another (or some basic logic) to make that connection. For example:



                                if (DMX_run()) //includes its own timing, and returns true at the start of each 30Hz interval, otherwise false

                                I2C_start(); //I2C frames are sync'ed to DMX

                                I2C_run(); //once started, an I2C frame runs freely until finished



                                If you study the datasheet, you may also find that the hardware peripherals can be massaged to do what you want without any CPU intervention at all.



                                Output pulse generation, for example, is a common one. Turn it on, set the peripheral to turn it off some time later, and forget about it. It's typically in the same general area as PWM.






                                share|improve this answer









                                $endgroup$

















                                  0












                                  $begingroup$

                                  You have a single-core, single-threaded CPU. This means that at any given time, it's doing exactly one thing. If your application requires it to do several things, then the code has to be designed to switch between all of them. This can be as trivial or as complex as you like.



                                  Normally, the CPU putters around the main loop, doing whatever is in there, and that's all well and good until an interrupt occurs. The interrupt hardware basically forces a function call to the appropriate ISR, even though there's no call instruction for it in the main loop. This unpredictability is where most of the rules come from for writing ISR's.



                                  Whatever time you spend in an ISR is time that the main loop is paused, waiting for the ISR to return. If the main loop is the only one to reset an active watchdog timer (very good practice), then the watchdog will not be reset during that time. If the watchdog times out, it gives you a hard reset. Just like the external reset, but with different flags that you can check on startup. This is probably the "crash" that you heard of.




                                  It's very good practice to use the watchdog, and to only reset it once each trip around the main loop. This forces you to write code that stays responsive. If you need to wait for something, you can set up an event (timer finished, next character received, etc.), and move on. Check periodically for that event or set another interrupt for its completion, and get back to it then. Meanwhile, you continue with whatever else you were doing.



                                  My main structure is typically something like this:



                                  #include "module1.h"
                                  #include "module2.h"

                                  void main(void)

                                  //overall
                                  //chip
                                  //setup

                                  mod1_init();
                                  mod2_init();

                                  //clear interrupt flags
                                  //global interrupt enable

                                  while(1)

                                  //clear watchdog

                                  mod1_run();
                                  mod2_run();




                                  And my modules are like this:



                                  void modX_init(void)

                                  //hardware and variable init for this module only
                                  //don't use interrupts if polling is good enough


                                  void modX_run(void)

                                  if (POLLED_INTERRUPT_FLAG)

                                  POLLED_INTERRUPT_FLAG = 0;

                                  //non-blocking "ISR" code



                                  void ISR modX_ISR(void)

                                  //okay, this does require an *immediate* response
                                  //spend the absolute minimum time here and get out



                                  The function signatures don't have to be void, but most of them are. Sometimes I'll have some broad timing in one module that is also used by another, and it's handy to use the return value of one modX_run() and the arguments of another (or some basic logic) to make that connection. For example:



                                  if (DMX_run()) //includes its own timing, and returns true at the start of each 30Hz interval, otherwise false

                                  I2C_start(); //I2C frames are sync'ed to DMX

                                  I2C_run(); //once started, an I2C frame runs freely until finished



                                  If you study the datasheet, you may also find that the hardware peripherals can be massaged to do what you want without any CPU intervention at all.



                                  Output pulse generation, for example, is a common one. Turn it on, set the peripheral to turn it off some time later, and forget about it. It's typically in the same general area as PWM.






                                  share|improve this answer









                                  $endgroup$















                                    0












                                    0








                                    0





                                    $begingroup$

                                    You have a single-core, single-threaded CPU. This means that at any given time, it's doing exactly one thing. If your application requires it to do several things, then the code has to be designed to switch between all of them. This can be as trivial or as complex as you like.



                                    Normally, the CPU putters around the main loop, doing whatever is in there, and that's all well and good until an interrupt occurs. The interrupt hardware basically forces a function call to the appropriate ISR, even though there's no call instruction for it in the main loop. This unpredictability is where most of the rules come from for writing ISR's.



                                    Whatever time you spend in an ISR is time that the main loop is paused, waiting for the ISR to return. If the main loop is the only one to reset an active watchdog timer (very good practice), then the watchdog will not be reset during that time. If the watchdog times out, it gives you a hard reset. Just like the external reset, but with different flags that you can check on startup. This is probably the "crash" that you heard of.




                                    It's very good practice to use the watchdog, and to only reset it once each trip around the main loop. This forces you to write code that stays responsive. If you need to wait for something, you can set up an event (timer finished, next character received, etc.), and move on. Check periodically for that event or set another interrupt for its completion, and get back to it then. Meanwhile, you continue with whatever else you were doing.



                                    My main structure is typically something like this:



                                    #include "module1.h"
                                    #include "module2.h"

                                    void main(void)

                                    //overall
                                    //chip
                                    //setup

                                    mod1_init();
                                    mod2_init();

                                    //clear interrupt flags
                                    //global interrupt enable

                                    while(1)

                                    //clear watchdog

                                    mod1_run();
                                    mod2_run();




                                    And my modules are like this:



                                    void modX_init(void)

                                    //hardware and variable init for this module only
                                    //don't use interrupts if polling is good enough


                                    void modX_run(void)

                                    if (POLLED_INTERRUPT_FLAG)

                                    POLLED_INTERRUPT_FLAG = 0;

                                    //non-blocking "ISR" code



                                    void ISR modX_ISR(void)

                                    //okay, this does require an *immediate* response
                                    //spend the absolute minimum time here and get out



                                    The function signatures don't have to be void, but most of them are. Sometimes I'll have some broad timing in one module that is also used by another, and it's handy to use the return value of one modX_run() and the arguments of another (or some basic logic) to make that connection. For example:



                                    if (DMX_run()) //includes its own timing, and returns true at the start of each 30Hz interval, otherwise false

                                    I2C_start(); //I2C frames are sync'ed to DMX

                                    I2C_run(); //once started, an I2C frame runs freely until finished



                                    If you study the datasheet, you may also find that the hardware peripherals can be massaged to do what you want without any CPU intervention at all.



                                    Output pulse generation, for example, is a common one. Turn it on, set the peripheral to turn it off some time later, and forget about it. It's typically in the same general area as PWM.






                                    share|improve this answer









                                    $endgroup$



                                    You have a single-core, single-threaded CPU. This means that at any given time, it's doing exactly one thing. If your application requires it to do several things, then the code has to be designed to switch between all of them. This can be as trivial or as complex as you like.



                                    Normally, the CPU putters around the main loop, doing whatever is in there, and that's all well and good until an interrupt occurs. The interrupt hardware basically forces a function call to the appropriate ISR, even though there's no call instruction for it in the main loop. This unpredictability is where most of the rules come from for writing ISR's.



                                    Whatever time you spend in an ISR is time that the main loop is paused, waiting for the ISR to return. If the main loop is the only one to reset an active watchdog timer (very good practice), then the watchdog will not be reset during that time. If the watchdog times out, it gives you a hard reset. Just like the external reset, but with different flags that you can check on startup. This is probably the "crash" that you heard of.




                                    It's very good practice to use the watchdog, and to only reset it once each trip around the main loop. This forces you to write code that stays responsive. If you need to wait for something, you can set up an event (timer finished, next character received, etc.), and move on. Check periodically for that event or set another interrupt for its completion, and get back to it then. Meanwhile, you continue with whatever else you were doing.



                                    My main structure is typically something like this:



                                    #include "module1.h"
                                    #include "module2.h"

                                    void main(void)

                                    //overall
                                    //chip
                                    //setup

                                    mod1_init();
                                    mod2_init();

                                    //clear interrupt flags
                                    //global interrupt enable

                                    while(1)

                                    //clear watchdog

                                    mod1_run();
                                    mod2_run();




                                    And my modules are like this:



                                    void modX_init(void)

                                    //hardware and variable init for this module only
                                    //don't use interrupts if polling is good enough


                                    void modX_run(void)

                                    if (POLLED_INTERRUPT_FLAG)

                                    POLLED_INTERRUPT_FLAG = 0;

                                    //non-blocking "ISR" code



                                    void ISR modX_ISR(void)

                                    //okay, this does require an *immediate* response
                                    //spend the absolute minimum time here and get out



                                    The function signatures don't have to be void, but most of them are. Sometimes I'll have some broad timing in one module that is also used by another, and it's handy to use the return value of one modX_run() and the arguments of another (or some basic logic) to make that connection. For example:



                                    if (DMX_run()) //includes its own timing, and returns true at the start of each 30Hz interval, otherwise false

                                    I2C_start(); //I2C frames are sync'ed to DMX

                                    I2C_run(); //once started, an I2C frame runs freely until finished



                                    If you study the datasheet, you may also find that the hardware peripherals can be massaged to do what you want without any CPU intervention at all.



                                    Output pulse generation, for example, is a common one. Turn it on, set the peripheral to turn it off some time later, and forget about it. It's typically in the same general area as PWM.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 14 mins ago









                                    AaronDAaronD

                                    4,2895 silver badges28 bronze badges




                                    4,2895 silver badges28 bronze badges




















                                        thebear8 is a new contributor. Be nice, and check out our Code of Conduct.









                                        draft saved

                                        draft discarded


















                                        thebear8 is a new contributor. Be nice, and check out our Code of Conduct.












                                        thebear8 is a new contributor. Be nice, and check out our Code of Conduct.











                                        thebear8 is a new contributor. Be nice, and check out our Code of Conduct.














                                        Thanks for contributing an answer to Electrical Engineering Stack Exchange!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid


                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.

                                        Use MathJax to format equations. MathJax reference.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2felectronics.stackexchange.com%2fquestions%2f447850%2fwhats-the-maximum-time-an-interrupt-service-routine-can-take-to-execute-on-atme%23new-answer', 'question_page');

                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                                        Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                                        François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480