CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

restart_cause() and STKFUL [SOLVED]

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
VernonAMiller



Joined: 11 Sep 2014
Posts: 25
Location: Contoocook, NH

View user's profile Send private message

restart_cause() and STKFUL [SOLVED]
PostPosted: Thu Oct 09, 2014 7:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 09, 2014 8:39 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 09, 2014 9:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Oct 09, 2014 11:12 am     Reply with quote

and it is always just 'nice' when debugging to 'know'. Smile

It is a silly lack that ought to be pointed out to CCS.
VernonAMiller



Joined: 11 Sep 2014
Posts: 25
Location: Contoocook, NH

View user's profile Send private message

PostPosted: Thu Oct 09, 2014 12:11 pm     Reply with quote

Ttelmah wrote:
and it is always just 'nice' when debugging to 'know'. Smile

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 Smile

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...)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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