Failure of setjmp and longjmp (PIC18s)

Beta Testing discussion on mikroC PRO for PIC.
Post Reply
Author
Message
janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Failure of setjmp and longjmp (PIC18s)

#1 Post by janni » 31 Dec 2014 19:07

Probably very few use these functions and thus nobody noticed that they stopped functioning properly for PIC18s starting from version 6.40 of mC PRO. It's not like they fully functioned before - apart from simple examples :( - but now they fail miserably even in the example shipped with compiler.

I wouldn't notice it either if they weren't silently added to mP and mB System library which concerns me directly as I made available my version of this library. There's even additional error in their implementation in mP and mB which makes me wonder about purpose of this addition.

As I'm at it, two other, this time internal routines were earlier added to System library in all PIC compilers (__CC2D and __CC2DW) and seem to be never used (actually, __CC2D contains obvious mistake and is unusable and __CC2DW is redundant as already present internal routine does the same more efficiently) though one of Ethernet libraries demands their presence.

Would it be possible to rethink the changes introduced to System library? (And to correct the errors, naturally.)

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Failure of setjmp and longjmp (PIC18s)

#2 Post by filip » 05 Jan 2015 12:56

Hi,
Probably very few use these functions and thus nobody noticed that they stopped functioning properly for PIC18s starting from version 6.40 of mC PRO. It's not like they fully functioned before - apart from simple examples :( - but now they fail miserably even in the example shipped with compiler.
We will investigate the reported issue and see where the error is.
There's even additional error in their implementation in mP and mB which makes me wonder about purpose of this addition.
Please, can you be more detailed regarding this ?
As I'm at it, two other, this time internal routines were earlier added to System library in all PIC compilers (__CC2D and __CC2DW) and seem to be never used (actually, __CC2D contains obvious mistake and is unusable and __CC2DW is redundant as already present internal routine does the same more efficiently) though one of Ethernet libraries demands their presence.
Can you explain where is the obvious mistake with the __CC2D, and why do you feel that __CC2DW is redundant ?

Regards,
Filip.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Failure of setjmp and longjmp (PIC18s)

#3 Post by janni » 05 Jan 2015 14:04

Hi Filip,

Additional error in implementation in mP and mB is due to translation of

Code: Select all

if (!val) val=1;
to

Code: Select all

if not val=0 then val:=1;
in longjmp. Obviously, behaviour is different in both cases.

And the base error carried from earlier mC PRO versions remains in all compilers - only low byte of val parameter is copied to R0,R1 pair in longjmp (substitution for setjmp result), which makes application of setjmp/longjmp sensitive to user code.
Can you explain where is the obvious mistake with the __CC2D, and why do you feel that __CC2DW is redundant ?
This pair of internal routines was apparently added to allow copying of data from program memory (flash) to RAM. Well, there's already an internal routine that does exactly that, namely __CCA2AW (as the acronym suggests, it was intended for copying arrays, but its function is not limited to just arrays). While one could argue that __CC2D could be faster for small memory chunks (up to 256 bytes), the speed increase is marginal and it obviously wasn't ever used (needed?) as arguments in MOVFF instruction are accidentally reversed.

The argument about execution speed can be reversed in case of __CC2DW as compared to __CCA2AW. The latter is not only faster (and for large amounts of copied data it is noticeable) but it's also not limited to memory chunks greater than 256 bytes. In other words, __CCA2AW already does what both __CC2D and __CC2DW were supposed to do, and does it better. (Not that it couldn't be improved by making it insensitive to zero arguments - which may not be critical when copying arrays, but may be convenient when copying arbitrary data chunks. It was the first thing I did in my replacement for System library as I hate leaving loose ends.)

BTW, failure of setjmp/longjmp in mC PRO v 6.40/6.50 is due to use of accidental RAM locations in setjmp instead of pointer to env.

___________

ADDED: As a temporary solution one may use a replacement System library for mC PRO presented here.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Failure of setjmp and longjmp (PIC18s)

#4 Post by janni » 27 May 2015 00:17

Well, in version 6.60 of mC setjmp/longjmp functions were restored to their old form, which means the simple example coming with compiler works but any practical application still may fail. Pity.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: Failure of setjmp and longjmp (PIC18s)

#5 Post by filip » 27 May 2015 14:42

Hi,
Well, in version 6.60 of mC setjmp/longjmp functions were restored to their old form, which means the simple example coming with compiler works but any practical application still may fail. Pity
Please, have you tested this ?
If so, could you share your experience ?

Regards,
Filip.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Failure of setjmp and longjmp (PIC18s)

#6 Post by janni » 27 May 2015 16:05

Hi Filip,

I did perform tests or I wouldn't write about it. And there's nothing to share besides what I've already written before:
And the base error carried from earlier mC PRO versions remains in all compilers - only low byte of val parameter is copied to R0,R1 pair in longjmp (substitution for setjmp result), which makes application of setjmp/longjmp sensitive to user code.
ADDED:
Just in case nobody's inclined to analyse the code of System library, here's slightly modified example that comes with the compiler that demonstrates how setjump/longjmp pair fail in real projects.

Code: Select all

/*
 * Project name:
     SetjmpDemo (Example on using the mikroC's setjmp library)
 * Copyright:
     (c) mikroElektronika


#include <Setjmp18.h>

int i1,i2;

jmp_buf buf;             // Note: Program flow diagrams are indexed according
                         //       to the sequence of execution

void func33(){           //  2<------------|
  Delay_ms(1000);        //                |
                         //                |
  asm nop;               //                |
  i1 = i1/i2;
  longjmp(buf, 2);       //  3---------------->|
  asm nop;               //                |   |
                         //                |   |
}                        //                |   |
                         //                |   |
void func(){             //  1<--------|   |   |
                         //            |   |   |
  LATB = 3;              //            |   |   |
  if (setjmp(buf) == 2)  //  3<----------------|
    LATB = 1;            //  4-->|     |   |
  else                   //      |     |   |
    func33();            //  2------------>|
                         //      |     |
                         //  4<--|     |
}                        //  5----->|  |
                         //         |  |
void main() {            //         |  |
  ANSELB = 0;            //         |  |
  PORTB = 0;             //         |  |
  TRISB = 0;             //         |  |
                         //         |  |
  i1 = 512;
  i2 = 1;
  asm nop;               //         |  |
                         //         |  |
  func();                //  1-------->|
                         //         |
  asm nop;               //  5<-----|
  Delay_ms(1000);
  LATB = 0xFF;
}
Performing simple arithmetic operation in func33 causes internal register R1 to be nonzero and that's enough to destroy functioning of setjmp/longjmp - program will never pass func().

Post Reply

Return to “mikroC PRO for PIC Beta Testing”