epitalon
Joined: 11 Mar 2010 Posts: 11 Location: france
|
setjmp.h for PCH |
Posted: Tue Mar 15, 2011 12:20 pm |
|
|
Hi,
I use a PIC18F4550 along with PCH compiler version 4.104.
I bumped into a bug in the library file setjmp.h
setjmp.h usage :
1. The longjmp() function causes program execution to resume at the point of the last call to setjmp().
2. longjmp() and setjmp() provide a means of jumping between functions.
The most common use of longjmp() is to return from a deeply nested set of routines when an error occurs.
My problem comes from setjmp() omitting to save the bank register (BSR). Then, when longjmp() returns, the bank may be corrupted.
Note that setjmp.h contains two versions : one for PCH compiler (for 16-bit opcode PICĀ® microcontrollers) and one for others compiler (PCB and PCM ?).
I just fixed the PCH version. Here is the code.
Code: |
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
#ifndef _SETJMP
#define _SETJMP
#ifdef __PCH__
#define _NSETJMP 5
#else
#define _NSETJMP 2
#endif
/* The buffer where the environment will be stored by setjmp
*/
typedef BYTE jmp_buf[_NSETJMP];
/* Stores information on the current calling context in a data
* object of type jmp_buf and which marks where you want control
* to pass on a corresponding longjmp call.
*
* Parameters:
* env
* [out] The data object that will receive the current environment
*
* Return Values:
* If the return is from a direct invocation, this function returns 0.
* If the return is from a call to the longjmp function, the setjmp
* function return a nonzero value and it's the same value passed to
* the longjmp function.
*/
#inline
int setjmp(int8 *env);
/* Performs the nonlocal transfer of control.
*
* Parameters:
* env
* [in] The data object that will be restored by this function
* val
* [in] The value that the function setjmp will return. If
* val is 0 then the function setjmp will return 1 instead.
*
* Return Values:
* After longjmp is completed, program execution continues as if
* the corresponding invocation of the setjmp function had just
* returned the value specified by val.
*/
#separate
int longjmp(int8 * env, int val);
//---------------------------------------------------------------------------
// Internal Declerations (Used by the library only)
//---------------------------------------------------------------------------
int __SETJMPVAL;
#ifdef __PCH__
typedef struct {
long int address;
int stack;
int bsr;
} __jmp_environ;
#byte __SETJMP_STACK=0xffc
#byte __SETJMP_BSR=0xfe0
#inline
int setjmp(int8 *env)
{
((__jmp_environ*)env)->address = label_address(callback);
((__jmp_environ*)env)->stack = __SETJMP_STACK;
((__jmp_environ*)env)->bsr = __SETJMP_BSR;
return(0);
callback:
return(__SETJMPVAL);
}
#separate
int longjmp(int8 * env, int val)
{
int32 to;
to = ((__jmp_environ*)env)->address;
__SETJMP_STACK = ((__jmp_environ*)env)->stack;
if (val == 0)
val = 1;
__SETJMPVAL = val;
__SETJMP_BSR = ((__jmp_environ*)env)->bsr;
goto_address(to);
}
#else
#inline
int setjmp(jmp_buf env)
{
int i;
*((long*)env) = label_address(callback);
return(0);
callback:
return(__SETJMPVAL);
}
#separate
int longjmp(int8 * env, int val)
{
int i;
if (val == 0)
val = 1;
__SETJMPVAL = val;
goto_address(*((long*)env));
}
#endif
#endif
|
|
|