|
|
View previous topic :: View next topic |
Author |
Message |
markie
Joined: 24 Dec 2007 Posts: 2
|
RAM corruption (I don't think it's my fault!) |
Posted: Mon Dec 24, 2007 3:09 pm |
|
|
Hi all,
I am using v4.057 and a PIC18F2520. At first all seemed well and everything worked fine, but as my project grew (a digitally controlled preamp, so growth was inevitable) seemingly random faults kept popping up. I would add some code, and other code would stop working or produce gibberish on the LCD, etc etc.
I have spend three days now trying to figure it out, and it seems that it is *not* my coding that's been at fault. I only use a couple of simple arrays so far, and have a primitive Fault() functions which stores a value in eeprom then calls a reset_cpu(). I use this to check for various array overflow conditions or other things which aren't supposed to happen. This function isn't getting called (though I have verified it works), so I have concluded that the problem isn't anything to do with my code overwriting the RAM and corrupting things.
Today I found out about the .lst and .sym stuff. As it happens I could get my program to near enough work, with just one piece of array data corrupted and everything else functioning fine, and to completely fail - simply by moving a single loop variable (k) declaration a few lines up in the program. Working = declare at beginning of main function, broken = declare just before the for loop!
I compared the .lst and .sym for the "working" code and the broken code. When declared at the top of the main function, I saw the variable in the .sym file. When declared just before the loop, the variable completely disappeared from the .sym file. I assume the compiler decided to locate it in some kind of temporary memory. This would actually explain the exact behaviour I was seeing!
The loop in question was the main loop for my primitive task system. It looked at each task and ran the appropriate function if it was scheduled. The broken compile was never exiting the for loop around the task array, and was only ever executing task 0, even though other tasks were being scheduled. I figure the loop variable being in some kind of temporary space made the variable keep being reset to 0 after calling the task execution function.
Here's the part of code that was failing. Where the "int k" is currently, it "works". If I move it to just before the for(), it dies.
Code: |
void MainLoop()
{
unsigned int k = 0;
while (TRUE)
{
// Only do task stuff if the power is actually on
if (GetPowerState())
{
// Run each scheduled task
for (k = 0; k < MAX_TASKS; k++)
{
if (Scheduled(k))
{
ExecuteTask(k);
}
}
} else {
sleep();
if (Scheduled(TASK_POWER_ON))
{
ExecuteTask(TASK_POWER_ON);
}
}
}
}
|
Anyway, further looking at the 'working' compile I saw that the corruption on some of the text I was seeing was because the compiler has decided to reuse that RAM space, which that array sits in, for some functions I call later on, so the text was being overwritten. The array in question is a compile time defined array just holding some simple preamp source selection names (Computer, Tuner, TV /AV etc etc), so of course the text remains corrupted and eventually gets displayed on the LCD.
Code: |
char sourceNames[7][21] = { "Computer", "CD / DVD", "AUX", "Tuner", "Tape", "TV / AV", "MP3 Player" };
|
"Tape" is the one that's currently corrupted, though it has been other things in the past like "Tuner" and "CD / DVD".
From the .lst, here is the above array being assigned at main()
Code: |
1D28 0E43 07364 MOVLW 43
1D2A 6F92 07365 MOVWF x92
1D2C 0E6F 07366 MOVLW 6F
1D2E 6F93 07367 MOVWF x93
1D30 0E6D 07368 MOVLW 6D
1D32 6F94 07369 MOVWF x94
1D34 0E70 07370 MOVLW 70
1D36 6F95 07371 MOVWF x95
1D38 0E75 07372 MOVLW 75
1D3A 6F96 07373 MOVWF x96
1D3C 0E74 07374 MOVLW 74
1D3E 6F97 07375 MOVWF x97
1D40 0E65 07376 MOVLW 65
1D42 6F98 07377 MOVWF x98
1D44 0E72 07378 MOVLW 72
1D46 6F99 07379 MOVWF x99
1D48 6B9A 07380 CLRF x9A
1D4A 6B9B 07381 CLRF x9B
1D4C 6B9C 07382 CLRF x9C
1D4E 6B9D 07383 CLRF x9D
1D50 6B9E 07384 CLRF x9E
1D52 6B9F 07385 CLRF x9F
1D54 6BA0 07386 CLRF xA0
1D56 6BA1 07387 CLRF xA1
1D58 6BA2 07388 CLRF xA2
1D5A 6BA3 07389 CLRF xA3
1D5C 6BA4 07390 CLRF xA4
1D5E 6BA5 07391 CLRF xA5
1D60 6BA6 07392 CLRF xA6
1D62 0E43 07393 MOVLW 43
1D64 6FA7 07394 MOVWF xA7
1D66 0E44 07395 MOVLW 44
1D68 6FA8 07396 MOVWF xA8
1D6A 0E20 07397 MOVLW 20
1D6C 6FA9 07398 MOVWF xA9
1D6E 0E2F 07399 MOVLW 2F
1D70 6FAA 07400 MOVWF xAA
1D72 0E20 07401 MOVLW 20
1D74 6FAB 07402 MOVWF xAB
1D76 0E44 07403 MOVLW 44
1D78 6FAC 07404 MOVWF xAC
1D7A 0E56 07405 MOVLW 56
1D7C 6FAD 07406 MOVWF xAD
1D7E 0E44 07407 MOVLW 44
1D80 6FAE 07408 MOVWF xAE
1D82 6BAF 07409 CLRF xAF
1D84 6BB0 07410 CLRF xB0
1D86 6BB1 07411 CLRF xB1
1D88 6BB2 07412 CLRF xB2
1D8A 6BB3 07413 CLRF xB3
1D8C 6BB4 07414 CLRF xB4
1D8E 6BB5 07415 CLRF xB5
1D90 6BB6 07416 CLRF xB6
1D92 6BB7 07417 CLRF xB7
1D94 6BB8 07418 CLRF xB8
1D96 6BB9 07419 CLRF xB9
1D98 6BBA 07420 CLRF xBA
1D9A 6BBB 07421 CLRF xBB
1D9C 0E41 07422 MOVLW 41
1D9E 6FBC 07423 MOVWF xBC
1DA0 0E55 07424 MOVLW 55
1DA2 6FBD 07425 MOVWF xBD
1DA4 0E58 07426 MOVLW 58
1DA6 6FBE 07427 MOVWF xBE
1DA8 6BBF 07428 CLRF xBF
1DAA 6BC0 07429 CLRF xC0
1DAC 6BC1 07430 CLRF xC1
1DAE 6BC2 07431 CLRF xC2
1DB0 6BC3 07432 CLRF xC3
1DB2 6BC4 07433 CLRF xC4
1DB4 6BC5 07434 CLRF xC5
1DB6 6BC6 07435 CLRF xC6
1DB8 6BC7 07436 CLRF xC7
1DBA 6BC8 07437 CLRF xC8
1DBC 6BC9 07438 CLRF xC9
1DBE 6BCA 07439 CLRF xCA
1DC0 6BCB 07440 CLRF xCB
1DC2 6BCC 07441 CLRF xCC
1DC4 6BCD 07442 CLRF xCD
1DC6 6BCE 07443 CLRF xCE
1DC8 6BCF 07444 CLRF xCF
1DCA 6BD0 07445 CLRF xD0
1DCC 0E54 07446 MOVLW 54
1DCE 6FD1 07447 MOVWF xD1
1DD0 0E75 07448 MOVLW 75
1DD2 6FD2 07449 MOVWF xD2
1DD4 0E6E 07450 MOVLW 6E
1DD6 6FD3 07451 MOVWF xD3
1DD8 0E65 07452 MOVLW 65
1DDA 6FD4 07453 MOVWF xD4
1DDC 0E72 07454 MOVLW 72
1DDE 6FD5 07455 MOVWF xD5
1DE0 6BD6 07456 CLRF xD6
1DE2 6BD7 07457 CLRF xD7
1DE4 6BD8 07458 CLRF xD8
1DE6 6BD9 07459 CLRF xD9
1DE8 6BDA 07460 CLRF xDA
1DEA 6BDB 07461 CLRF xDB
1DEC 6BDC 07462 CLRF xDC
1DEE 6BDD 07463 CLRF xDD
1DF0 6BDE 07464 CLRF xDE
1DF2 6BDF 07465 CLRF xDF
1DF4 6BE0 07466 CLRF xE0
1DF6 6BE1 07467 CLRF xE1
1DF8 6BE2 07468 CLRF xE2
1DFA 6BE3 07469 CLRF xE3
1DFC 6BE4 07470 CLRF xE4
1DFE 6BE5 07471 CLRF xE5
1E00 0E54 07472 MOVLW 54
1E02 6FE6 07473 MOVWF xE6
1E04 0E61 07474 MOVLW 61
1E06 6FE7 07475 MOVWF xE7
1E08 0E70 07476 MOVLW 70
1E0A 6FE8 07477 MOVWF xE8
1E0C 0E65 07478 MOVLW 65
1E0E 6FE9 07479 MOVWF xE9
1E10 6BEA 07480 CLRF xEA
1E12 6BEB 07481 CLRF xEB
1E14 6BEC 07482 CLRF xEC
1E16 6BED 07483 CLRF xED
1E18 6BEE 07484 CLRF xEE
1E1A 6BEF 07485 CLRF xEF
1E1C 6BF0 07486 CLRF xF0
1E1E 6BF1 07487 CLRF xF1
1E20 6BF2 07488 CLRF xF2
1E22 6BF3 07489 CLRF xF3
1E24 6BF4 07490 CLRF xF4
1E26 6BF5 07491 CLRF xF5
1E28 6BF6 07492 CLRF xF6
1E2A 6BF7 07493 CLRF xF7
1E2C 6BF8 07494 CLRF xF8
1E2E 6BF9 07495 CLRF xF9
1E30 6BFA 07496 CLRF xFA
1E32 0E54 07497 MOVLW 54
1E34 6FFB 07498 MOVWF xFB
1E36 0E56 07499 MOVLW 56
1E38 6FFC 07500 MOVWF xFC
1E3A 0E20 07501 MOVLW 20
1E3C 6FFD 07502 MOVWF xFD
1E3E 0E2F 07503 MOVLW 2F
1E40 6FFE 07504 MOVWF xFE
1E42 0E20 07505 MOVLW 20
1E44 6FFF 07506 MOVWF xFF
1E46 0E41 07507 MOVLW 41
1E48 0101 07508 MOVLB 1
1E4A 6F00 07509 MOVWF x00
1E4C 0E56 07510 MOVLW 56
1E4E 6F01 07511 MOVWF x01
1E50 6B02 07512 CLRF x02
1E52 6B03 07513 CLRF x03
1E54 6B04 07514 CLRF x04
1E56 6B05 07515 CLRF x05
1E58 6B06 07516 CLRF x06
1E5A 6B07 07517 CLRF x07
1E5C 6B08 07518 CLRF x08
1E5E 6B09 07519 CLRF x09
1E60 6B0A 07520 CLRF x0A
1E62 6B0B 07521 CLRF x0B
1E64 6B0C 07522 CLRF x0C
1E66 6B0D 07523 CLRF x0D
1E68 6B0E 07524 CLRF x0E
1E6A 6B0F 07525 CLRF x0F
1E6C 0E4D 07526 MOVLW 4D
1E6E 6F10 07527 MOVWF x10
1E70 0E50 07528 MOVLW 50
1E72 6F11 07529 MOVWF x11
1E74 0E33 07530 MOVLW 33
1E76 6F12 07531 MOVWF x12
1E78 0E20 07532 MOVLW 20
1E7A 6F13 07533 MOVWF x13
1E7C 0E50 07534 MOVLW 50
1E7E 6F14 07535 MOVWF x14
1E80 0E6C 07536 MOVLW 6C
1E82 6F15 07537 MOVWF x15
1E84 0E61 07538 MOVLW 61
1E86 6F16 07539 MOVWF x16
1E88 0E79 07540 MOVLW 79
1E8A 6F17 07541 MOVWF x17
1E8C 0E65 07542 MOVLW 65
1E8E 6F18 07543 MOVWF x18
1E90 0E72 07544 MOVLW 72
1E92 6F19 07545 MOVWF x19
|
If I then search for xE7, which is apparently the second character in the "Tape" string, I get various results of this location being reused.
Code: |
04795 ....................
04796 .................... //
04797 .................... // Clear the display
04798 .................... //
04799 .................... void lcd_ClearDisplay()
04800 .................... {
04801 .................... lcd_SendCommand(0x01);
1728 0E01 04802 MOVLW 01
172A 6FE7 04803 MOVWF xE7
172C EC9D F004 04804 CALL 093A
1730 6A18 04805 CLRF 18
1732 BEF2 04806 BTFSC FF2.7
1734 8E18 04807 BSF 18.7
1736 9EF2 04808 BCF FF2.7
04809 .................... delay_ms(2);
|
Code: |
04771 .................... //
04772 .................... // Turn the display on / off
04773 .................... //
04774 .................... void lcd_display(short enable)
04775 .................... {
04776 .................... if (enable)
1746 53DF 04777 MOVF xDF,F
1748 E005 04778 BZ 1754
04779 .................... {
04780 .................... lcd_SendCommand(0x0C);
174A 0E0C 04781 MOVLW 0C
174C 6FE7 04782 MOVWF xE7
174E EC9D F004 04783 CALL 093A
04784 .................... } else {
1752 D004 04785 BRA 175C
04786 .................... lcd_SendCommand(0x08);
1754 0E08 04787 MOVLW 08
1756 6FE7 04788 MOVWF xE7
1758 EC9D F004 04789 CALL 093A
04790 .................... }
04791 ....................
04792 .................... //delay_ms(1);
04793 .................... }
175C 0C00 04794 RETLW 00
|
and some others...
So, I guess my question is... is there any simple way to tell the compiler to stop doing this sort of thing!? I have tried turning the optimization setting in the global compile options right down, but this has no effect. I have also tried making all variables static, or just the global variables static, both of which also doesn't seem to solve the issue.
I am using multiple source files. Though it compiles fine, perhaps this is a problem....?
Unless requested I won't post the code yet as there's a fair bit of it, but here's my fuses and basic config stuff
Code: |
#include <18F2520.h>
#device PIC18F2520 *=16 ADC=10 ICD=FALSE HIGH_INTS=FALSE
//
// Configuration
//
//////// Fuses: LP,XT,HS,RC,EC,EC_IO,H4,RC_IO,PROTECT,NOPROTECT
//////// Fuses: BROWNOUT_NOSL,BROWNOUT_SW,NOBROWNOUT,BROWNOUT,WDT1,WDT2,WDT4
//////// Fuses: WDT8,WDT16,WDT32,WDT64,WDT128,WDT,NOWDT,BORV20,BORV27,BORV42
//////// Fuses: BORV45,PUT,NOPUT,CPD,NOCPD,NOSTVREN,STVREN,NODEBUG,DEBUG
//////// Fuses: NOLVP,LVP,WRT,NOWRT,WRTD,NOWRTD,IESO,NOIESO,FCMEN,NOFCMEN
//////// Fuses: PBADEN,NOPBADEN,CCP2B3,CCP2C1,WRTC,NOWRTC,WRTB,NOWRTB,EBTR
//////// Fuses: NOEBTR,EBTRB,NOEBTRB,CPB,NOCPB,LPT1OSC,NOLPT1OSC,MCLR,NOMCLR
//////// Fuses: XINST,NOXINST,INTRC,INTRC_IO,WDT256,WDT512,WDT1024,WDT2048
//////// Fuses: WDT4096,WDT8192,WDT16384,WDT32768
#fuses INTRC_IO
#fuses NOWDT
#fuses NOPROTECT
#fuses NOLVP
#fuses NOPUT
#fuses BROWNOUT
#fuses BORV42
#fuses NODEBUG
#fuses NOXINST
#fuses MCLR
#fuses STVREN
#fuses IESO
#fuses FCMEN
#fuses NOPBADEN
#use delay(clock=32M)
|
Sorry for the lengthy post! |
|
|
markie
Joined: 24 Dec 2007 Posts: 2
|
|
Posted: Mon Dec 24, 2007 4:02 pm |
|
|
Aha!
With some more searching (I have been searching these forums for a few hours too), I came across this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=32221&highlight=linker
I read the three links posted and rearranged my source files to do it the 'traditional' CCS way, rather than using the linker. It seems to keep it modular-ish, and I flashed this compile...... no more corruption on the text! I guess it must be the linker to blame.
I guess it has to recompile the lot each time, rather than just changed modules and relinking....... but at least it seems to be working now. I'm over the moon!
Thanks PCM! Should the problem reappear using this method I will post back, but I have a feeling it won't |
|
|
|
|
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
|