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

Switch statement going to wrong case...
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Fri Jun 04, 2010 8:39 am     Reply with quote

OK so you missed the [ code ] tag at the start. I see you got the end one in Smile

So you are using the debugger to step through this. you also have a default clause. Because of this is will have to step through each case comparison before it hits the correct one. You do not state if it does eventually get to the correct one.
If you remove the default clause than it will use a look up (I think) table instead and will be a lot faster.

As it stands there is proberbly no problem if it does execute the correct code.
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

PostPosted: Fri Jun 04, 2010 9:03 am     Reply with quote

Thanks for the reply.

The code executes case 1.

I suppose I could remove the default case. I just did that "in case" - no pun intended.

My feeling was maybe that maybe there was some problem with the debugger showing me the wrong step. Seems unlikely.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Mon Jun 07, 2010 2:11 am     Reply with quote

Hi,
What you are seeing in the debugger could be missleading. case 1 has no code to execute so when you say it is executing case 1 I assume you mean it goes to the break within case 1 ?

I also assume that when you step over this it drops out the bottom of the switch statement ?

I also do not know what the functions within the switch do. If they are empty then the compiler may have just optimised them out in which case Smile case 1 and case 9 will be the same!

Confirm that the value of rpc is correct with the debugger.
Place some code in case 1 and see if it steps to it.
Step through the assembly .lst file and see if it is executing correctly.
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Switch
PostPosted: Mon Jun 07, 2010 7:25 am     Reply with quote

Thanks for the reply. I tried all kinds of things including putting code in Case 1, removing the default case, break up the 30 switch cases into 3 seperate switch statements.

The two things I did that made the switch statement work properly were to (1) call it directly from Main(), and (2) comment out code that executed before it.

It didn't seem to matter what kinds of code I removed, just as long as so many lines were commented out.

I will go back and make sure there is unique code to be executed in each case statement to answer the optimization possibility you mentioned.
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Switch
PostPosted: Mon Jun 07, 2010 8:47 am     Reply with quote

Setting up unique code for each Case didn't help. The fact that I can call it from Main() or remove executed code ahead of this routine seems to rule out all kinds of things.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Jun 08, 2010 1:48 am     Reply with quote

Not sure what you mean by call directly from main but if commenting out code makes a difference then this usually indicates data corruption due to buffer / variable overruns.

If you could create a small compilable program which exhibits the problem and possible solution with commented out code we could help you.

I do not know how big your program is, can you not post it ?
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Update
PostPosted: Tue Jun 08, 2010 7:40 am     Reply with quote

Yesterday I removed all routines that had not yet been filled with code. This 'fixed' the switch problem. Now I'm seeing something I saw the other day. I have a routine calling another routine, it passes a value from an array (not a pointer), this value is 0x36. Inside the called routine the value is 0x30... I cannot track where the 0x30 comes from. It's not in the array.

There is the possibility that something is being overrun and I will look into that today. I'd be happy to post the code but it's too large to put into a message. I don't see a way to attach files here.

Thanks for hanging in there with me. I appreciate it.
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

PostPosted: Mon Jun 14, 2010 9:16 am     Reply with quote

I'm back to this switch problem going to the wrong case. I'm looking at the disassembly listing and see something wrong at the top. Case 5 is not shown and there seems to be an inordinately large gap in the program addresses. See my comments near the top of the code. I'm stepping through the program, rpc = 8A but is jumping to case 9.

Processor is PIC18F4550. Compiler is 3.249 (or 3.439...), using MPLAB 8.5.0.

Any ideas ? Thanks.
Code:

