EmbeddedRelated.com
Forums

C program flow control - Very Basic Question.

Started by Royston Vasey June 2, 2010
On 06/02/2010 05:24 AM, Royston Vasey wrote:
> I've got a very basic question guys, I'm teaching myself C using Microchip's > C18 compiler. > > > I've got my main loop running, looking for certain conditions to occur, > receiving a serial command& processing it. > > I need to monitor a few things for a time out condition, to do this I'm > pre-loading Timer1 with the required values and when the timer overflows it > jumps to the relevant interrupt. > > > All the above works fine. > > > When the Timer1 interrupt fires what is the easiest/best/correct way to > execute a block of "reset" code and then recommence execution at a > _particular_ place in the main() loop? > > Using assembly I would have used "goto" to steer execution where I wanted > it, but how is it approached in C?
Just jump to wherever the thing starts up from out of reset? I think the PIC18 has a watch-dog timer that will do what you want in hardware -- if you don't kick the dog periodically it'll time out and reset the processor. If your timeout is to make sure that code is executing correctly, this may be what you want. Assuming normal program operation, however, the way that this sort of thing is done is to implement a state machine in main, that loops, tests states to see where it should go next, and tests flags to see if it should do anything exceptional. In your case you'd have a flag that would get set in the ISR, then tested in main. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com
Hi Tim,

Tim Wescott wrote:
> Exception handling in object-oriented programming is specifically > designed to address the problems in C++ that C's "goto" and long branch > (long goto? I can't remember what it's called) solve in C.
setjmp()/longjmp()?
On Wed, 2 Jun 2010 20:24:01 +0800 in comp.arch.embedded, "Royston Vasey"
<royston@vasey.com> wrote:

>I've got a very basic question guys, I'm teaching myself C using Microchip's >C18 compiler. > > >I've got my main loop running, looking for certain conditions to occur, >receiving a serial command & processing it. > >I need to monitor a few things for a time out condition, to do this I'm >pre-loading Timer1 with the required values and when the timer overflows it >jumps to the relevant interrupt. > > >All the above works fine. > > >When the Timer1 interrupt fires what is the easiest/best/correct way to >execute a block of "reset" code and then recommence execution at a >_particular_ place in the main() loop? > >Using assembly I would have used "goto" to steer execution where I wanted >it, but how is it approached in C?
It sounds like you want to avoid executing some code in the main loop if a timeout occurs. The reset code is probably best handled in the interrupt routine. Also, when in that routine set a volatile global variable timeout_occured and test it in the main loop just before entering the stretch of code you don't want executed. ex: volatile bool timeout_occured; : : /* I don't use this compiler, so use whatever interrupt pragma it calls for */ void timeout_interrupt(void) { : /* reset code */ timeout_occured = true; } : : while (true) do { timeout_occured = false; : : if (timeout_occured) next; /* skip remaining code in the loop */ /* stuff to exexcute if no timeout has occured */ } Yes, this is a bit of a kludge, but it is easy to understand (extremely important when you come back to modify the code months later) and it should preserve the good structure of the main loop. If the reset code is going to take too long (always remember to keep your interrupt routines as fast as possible so as not to miss other interrupts), change the if... code to something like this: if (!timeout_occured) { /* stuff to exexcute if no timeout has occured */ } else { /* reset code, ripped out of the ISR */ } hope that helps Joe Power Pain is inevitable; suffering is optional.
D Yuniskis wrote:
> Hi Tim, > > Tim Wescott wrote: >> Exception handling in object-oriented programming is specifically >> designed to address the problems in C++ that C's "goto" and long >> branch (long goto? I can't remember what it's called) solve in C. > > setjmp()/longjmp()?
People who are allergic to "goto" in C should run screaming at the sight of these functions! There are times when "goto" is the best way to structure your code - I've used it a few times. You have to be careful with it, as it's easy to write spaghetti code and lose track of things like variable initialisations (C++ is fussier about when you are allowed to use it). But setjmp() and longjmp() are far worse - if you think you need them, you are almost certainly wrong and should re-structure your code. (If you /know/ you need them, it's a different matter - few rules in C programming are absolute.)
David Brown wrote:
> D Yuniskis wrote: >> Hi Tim, >> >> Tim Wescott wrote: >>> Exception handling in object-oriented programming is specifically >>> designed to address the problems in C++ that C's "goto" and long >>> branch (long goto? I can't remember what it's called) solve in C. >> >> setjmp()/longjmp()? > > People who are allergic to "goto" in C should run screaming at the sight > of these functions! > > There are times when "goto" is the best way to structure your code - > I've used it a few times. You have to be careful with it, as it's easy > to write spaghetti code and lose track of things like variable > initialisations (C++ is fussier about when you are allowed to use it). > But setjmp() and longjmp() are far worse - if you think you need them, > you are almost certainly wrong and should re-structure your code. (If > you /know/ you need them, it's a different matter - few rules in C > programming are absolute.)
Back before C++ exceptions, I wrapped setjump/longjump in a struct w/ heap cleanup func pointers to handler errors that just wouldn't reasonably work any other way (floating point and floppy disk errors). I treat C++ exceptions just as warily. If the problem can be handled with error returns, then you don't need exceptions/longjump. -- Bob
Hi Bob,

