|
|
View previous topic :: View next topic |
Author |
Message |
VernonAMiller
Joined: 11 Sep 2014 Posts: 25 Location: Contoocook, NH
|
restart_cause() and STKFUL [SOLVED] |
Posted: Thu Oct 09, 2014 7:32 am |
|
|
Hi:
In compiler version 5.025d anyway, restart_cause() still doesn't appear to return stack-related causes (STKFUL or STKUNF). How is the best way to check these? It looks like the "preamble" code that the compiler generates for main() doesn't touch STKPTR (at least not explicitly), so is just checking the bits myself at the beginning of main() good enough?
Thanks,
VAM
Last edited by VernonAMiller on Wed Oct 15, 2014 8:46 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Oct 09, 2014 8:39 am |
|
|
What chip?.
On a lot of chips with stack overflow resets, so does 'RESTART_CAUSE'. So for instance, on the 16LF1714, you have:
Code: |
// Constants returned from RESTART_CAUSE() are:
#define NORMAL_POWER_UP 0x3C
#define BROWNOUT_RESTART 0x3E
#define MCLR_FROM_SLEEP 0x27
#define WDT_TIMEOUT 0x1F
#define WDT_FROM_SLEEP 0x0F
#define INTERRUPT_FROM_SLEEP 0x2F
#define MCLR_FROM_RUN 0x37
#define RESET_INSTRUCTION 0x3B
#define STACK_OVERFLOW 0xBF
#define STACK_UNDERFLOW 0x7F
|
However CCS 'habitually' misses them on the PIC18's, so you just code:
Code: |
#bit STKFUL=getenv("BIT:STKFUL")
#bit STKUNF=getenv("BIT:STKUNF")
int8 cause;
cause=restart_cause(); //read this before the stack bits
if (STKUNF)
//handle stack underflow
if (STKFUL)
//handle stack overflow
STKUNF=STKFUL=0; //You must explicitly clear them
//Then test cause for anything else.
|
I think the reason CCS 'miss' them, is that there isn't anything you can do about them. They are either down to a code fault, or there has been an internal error like a cosmic ray hit. On most other restart causes, you may want to run the code differently (perhaps not clearing variables etc..). Since you know the stack size from the compiler listing, you should be able to avoid the former cause, leaving only a really random event, which really needs to be treated the same as any other normal reset. |
|
|
VernonAMiller
Joined: 11 Sep 2014 Posts: 25 Location: Contoocook, NH
|
|
Posted: Thu Oct 09, 2014 9:55 am |
|
|
Ttelmah wrote: | What chip?
|
Ah, sorry, forgot. This is in fact a PIC18F, specifically a PIC18F2685.
Ttelmah wrote: |
On a lot of chips with stack overflow resets, so does 'RESTART_CAUSE'. So for instance, on the 16LF1714, you have:
Code: |
// Constants returned from RESTART_CAUSE() are:
#define NORMAL_POWER_UP 0x3C
#define BROWNOUT_RESTART 0x3E
#define MCLR_FROM_SLEEP 0x27
#define WDT_TIMEOUT 0x1F
#define WDT_FROM_SLEEP 0x0F
#define INTERRUPT_FROM_SLEEP 0x2F
#define MCLR_FROM_RUN 0x37
#define RESET_INSTRUCTION 0x3B
#define STACK_OVERFLOW 0xBF
#define STACK_UNDERFLOW 0x7F
|
|
Thanks for the info.
Ttelmah wrote: |
However CCS 'habitually' misses them on the PIC18's, so you just code:
Code: |
#bit STKFUL=getenv("BIT:STKFUL")
#bit STKUNF=getenv("BIT:STKUNF")
int8 cause;
cause=restart_cause(); //read this before the stack bits
if (STKUNF)
//handle stack underflow
if (STKFUL)
//handle stack overflow
STKUNF=STKFUL=0; //You must explicitly clear them
//Then test cause for anything else.
|
I think the reason CCS 'miss' them, is that there isn't anything you can do about them. They are either down to a code fault, or there has been an internal error like a cosmic ray hit. On most other restart causes, you may want to run the code differently (perhaps not clearing variables etc..). Since you know the stack size from the compiler listing, you should be able to avoid the former cause, leaving only a really random event, which really needs to be treated the same as any other normal reset. |
Great, just what I was looking for. Yeah, I understand there's nothing I can really do about it, but I'm just using a "belt and suspenders" approach with my error handling, and want to know as much as practical if something happens.
Thanks for the help, much appreciated!
VAM |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Thu Oct 09, 2014 11:12 am |
|
|
and it is always just 'nice' when debugging to 'know'.
It is a silly lack that ought to be pointed out to CCS. |
|
|
VernonAMiller
Joined: 11 Sep 2014 Posts: 25 Location: Contoocook, NH
|
|
Posted: Thu Oct 09, 2014 12:11 pm |
|
|
Ttelmah wrote: | and it is always just 'nice' when debugging to 'know'.
It is a silly lack that ought to be pointed out to CCS. |
Agreed on both counts. I'll file an enhancement request.
BTW, in case anyone wants a full example, here is my code based on your suggestions. It seems to be working fine so far, though I haven't tried causing a stack full or underflow - yet
VAM
Code: |
void main() {
{
BOOLEAN stackFull, stackUnderflow;
BYTE cause;
cause = restart_cause(); // Get this first.
#bit STKFUL=getenv("BIT:STKFUL")
#bit STKUNF=getenv("BIT:STKUNF")
// Get working copies of STKFUL and STKUNF and then clear the originals.
stackFull = STKFUL;
stackUnderflow = STKUNF;
STKFUL = STKUNF = 0;
// Wait for the UART to settle before trying to print anything.
delay_ms(100);
printf("Restart reason is: ");
if (stackFull) {
printf("Stack Full");
}
else if (stackUnderflow) {
printf("Stack Underflow");
}
else {
switch (cause) {
case RESET_INSTRUCTION:
printf("RESET instruction");
break;
case WDT_FROM_SLEEP:
printf("Watchdog Timeout during sleep");
break;
case WDT_TIMEOUT:
printf("Watchdog Timeout");
break;
case MCLR_FROM_SLEEP:
printf("MCLR during sleep");
break;
case NORMAL_POWER_UP:
printf("Normal power-up");
break;
case BROWNOUT_RESTART:
printf("Brownout restart");
break;
case MCLR_FROM_RUN:
printf("MCLR while running");
break;
default:
printf("Unknown reason %u", cause);
break;
}
}
printf("\r\n");
}
.
.
.
(rest of main() goes here...)
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|