358:               void rpc_exec(){
359:                                       // Depending on rpc number passed, execute code for that rpc.
360:                                       // Depending on rpc number passed, execute code for that rpc.
361:                  int1   flag;
362:               
363:               //   tx_block=FALSE;            // Amulet is done blocking transmission if it's sending rpc's
364:               
365:                  switch(rpc_num){
  210C    0007     DAW

case 5 is missing here and there is a 12 byte gap programm addresses 210C to 2118

  2118    E014     BZ 0x2142         (( case 9 ))
  211A    0A02     XORLW 0x2
  211C    E016     BZ 0x214a         (( case 0B ))
  211E    0A18     XORLW 0x18
  2120    E017     BZ 0x2150         (( case 13h ))
  2122    0A93     XORLW 0x93
  2124    E01C     BZ 0x215e         (( case 80h ))
  2126    0A01     XORLW 0x1
  2128    E021     BZ 0x216c         (( case 81h ))
  212A    0A0B     XORLW 0xb
  212C    E024     BZ 0x2176         (( case 8A ))
  212E    0A01     XORLW 0x1
  2130    E027     BZ 0x2180         (( case 8B ))
  2132    D04E     BRA 0x21d0         (( default case ))
366:               
367:                     case 0x05:                         // Stop sequence (stir and heat)
368:                        tx_blk_timer=TX_BLOCK_LOAD;      // reset timeout timer.
  2134    0EC3     MOVLW 0xc3
  2136    0102     MOVLB 0x2
  2138    6F78     MOVWF 0x78, BANKED
  213A    0E50     MOVLW 0x50
  213C    6F77     MOVWF 0x77, BANKED
369:                        tx_block=TRUE;
  213E    8E1E     BSF 0x1e, 0x7, ACCESS
370:                        break;
  2140    D04A     BRA 0x21d6
371:                     
372:                     case 0x09:                      // Save current sequence entries:  rpm, time, deg C
373:                        save_procedure();      // check entries and save,  flag value has no meaning here
  2142    EF7A     GOTO 0x14f4
374:                        break;
  2146    0102     MOVLB 0x2
  2148    D046     BRA 0x21d6
375:               
376:                     case 0x0B:                     // "New" screen opening
377:                        new_procedure();
  214A    D5EC     BRA 0x1d24
378:                        break;
  214C    0102     MOVLB 0x2
  214E    D043     BRA 0x21d6
379:               
380:                     case 0x13:                // Select Procedure 1 from list to edit
381:                        edit_procedure(1);      // edit first procedure in displayed list
  2150    0E01     MOVLW 0x1
  2152    0102     MOVLB 0x2
  2154    6F7B     MOVWF 0x7b, BANKED
  2156    0100     MOVLB 0
  2158    D69B     BRA 0x1e90
382:                        break;
  215A    0102     MOVLB 0x2
  215C    D03C     BRA 0x21d6
383:               
384:                     case 0x80:                     // block xmit during amulet screen change
385:                        tx_blk_timer=TX_BLOCK_LOAD;      // reset timeout timer.
  215E    0EC3     MOVLW 0xc3
  2160    0102     MOVLB 0x2
  2162    6F78     MOVWF 0x78, BANKED
  2164    0E50     MOVLW 0x50
  2166    6F77     MOVWF 0x77, BANKED
386:                        tx_block=TRUE;
  2168    8E1E     BSF 0x1e, 0x7, ACCESS
387:                        break;
  216A    D035     BRA 0x21d6
388:               
389:                     case 0x81:                  // Un-block xmit after amulet screen change
390:                                             // may need to add code based on err_source value.
391:                        err_source=0;            // clear who opened the pop-up screen
  216C    6BDF     CLRF 0xdf, BANKED
392:                        tx_block=FALSE;
  216E    9E1E     BCF 0x1e, 0x7, ACCESS
393:                        pop_up_open=false;      
  2170    961E     BCF 0x1e, 0x3, ACCESS
394:                        break;
  2172    0102     MOVLB 0x2
  2174    D030     BRA 0x21d6
395:               
396:                     case 0x8A:                   // send procedure names for display on Amulet (to edit)
397:               
398:                        send_procedure_list(1);      // send 4 active procedure names to amulet starting at argument #
  2176    0E01     MOVLW 0x1
  2178    0102     MOVLB 0x2
  217A    6F7B     MOVWF 0x7b, BANKED
  217C    0100     MOVLB 0
  217E    D72F     BRA 0x1fde
399:                        break;
400:               
401:                     case 0x8B:                        // send procedure names for display on Amulet (to run)
402:                         queue_string(0x28,&proc_list[0][0]);
  2180    0E28     MOVLW 0x28
  2182    0102     MOVLB 0x2
  2184    6FED     MOVWF 0xed, BANKED
  2186    6BEF     CLRF 0xef, BANKED
  2188    0EEB     MOVLW 0xeb
  218A    6FEE     MOVWF 0xee, BANKED
  218C    0100     MOVLB 0
  218E    ECAE     CALL 0x55c, 0
403:                         queue_string(0x29,&proc_list[1][0]);
  2192    0E29     MOVLW 0x29
  2194    0102     MOVLB 0x2
  2196    6FED     MOVWF 0xed, BANKED
  2198    6BEF     CLRF 0xef, BANKED
  219A    0EFE     MOVLW 0xfe
  219C    6FEE     MOVWF 0xee, BANKED
  219E    0100     MOVLB 0
  21A0    ECAE     CALL 0x55c, 0
404:                         queue_string(0x2A,&proc_list[2][0]);
  21A4    0E2A     MOVLW 0x2a
  21A6    0102     MOVLB 0x2
  21A8    6FED     MOVWF 0xed, BANKED
  21AA    0E01     MOVLW 0x1
  21AC    6FEF     MOVWF 0xef, BANKED
  21AE    0E11     MOVLW 0x11
  21B0    6FEE     MOVWF 0xee, BANKED
  21B2    0100     MOVLB 0
  21B4    ECAE     CALL 0x55c, 0
405:                         queue_string(0x2B,&proc_list[3][0]);
  21B8    0E2B     MOVLW 0x2b
  21BA    0102     MOVLB 0x2
  21BC    6FED     MOVWF 0xed, BANKED
  21BE    0E01     MOVLW 0x1
  21C0    6FEF     MOVWF 0xef, BANKED
  21C2    0E24     MOVLW 0x24
  21C4    6FEE     MOVWF 0xee, BANKED
  21C6    0100     MOVLB 0
  21C8    ECAE     CALL 0x55c, 0
406:                        break;
  21CC    0102     MOVLB 0x2
  21CE    D003     BRA 0x21d6
407:                     
408:                     default:
409:                        flag=true;
  21D0    0102     MOVLB 0x2
  21D2    817A     BSF 0x7a, 0, BANKED
410:               
411:                     break;
  21D4    D000     BRA 0x21d6
412:                  }
413:                  rpc_num=0;
  21D6    0101     MOVLB 0x1
  21D8    6B94     CLRF 0x94, BANKED
414:               }
  21DA    0100     MOVLB 0
  21DC    EF49     GOTO 0x2292
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Mon Jun 14, 2010 10:11 am     Reply with quote

