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.)
Failure of setjmp and longjmp (PIC18s)
Re: Failure of setjmp and longjmp (PIC18s)
Hi,
Regards,
Filip.
We will investigate the reported issue and see where the error is.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.
Please, can you be more detailed regarding this ?There's even additional error in their implementation in mP and mB which makes me wonder about purpose of this addition.
Can you explain where is the obvious mistake with the __CC2D, and why do you feel that __CC2DW is redundant ?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.
Regards,
Filip.
Re: Failure of setjmp and longjmp (PIC18s)
Hi Filip,
Additional error in implementation in mP and mB is due to translation oftoin 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.
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.
Additional error in implementation in mP and mB is due to translation of
Code: Select all
if (!val) val=1;
Code: Select all
if not val=0 then val:=1;
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.
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.Can you explain where is the obvious mistake with the __CC2D, and why do you feel that __CC2DW is redundant ?
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.
Re: Failure of setjmp and longjmp (PIC18s)
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.
Re: Failure of setjmp and longjmp (PIC18s)
Hi,
If so, could you share your experience ?
Regards,
Filip.
Please, have you tested this ?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
If so, could you share your experience ?
Regards,
Filip.
Re: Failure of setjmp and longjmp (PIC18s)
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:
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.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().
I did perform tests or I wouldn't write about it. And there's nothing to share besides what I've already written before:
ADDED: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.
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;
}