Bob wrote:
> Back before C++ exceptions, I wrapped setjump/longjump in a struct w/ > heap cleanup func pointers to handler errors that just wouldn't > reasonably work any other way (floating point and floppy disk errors). I > treat C++ exceptions just as warily. If the problem can be handled with > error returns, then you don't need exceptions/longjump.
I've only used setjmp/longjmp to implement simulators and coroutines. Other than that, I think your "error returns" comment applies best! (i.e., make the problem *visible*)
Tim Wescott wrote:

> But used carefully and sparingly, "goto" in C can provide a very good > mechanism for exception handling. I use it occasionally, and it does > well for what it is. Were I to see a "goto" in a code review I would > pin the author of the code against the wall to make sure he was using it > correctly; were I to enter some of my code with a "goto" in a code > review I would schedule extra time to be pinned to the wall and justify > myself (I'd probably have careful comments in the code, too). >
In our code reviews a goto had to be either a usage that the team had agreed on (very few - usually related to exception cases) or you had to defend the usage.
> Exception handling in object-oriented programming is specifically > designed to address the problems in C++ that C's "goto" and long branch > (long goto? I can't remember what it's called) solve in C. >
When we went to C++ most of the error case gotos went away with well designed destructors (to release resources) and throw() of an exception.
David Brown wrote:
> There are times when "goto" is the best way to structure your code - > I've used it a few times. You have to be careful with it, as it's easy > to write spaghetti code and lose track of things like variable > initialisations (C++ is fussier about when you are allowed to use it). > But setjmp() and longjmp() are far worse - if you think you need them, > you are almost certainly wrong and should re-structure your code. (If > you /know/ you need them, it's a different matter - few rules in C > programming are absolute.)
One of the incentives to move to C++ was the nested setjmp() and longjmp() in the existing C code (yes setjmp() and longjmp() was the cleanest solution in C). With matching constructors and destructors in C++ it was much easier to manage resources automatically on a throw() in the exception case. Of course C++ takes some careful design up front.
On 06/02/2010 10:01 AM, D Yuniskis wrote:
> Hi Tim, > > Tim Wescott wrote: >> Exception handling in object-oriented programming is specifically >> designed to address the problems in C++ that C's "goto" and long >> branch (long goto? I can't remember what it's called) solve in C. > > setjmp()/longjmp()?
That's it. The more you start doing "C++ish" things the more dangerous it gets -- but it's kewl for (very, very carefully constructed) library code-like things. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com
On 06/02/2010 02:24 PM, Dennis wrote:
> Tim Wescott wrote: > >> But used carefully and sparingly, "goto" in C can provide a very good >> mechanism for exception handling. I use it occasionally, and it does >> well for what it is. Were I to see a "goto" in a code review I would >> pin the author of the code against the wall to make sure he was using >> it correctly; were I to enter some of my code with a "goto" in a code >> review I would schedule extra time to be pinned to the wall and >> justify myself (I'd probably have careful comments in the code, too). >> > In our code reviews a goto had to be either a usage that the team had > agreed on (very few - usually related to exception cases) or you had to > defend the usage.
Yup. And if you're smart you take your code to one or two of the folks you know are going to _really_ care and you run it by them _first_.
>> Exception handling in object-oriented programming is specifically >> designed to address the problems in C++ that C's "goto" and long >> branch (long goto? I can't remember what it's called) solve in C. >> > When we went to C++ most of the error case gotos went away with well > designed destructors (to release resources) and throw() of an exception.
And yup. -- Tim Wescott Control system and signal processing consulting www.wescottdesign.com