First make sure you 'rem' out the #nolist line in the processor define file. This makes the listing file 'lack' lines for some of the code. Then if the missing code is still not shown, do a search for the first address. It is common for the listing file to not be sequential, with 'parts' elsewhere....
Print out the disassembler listing from MPLAB, for this section.
Show the code that calls 'rpc_exec'. The compiler appears to be doing some fairly complex optimisations to perform the tests. The interesting thing is starting with the DAW instruction, since the effect of this depends on the DC, and C flags. It suggests the code is relying on some maths performed 'earlier', to set these....

Best Wishes
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

PostPosted: Mon Jun 14, 2010 10:39 am     Reply with quote

I tried replacing the switch with multiple IF statements and came up with the same DAW as shown in the earlier code. RPC is an in8 global.
Thanks.

Here is the main() code that calls the rpc_exec routine.
Code:

17:    void main(){

   i removed a lot of prelimiary register settings here

18:               
19:                   initialize();
  2264    0100     MOVLB 0
  2266    EF93     GOTO 0x326
20:                   enable_interrupts(GLOBAL);
  226A    0EC0     MOVLW 0xc0
  226C    12F2     IORWF 0xff2, F, ACCESS
21:               
22:                   //read_eeprom_data(1);
23:               
24:                   while(true){
25:               
26:                      serial_exec();
  226E    EF95     GOTO 0xf2a
27:               
28:                      if (rpc_num>0 && serial_state==ST_IDLE)
  2272    0101     MOVLB 0x1
  2274    5394     MOVF 0x94, F, BANKED
  2276    E004     BZ 0x2280
  2278    53C8     MOVF 0xc8, F, BANKED
  227A    E102     BNZ 0x2280
29:                          rpc_exec();
  227C    0100     MOVLB 0
  227E    D746     BRA 0x210c
30:               
31:                      delay_ms(1);
  2280    0E01     MOVLW 0x1
  2282    0102     MOVLB 0x2
  2284    6F84     MOVWF 0x84, BANKED
  2286    0100     MOVLB 0
  2288    EC2D     CALL 0x25a, 0
32:                   }
  228C    D7F0     BRA 0x226e
33:                }
  228E    0003     SLEEP


This is the routine with the switch problem
Code:

