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

BUG with delay_ms() in PCH 3.249
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

BUG with delay_ms() in PCH 3.249
PostPosted: Sat Jun 10, 2006 2:08 pm     Reply with quote

The problem is that the compiler uses the same memory location for a counter in the delay_ms() routine and for some other functions, including an ISR that is interrupting at 10 ms. Somewhere in my initialisation section I have a call delay_ms(500) right after I enable the mentioned ISR. The result is that the ISR modifies one register (the one used as a counter by delay_ms) at every interrupt, so the delay_ms() routine never finishes and the software hangs! I have not allocated anything by myself, all allocation is done by the compiler and obviously it messes it up. Any advice anyone?
Ttelmah
Guest







PostPosted: Sat Jun 10, 2006 2:18 pm     Reply with quote

Where is your '#use delay' statement?. The only time I have seen behaviour like this, was where this was after the interrupt declarations.

Best Wishes
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Sat Jun 10, 2006 2:39 pm     Reply with quote

It's at the beginning of the code, as usual, after the #fuses.
Ttelmah
Guest







PostPosted: Sun Jun 11, 2006 3:56 am     Reply with quote

You are going to need to post simple code showing the problem.
You would have to do this to report it as a bug anyway, and this may make it possible for somebody to see what is happening.

Best Wishes
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Sun Jun 11, 2006 5:22 am     Reply with quote

I've already sent the entire LST and SYM files to customer support, but it seems to me that they don't want to admit it's a compiler bug. Their answers were short and not very helpful...

Anyway, here is the portion of the SYM file with that memory location usage:
Code:
172     isr_tmr3.inputState
172     isr_tmr1.i
172     lcd_gotoxy.x
172     @delay_ms1.P1


The delay_ms1 routine (CLKSPEED is 32000000):
Code:
.................... #use delay(clock=CLKSPEED)
*
1172:  MOVLW  01
1174:  MOVWF  FEA
1176:  MOVLW  72
1178:  MOVWF  FE9
117A:  MOVF   FEF,W        ; Test 172 using INDF0
117C:  BZ    1198
117E:  MOVLW  0A
1180:  MOVWF  01
1182:  CLRF   00
1184:  DECFSZ 00,F
1186:  BRA    1184
1188:  DECFSZ 01,F
118A:  BRA    1182
118C:  MOVLW  5F
118E:  MOVWF  00
1190:  DECFSZ 00,F
1192:  BRA    1190
1194:  DECFSZ FEF,F        ; 172 is decremented using INDF0
1196:  BRA    117E
1198:  RETLW  00


The delay_ms(500) call that HANGS:
Code:
....................    delay_ms(500);   // WHY THIS LOCKS UP ???
3030:  MOVLW  02
3032:  MOVWF  xBD
3034:  MOVLW  FA
3036:  MOVLB  1
3038:  MOVWF  x72       ; Loads starting counter in 172
303A:  MOVLB  0
303C:  CALL   1172
3040:  DECFSZ xBD,F
3042:  BRA    3034
3044:  CLRF   18
3046:  BTFSC  FF2.7
3048:  BSF    18.7
304A:  BCF    FF2.7
.................... 


