|
|
View previous topic :: View next topic |
Author |
Message |
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
BUG with delay_ms() in PCH 3.249 |
Posted: Sat Jun 10, 2006 2:08 pm |
|
|
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
|
|
Posted: Sat Jun 10, 2006 2:18 pm |
|
|
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
|
|
Posted: Sat Jun 10, 2006 2:39 pm |
|
|
It's at the beginning of the code, as usual, after the #fuses. |
|
|
Ttelmah Guest
|
|
Posted: Sun Jun 11, 2006 3:56 am |
|
|
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
|
|
Posted: Sun Jun 11, 2006 5:22 am |
|
|
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
|
|
Posted: Sun Jun 11, 2006 6:27 am |
|
|
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
|
|
Posted: Sun Jun 11, 2006 7:01 am |
|
|
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
|
|
Posted: Sun Jun 11, 2006 12:25 pm |
|
|
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
|
|
Posted: Sun Jun 11, 2006 2:40 pm |
|
|
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
|
|
Posted: Sun Jun 11, 2006 4:02 pm |
|
|
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
|
|
Posted: Sun Jun 11, 2006 4:27 pm |
|
|
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
|
|
Posted: Sun Jun 11, 2006 5:02 pm |
|
|
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
|
|
Posted: Mon Jun 12, 2006 4:29 am |
|
|
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
|
|
|
metalm2 Guest
|
|
Posted: Fri Apr 20, 2007 7:31 am |
|
|
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. |
|
|
|
|
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
|