|
|
View previous topic :: View next topic |
Author |
Message |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Fri Jun 04, 2010 8:39 am |
|
|
OK so you missed the [ code ] tag at the start. I see you got the end one in
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
|
|
Posted: Fri Jun 04, 2010 9:03 am |
|
|
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
|
|
Posted: Mon Jun 07, 2010 2:11 am |
|
|
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 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
|
Switch |
Posted: Mon Jun 07, 2010 7:25 am |
|
|
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
|
Switch |
Posted: Mon Jun 07, 2010 8:47 am |
|
|
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
|
|
Posted: Tue Jun 08, 2010 1:48 am |
|
|
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
|
Update |
Posted: Tue Jun 08, 2010 7:40 am |
|
|
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
|
|
Posted: Mon Jun 14, 2010 9:16 am |
|
|
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
|
|
Posted: Mon Jun 14, 2010 10:11 am |
|
|
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
|
|
Posted: Mon Jun 14, 2010 10:39 am |
|
|
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
|
more |
Posted: Mon Jun 14, 2010 12:56 pm |
|
|
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
|
Solved ? |
Posted: Mon Jun 14, 2010 1:13 pm |
|
|
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
|
Compiler problem |
Posted: Tue Jun 15, 2010 12:44 pm |
|
|
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
|
|
Posted: Tue Jun 15, 2010 2:42 pm |
|
|
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
|
Solved |
Posted: Tue Jun 15, 2010 2:49 pm |
|
|
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. |
|
|
|
|
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
|