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

setjmp.h for PCH

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
epitalon



Joined: 11 Mar 2010
Posts: 11
Location: france

View user's profile Send private message

setjmp.h for PCH
PostPosted: Tue Mar 15, 2011 12:20 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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