358:               void rpc_exec(){
359:               
360:                  switch(rpc_num){
  210C    0007     DAW

      ((missing BZ 0x2134 to case 5 )
      (( rpc = 8A but is jumping to case 9 and executing it ))

  2118    E015     BZ 0x2144
  211A    0A02     XORLW 0x2
  211C    E015     BZ 0x2148
  211E    0A18     XORLW 0x18
  2120    E014     BZ 0x214a
  2122    0A93     XORLW 0x93
  2124    E017     BZ 0x2154
  2126    0A01     XORLW 0x1
  2128    E01D     BZ 0x2164
  212A    0A0B     XORLW 0xb
  212C    E01F     BZ 0x216c
  212E    0A01     XORLW 0x1
  2130    E022     BZ 0x2176
  2132    D048     BRA 0x21c4
361:               
362:                     case 0x05:                         // Stop sequence (stir and heat)
363:                        tx_blk_timer=TX_BLOCK_LOAD;      // reset timeout timer.
  2134    0EC3     MOVLW 0xc3
  2136    0102     MOVLB 0x2
  2138    6F78     MOVWF 0x78, BANKED
  213A    0E50     MOVLW 0x50
  213C    6F77     MOVWF 0x77, BANKED
364:                        tx_block=TRUE;
  213E    8E1E     BSF 0x1e, 0x7, ACCESS
365:                        break;
  2140    0100     MOVLB 0
  2142    D040     BRA 0x21c4
366:                     
367:                     case 0x09:                      // Save current sequence entries:  rpm, time, deg C
368:                        save_procedure();      // check entries and save,  flag value has no meaning here
  2144    EF7A     GOTO 0x14f4
369:                        break;
370:               
371:                     case 0x0B:                     // "New" screen opening
372:                        new_procedure();
  2148    D5ED     BRA 0x1d24
373:                        break;
374:               
375:                     case 0x13:                // Select Procedure 1 from list to edit
376:                        edit_procedure(1);      // edit first procedure in displayed list
  214A    0E01     MOVLW 0x1
  214C    0102     MOVLB 0x2
  214E    6F7A     MOVWF 0x7a, BANKED
  2150    0100     MOVLB 0
  2152    D69E     BRA 0x1e90
377:                        break;
378:               
379:                     case 0x80:                     // block xmit during amulet screen change
380:                        tx_blk_timer=TX_BLOCK_LOAD;      // reset timeout timer.
  2154    0EC3     MOVLW 0xc3
  2156    0102     MOVLB 0x2
  2158    6F78     MOVWF 0x78, BANKED
  215A    0E50     MOVLW 0x50
  215C    6F77     MOVWF 0x77, BANKED
381:                        tx_block=TRUE;
  215E    8E1E     BSF 0x1e, 0x7, ACCESS
382:                        break;
  2160    0100     MOVLB 0
  2162    D030     BRA 0x21c4
383:               
384:                     case 0x81:                  // Un-block xmit after amulet screen change
385:                                             // may need to add code based on err_source value.
386:                        err_source=0;            // clear who opened the pop-up screen
  2164    6BDF     CLRF 0xdf, BANKED
387:                        tx_block=FALSE;
  2166    9E1E     BCF 0x1e, 0x7, ACCESS
388:                        pop_up_open=false;      
  2168    961E     BCF 0x1e, 0x3, ACCESS
389:                        break;
  216A    D02C     BRA 0x21c4
390:               
391:                     case 0x8A:                   // send procedure names for display on Amulet (to edit)
392:               
393:                        send_procedure_list(1);      // send 4 active procedure names to amulet starting at argument #
  216C    0E01     MOVLW 0x1
  216E    0102     MOVLB 0x2
  2170    6F7A     MOVWF 0x7a, BANKED
  2172    0100     MOVLB 0
  2174    D734     BRA 0x1fde
394:                        break;
395:               
396:                     case 0x8B:            // send procedure names for display on Amulet (to run)
397:                         queue_string(0x28,&proc_list[0][0]);
  2176    0E28     MOVLW 0x28
  2178    0102     MOVLB 0x2
  217A    6FED     MOVWF 0xed, BANKED
  217C    6BEF     CLRF 0xef, BANKED
  217E    0EEB     MOVLW 0xeb
  2180    6FEE     MOVWF 0xee, BANKED
  2182    0100     MOVLB 0
  2184    ECAE     CALL 0x55c, 0
398:                         queue_string(0x29,&proc_list[1][0]);
  2188    0E29     MOVLW 0x29
  218A    0102     MOVLB 0x2
  218C    6FED     MOVWF 0xed, BANKED
  218E    6BEF     CLRF 0xef, BANKED
  2190    0EFE     MOVLW 0xfe
  2192    6FEE     MOVWF 0xee, BANKED
  2194    0100     MOVLB 0
  2196    ECAE     CALL 0x55c, 0
399:                         queue_string(0x2A,&proc_list[2][0]);
  219A    0E2A     MOVLW 0x2a
  219C    0102     MOVLB 0x2
  219E    6FED     MOVWF 0xed, BANKED
  21A0    0E01     MOVLW 0x1
  21A2    6FEF     MOVWF 0xef, BANKED
  21A4    0E11     MOVLW 0x11
  21A6    6FEE     MOVWF 0xee, BANKED
  21A8    0100     MOVLB 0
  21AA    ECAE     CALL 0x55c, 0
400:                         queue_string(0x2B,&proc_list[3][0]);
  21AE    0E2B     MOVLW 0x2b
  21B0    0102     MOVLB 0x2
  21B2    6FED     MOVWF 0xed, BANKED
  21B4    0E01     MOVLW 0x1
  21B6    6FEF     MOVWF 0xef, BANKED
  21B8    0E24     MOVLW 0x24
  21BA    6FEE     MOVWF 0xee, BANKED
  21BC    0100     MOVLB 0
  21BE    ECAE     CALL 0x55c, 0
401:                        break;
  21C2    D000     BRA 0x21c4
402:                  }
403:                  rpc_num=0;
  21C4    0101     MOVLB 0x1
  21C6    6B94     CLRF 0x94, BANKED
404:               }
  21C8    0100     MOVLB 0
  21CA    EF40     GOTO 0x2280
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

more
PostPosted: Mon Jun 14, 2010 12:56 pm     Reply with quote

I tried inserting some junk code before the switch but the DAW is still there and the switch does not execute the proper case.

Code:
358:               void rpc_exec(){
359:               
360:                  int1   flag;
361:                  int8   crap;
362:               
363:                  crap=6;
  210C    0007     DAW
364:                  crap=0xff;
365:               
366:                  switch(rpc_num){
  2118    5194     MOVF 0x94, W, BANKED
  211A    0A05     XORLW 0x5
  211C    0100     MOVLB 0
  211E    E00F     BZ 0x213e
  2120    0A0C     XORLW 0xc
  2122    E014     BZ 0x214c
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Solved ?
PostPosted: Mon Jun 14, 2010 1:13 pm     Reply with quote

I tried calling the rpc routine before the serial routine and it seems to be working ok now and the dissassembly looks more like you'd expect.
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Compiler problem
PostPosted: Tue Jun 15, 2010 12:44 pm     Reply with quote

I am able to to make this problem go away at times but one thing that stays consistent is that program location 210C is always a DAW command. The assembly code around it can change as I add more C code but this never changes.
Ttelmah



Joined: 11 Mar 2010
Posts: 19587

View user's profile Send private message

PostPosted: Tue Jun 15, 2010 2:42 pm     Reply with quote

What is the printout with DAW, actually 'from'?.
Have you looked directly in the .LST file (the actual CCS assembler listing), instead?.
I'm beginning to wonder if you have something 'silly', like a #ROM statement for the wrong processor in your code.
0x2100, is the location for the EEPROM on the older 16F series processors (very wrong for a 18F chip...). I'm starting to think you have something being loaded, possibly a piece of code moved from an 'older' chip, which directly puts values into this area, resulting in part of the code being destroyed. This would then result in incorrect operation (obviously), with the results varying according to what other code is using this area.
Do a search of all the source files, for a #ROM, and also for any #ORG statements.

Best Wishes
DonWare



Joined: 18 Jan 2006
Posts: 43

View user's profile Send private message

Solved
PostPosted: Tue Jun 15, 2010 2:49 pm     Reply with quote

Right you are. I had a ROM statement where I had inserted a version string in eeprom on a 16F processor.

I noticed that the DAW location was always 210C no matter when everything else changed in the assembly listing. 210C is the next byte after my version string. It got me to thinking.

Pretty stupid. Oh well live and learn.

Thanks for your help. I really appreciate it.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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