Jump to content

JMoore

EstablishedMember
  • Content Count

    5
  • Joined

  • Last visited

Community Reputation

0 Neutral

About JMoore

  • Rank
    Newbrie
  1. I don't think it is necessary to read or write the stack - only the stack pointer. You need to do two things; 1) Put the stack pointer back to where it was when the setjmp was called. I don't know if the PIC has the instructions to do this, but I would expect so. Note that MCC18 allows this. 2) Restore any non-stacked context (register held local variables, for example) that was present when the setjmp was called. The buffer provided to setjmp is where this information (stack pointer or level, other context). 3) Set the return from setjmp to the appropriate value. BTW, without software stacks, how do you handle local variables? In a classic implementation, they are stored after/before the PC in the stack frame, or if optimized, in registers that are stored when a subsequent routine is called (or in higher levels of optimization, different registers are allocated as needed, which is the equivalent of a software stack). It's been too (4) many decades since my last compiler construction course. :angry:
  2. I have to disagree. This can be done cleanly, and other compilers do it. I have also used it on small 8-bit Atmel processors, which are just as tiny and also have the (cursed) Harvard architecture. It is independent of how deep the stack can be (i.e. if I have too deep a stack, it's a fail with or without longjmp). The setjmp buffer holds enough information to restore the stack (or at least the items still active after the longjmp) to the point it was at when setjmp was called. This is obviously compiler dependent, but is quite doable. Usually it is just the address the stack was at, but if the stack uses dynamically allocated stack frames, the longjmp would have to de-allocate them. Since I don't know how this compiler handles the stack, I can't write the code myself (and doing so by experimentation would make me vulnerable to version changes). It is a feature I think should be in any C compiler library. The other approach you suggested is, of course, an alternative which I had considered. However, the setjmp/longjmp approach is much, much cleaner in the code. I don't have to worry about the timeout except where it is detected, and at the place I want to end up as a result of the timeout. Furthermore, I am porting Atmel code that already uses it. The flag approach means that every place I call a routine that could time out, I have to remember to put in the check - bunches of code, and easy to forget. Since I am parsing input data, I call a get character routine from all over the place, and each of those would have to check (there is an alternative trick, but its ugly - have get character return something really illegal, and only check where a retry would happen). For me, not being able to do setjmp/longjmp is a deal breaker. I need the functionality - I'm not going to clutter up my code with bug-prone checks all over the place. Hopefully the proprietors will answer this or point me to a reference that would allow me to code it myself. Thanks for your response
  3. What are setjmp/longjmp used for ? Regards Dave setjmp/longjmp are used sort of like Java exceptions - to allow control to jump out of multiple levels of subroutine calls. It is part of ANSI C. In my case, I have a user interface that makes calls in many places to input routines, some of which themselves call lower level routines. I need to have an input timeout, so that when it times out, control jumps back up out of the user interface. Example: jmp_buf abortJmpBuf; // The buffer for holding the jump context ... // Arm the timeout escape c = setjmp(abortJmpBuf); // If longjmp is called, it will look like a return from this if ( c == MY_TIMEOUT ) { // See if longjump popped us back to here return MY_ERROR; // Yes - leave user interface } // ... somewhere deep in low level subroutines if ( timedOut ) { longjmp(abortJmpBuf, MY_TIMEOUT); }
  4. I am porting code that uses setjmp/longjmp. I can't find a reference to it in the SourceBoost documentation. Is it available? If not, does anyone have code that will implement it? Tks
  5. I hope this is a suitable place for these questions. I am just starting some professional PIC development and am evaluating SourceBoost vs MCC18. First, I have a problem with SourceBoost integration with MPLAB: When I make a change in one file, it recompiles all of them. Since my projects will be fairly large, this can be a nuisance. Is there something I can change to make it selective in its compile? I have already concluded, for now, that the -X version of MPLAB is not ready enough yet. Beyond that, I would be interested in comments on what makes SourceBoost a good choice (not looking for negative comments or I wouldn't post it here). Obviously the price is attractive. Beyond that, what features are more desirable? For example, I would prefer to not be bothered with the quirks of the PIC - such as specifying memory banks and other stuff you don't have to sweat on other chips (such as Atmel or Freescale). Does SourceBoost do this in a more automatic manner? Another example: I like the way the pragmas work - more standard than MCC18. Other goodies? Thanks
×
×
  • Create New...