| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				| setjmp/longjmp or work-arounds |  
				|  Posted: Sat Apr 23, 2005 3:21 pm |   |  
				| 
 |  
				| I have an application where I wait for user input at many places in the code. I want a built-in timeout that takes me back to a spot in my mainline. 
 setjmp/longjmp are used for this in standard C, but I found a thread indicating that they may not work in PCH. I need to work with both 16F and 18F series processors.
 
 Do they work in both compilers?
 
 If not, is there a workaround using embedded assembler?
 
 If I can't find this sort of solution, I have to return an impossible value (0, for example) and then test for it every place I go to read a character, which would greatly increase the size of the code!
 
 Advice sought. I am new to PIC and new to CCS.
 
 Thanks
 _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 1:01 am |   |  
				| 
 |  
				| Can you provide a link to the thread that says they don't work in PCH ? |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				| setjmp/longjmp - do they work? And how to use on 14 bit part |  
				|  Posted: Sun Apr 24, 2005 9:37 am |   |  
				| 
 |  
				| I found this since my last response: 
 http://www.ccsinfo.com/forum/viewtopic.php?t=19923&highlight=setjmp
 
 An answer by "guest" says:
 
 ---------------
 
 r = setjmp(env); Standard C function (requires setjmp.h)
 longjmp(env,val); Standard C function (requires setjmp.h)
 
 Use these functions with GREAT caution. Note as well that setjmp and
 longjmp do not clean up the stack on 12 and 14 bit parts.
 
 ----------------
 
 This is a bit alarming, as I plan to use this capability on both 14 and 16 bit parts. If it does not "clean up the stack," what do I do?
 
 Traditional C compilers maintain a runtime stack with local variables on it, so "cleaning the stack" involves backup up that pointer. I believe these CCS compilers, since they use a compile-time function tree, simply hard allocate those variables in RAM, sharing those that cannot (according to the tree) be active at the same time. In that case, resetting the CPU stack pointer to the top should be adequate (assuming setjmp was called from the top level), since there is no local variable stack.
 
 Is this the case? What would the code look like?
 _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 4:29 pm |   |  
				| 
 |  
				| CCS doesn't have any example programs for the setjmp.h file. Normally, CCS would have something like EX_SETJMP.C, but
 I don't see one.
 
 I went to this guy's page and modified his "if-else.c" setjmp
 example slightly, so it would work with CCS.
 http://linuxgazette.net/issue90/raghu.html
 It appears to work OK with PCM vs. 3.223 with a 16F877, but
 it did not work with PCH vs. 3.188 with a 18F458.   I don't have
 the latest version of PCH, to test it.
 
 If CCS doesn't have a EX_SETJMP.C file to test it, how do
 they know if SETJMP.H works ?
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 5:08 pm |   |  
				| 
 |  
				| I have it working okay on a 18F452. 
 It's in the middle of a bunch of code, so I'll just post snippets:
 
 #include "setjmp.h"
 
 jmp_buf set_jmp_env;
 
 main() {
 ....
 if(!setjmp(set_jmp_env)) {
 printf(sendChar,"Going for getTimedChar\r\n");
 c = getTimedChar();
 printf(sendChar,"Got %c\r\n", c);
 ...
 } else {
 printf("longjump happened\r\n");
 }
 .....
 }
 
 int getTimedChar() {
 ....
 if (input_timer_setting_secs && !input_timer_countdown_secs) {
 longjmp(set_jmp_env, 0xa5);
 }
 .....
 }
 
 Now if I could just get interrupt driven USART receive working, I would be happy
 
 
  _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 5:20 pm |   |  
				| 
 |  
				|  	  | Quote: |  	  | I have it working okay on a 18F452. | 
 What version of PCH are you using ?
 
 
  	  | Quote: |  	  | Now if I could just get interrupt driven USART receive working, I would be happy | 
 We know how to make that work.    There are many people on this
 board who can help you with this.  Post a short test program that
 shows your complete #int_rda routine.  Also post code that shows
 how you test if the receive fifo has characters in it, and how you get
 the characters from the fifo.    Show all variable declarations, etc.
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 5:28 pm |   |  
				| 
 |  
				| I am running PCH Version 3.223. 
 I have no idea if longjmp/setjmp will work with PCM. If not, I've got a big problem. Unfortunately, I have no way to test it - all I have is a little test board that came with the PCH development kit, and it has an 18F452 on it.
 
 Regarding interrupts, maybe you can point me to an example. I'll put a separate post here with my code.
 
 Thanks
 _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 5:49 pm |   |  
				| 
 |  
				| FYI, I got the interrupt routine working, so no help needed. 
 It helps to read the data register with a "*" in front of the address of the input data fsf
  _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 6:07 pm |   |  
				| 
 |  
				|  	  | Quote: |  	  | I have no idea if longjmp/setjmp will work with PCM. If not, I've got a big
 problem. Unfortunately, I have no way to test it - all I have is a little test
 board that came with the PCH development kit, and it has an 18F452 on it.
 | 
 I guess you must have this mini 18F452 board.
 http://www.ccsinfo.com/evalkit452.shtml#18f452
 The PIC is soldered to the board, so there's no way you can buy
 another PIC and use it on that board.    You probably need to buy
 their 16F877A board to test your PCM compiler.    There are many
 methods of making a test board.
 
 Below, I have posted the modified "if-else.c" program from that guy's
 web page, at http://linuxgazette.net/issue90/raghu.html
 It produces the following output on the terminal window.
 So according to his description, it is working.  This was tested with
 PCM vs. 3.223.
 
  	  | Quote: |  	  | Start
 i = 0
 I am in if ..
 i = 2
 I am in else too...
 Done
 | 
 
 
  	  | Code: |  	  | #include <16F877.H> #fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
 #use delay(clock=4000000)
 #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
 
 #include<setjmp.h>
 
 main()
 {
 jmp_buf env;
 int i;
 
 printf("Start\n\r");
 
 i = setjmp(env);
 printf("i = %d\n\r", i);
 
 if(i == 0)
 printf("I am in if ..\n\r");
 else
 {
 printf("I am in else too...\n\r");
 goto done;
 }
 
 longjmp(env, 2);
 printf("Grrr... why am i not getting printed\n\r");
 
 done:
 
 printf("Done\n\r");
 while(1);
 }
 | 
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Sun Apr 24, 2005 6:11 pm |   |  
				| 
 |  
				| Thanks. It looks like it should do the job, then. _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Tue May 03, 2005 10:13 am |   |  
				| 
 |  
				| The example works fine in PCH/18F452, but in my application, where things are more complex and the longjmp takes place well down in a subroutine call hierarchy, it doesn't work right - it causes restarts sometimes and other times does not - all to the same input! 
 Because longjmp uses a stack, which makes it complex and the assembly code hard to follow, I am going to give up on it, assume there is a good reason that it is not in the compiler book and examples, and write my own simple one in assembly language.
 
 My tentative conclusion, after a lot of fiddling, is that setjmp/longjmp is possibly flawed in a subtle way. With the code slightly different it would always go to the right place but setjmp always returned 0, even when a longjmp(jmp_buf, 2) was taken. The code around it now looks like:
 
 
  	  | Code: |  	  | c = setjmp(jmp_env);
 if ( 0 == c ) {
 printf("---setjmp returns OK: %d\r\n", c);
 do_burst_or_poll() ;
 } else {
 printf("---setjmp returns timeout: %d\r\n", c);
 |
 
 | 
 
 The longjmp code:
 
  	  | Code: |  	  | 
 // If timed out, jump to mainline
 if (0 >= --input_timer_countdown_secs) {
 longjmp(jmp_env, 2);
 }
 
 | 
 
 The buffer declaration:
 
  	  | Code: |  	  | 
 // Set jump buffer
 jmp_buf jmp_env;
 
 | 
 
 I am new to the PIC and CCS. Does anyone know CCS's position on setjmp/longjmp? They are not listed in my compiler manual or the list of supported C library methods on the web site. Since it isn't in the compiler book, does that mean it is not a supported feature? Do I report this as a bug or is there a place to look for known bugs, or is it just not supported (I expect the latter)?
 _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 03, 2005 10:37 am |   |  
				| 
 |  
				| It is in the manual.   Download the Feb. 2005 manual.   Use the search engine of Acrobat Reader to search for:  setjmp
 
 It's in there, in several places.
 |  | 
	
		|  | 
	
		| gustnado 
 
 
 Joined: 23 Apr 2005
 Posts: 21
 Location: Phoenix,AZ
 
 
			        
 
 | 
			
				|  |  
				|  Posted: Tue May 03, 2005 11:34 am |   |  
				| 
 |  
				| You are correct, although it is not in the expected location - the alphabetical list of functions with descriptions. I missed it because I was using the printed version of the same manual. Thanks for the pointer. 
 However, there is my experience and that of the other person's where longjmp apparently frequently causes restarts on the 18f series.
 
 Should I report this as a possible bug?
 _________________
 The best weather is bad weather
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 03, 2005 11:42 am |   |  
				| 
 |  
				| Sure.  If you can give CCS a complete (but short) test program that allows them to easily see the problem, then your chances
 of getting them to fix it are much better.   Also give them your
 compiler version.
 |  | 
	
		|  | 
	
		|  |