And the portion of isr_tmr3 that modifies the memory location 172:
Code:
.................... void isr_tmr3()
.................... {
....................   static int8 debounceCount[4] = {0, 0, 0, 0};
....................   static int8 currentState = 0xFF;
....................   int8 inputState;
.................... 
....................   set_timer3(TIMER3_START_FROM);
*
101E:  MOVLW  63
1020:  MOVWF  FB3
1022:  MOVLW  C0
1024:  MOVWF  FB2
.................... 
....................   inputState = PORTB;
1026:  MOVFF  F81,172        ; Reads PORTB into 172, once every 10ms !!


Any idea about how to fix this will be helpful. The chip is 18F452. I have tried compiler optimisation levels 0 to 11, nothing works.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jun 11, 2006 6:27 am     Reply with quote

Looking at the given code I can only agree with you that this is an error situation. More than that we can't do right now.
You didn't give us enough information to help you solve the problem. Create a small but complete and compilable program so we can see the complete context and are able to simulate the problem on our own computers.
Ttelmah
Guest







PostPosted: Sun Jun 11, 2006 7:01 am     Reply with quote

Obvious workround, is just to make the state static, which will force it to use another memory location.
Sending CCS, the full listings of a large project, is just like posting these here. Unlikely to get an answer. Like me, they will suspect that in fact it is something in the code that is actually triggering the behaviour, and unless this is identified, or repeated by a lot of users, will not be able to spend the time to track it down.
The same applies with problems and any compiler (Microsoft etc.). You have to narrow the fault down to find what is actually causing it, rather than just the 'effect'.
Is there any possibility that you are enabling/disabling the interrupts yourself, rather than using the CCS commands?. I can generate this exact behaviour, if I declare a 'delay_ms', in my main, and enable interrupts in front of it, by manually setting the register bit, rather than using the CCS commands.

Best Wishes
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Sun Jun 11, 2006 12:25 pm     Reply with quote

Tried to make inputState static, but as I see in the new SYM file there is a new conflict. I am not enabling/disabling any interrupts by myself. Everything is done using CCS commands.

Creating a small program would certainly be of great help for you guys, but I really don't know if I will be able to replicate this bug in a small program. I will try though. I've written many programs (small and medium sized) using delays and those worked fine. This current project worked fine too until I added a new feature which used some more ram and flash. It's not a small and simple program, it's over 2700 lines of code and uses 400 bytes of ram at most. I think this makes PCH go out of control trying to optimise the code.

Can't believe nobody ran into this problem before. Also I haven't seen any compiler updates recently. I was intending to use PCH for bigger projects, but I just lost my confidence in it after what it did.
Ttelmah
Guest







PostPosted: Sun Jun 11, 2006 2:40 pm     Reply with quote

A 'new conflict'?. Still with one from the interrupt handler?. If so, then it points strongly to the problem being with the declaration of this. Are you declaring this _or the prototype for it_, before 'main'. This must be done.

Best Wishes
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Sun Jun 11, 2006 4:02 pm     Reply with quote

Here is a portion from the SYM file when I make inputState static:
Code:
173     ds1307_save_record.at
173     YmdToLong.y         **
173     lcd_gotoxy.x
173     @delay_ms1.P1
173-176 @DIVS3232.P2       **
173     save_config.addr       **
173-174 ds1307_getdatetime.year       **
173     save_record.addr               **
173     isr_tmr1.@SCRATCH          **

The marked variables are used by function calls inside isr_tmr1(), which can occur during a long delay, because I have some menus that calls some long delays and TIMER1 runs in the background.

I don't fully understand what you said about the declarations. Should I declare the interrupt handlers' prototypes before main() ? They are all defined before main(), so there is no need for declaring. I tried to do that though, but it's the same result, even if I declare them before the #use delay statement.
Ttelmah
Guest







PostPosted: Sun Jun 11, 2006 4:27 pm     Reply with quote

If the functions are declared in front of main, there shouldn't be a problem.
Basically, the compiler allows 're-use' of a memory area, where it is only used by a function that cannot occur 'inside' another (so is called before or after the other function in the same program 'flow'). The interrupt handlers can be called at any point inside main or it's subroutines, and if their 'presence' is not declared before this, you can get a problem that the compiler does not realise they could be called at any point
If you are calling a lot of routines from inside the interrupt, are these also called in the normal program flow?. If so, then the re-use would be expected, since the compiler should disable interrupts round these functions, stopping these from being accessed from two locations (the PIC does not support re-entrant code). The fact that there is a reference to a DS1307 routine, both as one flagged as called in the interrupt, and another outside, suggests that you are doing this, or at the very least accessing the chip with seperate code that could cause probelms. Interrupts would need to be disabled round the 'outer' DS1307 routine, if a problem is not to exist, and if there is no software in common, this would have to be done manually by you.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jun 11, 2006 5:02 pm     Reply with quote

I know it is difficult to reduce your program to a smaller version still showing the same error, but without doing so we can only 'shoot from the hip' and hope to come up with a suggestion that is on target.

I personally don't think the error is caused by the delay routines. You noticed the error in the delay routines but it is caused by some other error. It is strange to see the compiler allocating memory for the interrupt routines that is also shared by non-interrupt routines. The compiler screwed up or you are calling the same routines from both inside the isr and main(). As Ttelmah pointed out you have to make sure the same functions can not be called from an interrupt and main at the same time. You can accomplish this by disabling/enabling interrupts around the function calls or by creating a copy of these functions, one set for calling from main and the other for calling from the isr.


Quote:
I was intending to use PCH for bigger projects, but I just lost my confidence in it after what it did.

I don't know if the CCS compiler is any better or worse than the other PIC compilers around but just having this great forum here has been a really big plus to me. However for larger projects, of let's say, over 25kbytes of code I don't think the PIC processor is a good choice. When the first PIC processors were designed silicon was expensive and Microchip did a great job of reducing the price and silicon area by stripping the core down to the absolute minimum features. Now trying to be backwards compatible this history is crippling the new chip models:
- No software stack which makes it almost impossible to implement recursive routines,
- The largest PIC18 processor has less than 5kb of RAM, how can you expect to build an efficient TCP/IP stack on this?
- Too many chip models. Only of the PIC18 there are 78 different models in production today! With that many different models what can you expect of the response time for fixing the chip erratta? My expectations are low, look at the newer PIC18 chips with over 30 known errata.

My point is there are other processors out there like the ARM family, wich have larger memory, more efficient instructions and even lower power consumption at similar prices to the PIC18 processors. Commercial compilers for these chips are expensive (several 1000$) but working around the limitations of the PIC costs time and money also.
VanHauser



Joined: 03 Oct 2005
Posts: 88
Location: Ploiesti, Romania

View user's profile Send private message

PostPosted: Mon Jun 12, 2006 4:29 am     Reply with quote

Those routines are indeed called from outside the isr, but the compiler notices this and gives me warnings about disabling interrupts around them:
Code:
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (@I2C_WRITEU_1_31763_31764_32000000)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (@I2C_READU_1_31763_31764_32000000)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (save_record)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (ds1307_getdatetime)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (save_config)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (@DIVS3232)
>>> Warning 216 "cdl-01.c" Line 117(0,1): Interrupts disabled during call to prevent re-entrancy:  (@MUL3232)
      Memory usage:   ROM=72%      RAM=12% - 26%
      0 Errors,  7 Warnings.

I am also disabling timer1 interrupt manually when I call the shared functions.

I think I found a solution. I have declared most variables in my program as static (except function parameters) and the SYM file looks much better. delay_ms1() still shares memory but now there are no problems. And most important, the device now appears to work.

My conclusion is that the compiler really screws up. Instead of focusing on actual development, I am trying to find workarounds for making the code work.

I don't think that the PIC and it's limitations are the problem. A simple architecture implies simple programming, and I keep this in mind most of the time.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Thu Jun 15, 2006 5:36 am     Reply with quote

Had the same problem. Just don't use delays in ISR's or use delay_us() that works. Honestly I don't understand why..

http://www.ccsinfo.com/forum/viewtopic.php?t=27037&highlight=
metalm2
Guest







PostPosted: Fri Apr 20, 2007 7:31 am     Reply with quote

I already have problems during the interrupt, i think CCS could be a good compiller if they take more care of the interrupts.

I now have a program which in 9600 works fine, and when I compile the same code in 2400 bps it has a totally different operation.
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 1, 2  Next
Page 1 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