|
|
View previous topic :: View next topic |
Author |
Message |
cagacug
Joined: 14 Apr 2004 Posts: 5
|
16F877 "Not enough RAM for all variables" err but |
Posted: Wed Sep 29, 2004 7:17 am |
|
|
hi to all,
I am programing a little big program and having a sticky error which I could not manage to get rid of it. If you can give me some ideas I will be thankfull.
16f877
CCS 3.200
the xxx.h file
Code: | #include "D:\16F877.h"
#device ICD=TRUE
#device *=16
#device ADC=10
#use delay(clock=20000000)
#fuses NOWDT,HS, PUT, NOPROTECT, BROWNOUT, NOLVP, NOCPD, NOWRT, DEBUG |
begin of main file
Code: | #include "D:\xxx.h"
#include "D:\2416.c"
#include "D:\ds1307.c"
#include "D:\ds1868.c"
#ZERO_RAM |
have some pointers and a big array in RAM
Code: | int *pram[8]; //vram variables
int lcd_ram1[7][4],lcd_ram2[7][4],lcd_ram3[7][4],
lcd_ram4[7][4],lcd_ram5[7][4],lcd_ram6[7][4],
lcd_ram7[7][4],lcd_ram8[7][4]; |
and have a big table in rom of 1256bytes, so the page 3 is almost not usable!
Code: | #ORG 0x1AFF, 0x1FFF {}
#ROM 0x1AFF = {0,0,0,0,0, |
I am using the interrupts TIMER0 and EXT,
I tried to add a function call(keyb_rx()) to the int EXT ISR and got the "not enough RAM..." error. When I move the function call to main I dont have this error. So this make me to think that interrupts calls need more blocks of ram. Also there is lots of var that I have to use global, speed is concerned so the big array up is 224bytes long. Some funny errors in mind I try to change place of code or delete up to 10 global variables temporarly but no success. May be I am pushing to hard but I dont understand wht it is working when the function is in main?
Here is the .sta file when compiled w success(when the "keyb_rx ()" function is in main)
Code: | ROM used: 5030 (61%)
5505 (67%) including unused fragments
3 Average locations per line
9 Average locations per statement
RAM used: 287 (80%) at main() level
313 (87%) worst case
Lines Stmts % Files
----- ----- --- -----
916 478 82 D:\xxx.c
9 0 0 D:\xxx.h
260 0 0 D:\16F877.h
88 23 2 D:\2416.c
112 62 6 D:\ds1307.c
63 22 2 D:\ds1868.c
----- -----
2896 1170 Total
Page ROM % RAM Functions:
---- --- --- --- ----------
0 20 0 1 @delay_ms1
0 87 2 3 @I2C_READ_1_56_57_20000000
0 81 2 1 @I2C_WRITE_1_56_57_20000000
0 13 0 0 init_ext_eeprom
0 143 3 4 write_ds1307
0 25 0 3 @DIV88
0 166 3 6 read_ds1307
0 41 1 2 @MUL88
0 60 1 2 init_ds1307
0 111 2 8 set_pot
0 11 0 0 @const98
0 972 19 19 kol_kaydir_left
0 25 0 5 @MUL1616
0 11 0 0 @goto10262
1 881 18 17 kol_kaydir_right
1 11 0 0 @goto10356
0 80 2 8 load_data
1 368 7 4 keyb_rx
0 4 0 0 EXT_isr
2 1327 26 2 timer0_int
2 8 0 0 @goto10607
2 18 0 0 @goto10659
2 28 1 0 @goto10692
2 28 1 0 @goto10717
0 7 0 0 TMR0_isr
1 402 8 4 main
0 44 1 5 @DIV1616
Segment Used Free
--------- ---- ----
00000-00003 4 0
00004-00039 54 0
0003A-007FF 1901 89
00800-00FFF 1662 386
01000-017FF 1409 639
01800-01AFE 0 767
01AFF-01FFF 0 1281 |
Any diff idea??
Thanks,
caga |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Sep 29, 2004 12:42 pm |
|
|
1. PCM vs. 3.200 is the first one is the new 3.2xx series.
It could easily have a bug that is causing your problem.
2. You don't have a "big array". You have 8 arrays of moderate size.
One thing you might do, is to help the compiler with allocating
the ram. You can use the #locate directive to do this. Example:
#locate lcd_ram1 = 0x110
#locate lcd_ram2 = 0x12C
#locate lcd_ram3 = 0x148
#locate lcd_ram4 = 0x190
#locate lcd_ram5 = 0x1AC
#locate lcd_ram6 = 0x1C8
#locate lcd_ram7 = 0x0A0
#locate lcd_ram8 = 0x0BC
3. Look at this section in the 16F877 data sheet:
FIGURE 2-3: PIC16F877/876 REGISTER FILE MAP
All of your ram variables have to fit into those four ram banks.
Notice how the ram banks have different sizes. You have to pick
locations for your arrays that will fit into the given banks, and
also allow the compiler some room to fit the other variables
into the remaining space.
4. Try not to use #locate in the common RAM area at 0x70-7F
(and also the corresponding addresses for banks 1-3) because
the compiler likes to use this area. Also avoid using 0x20-0x2F
for the same reason. |
|
|
cagacug
Joined: 14 Apr 2004 Posts: 5
|
bingo! |
Posted: Wed Sep 29, 2004 1:05 pm |
|
|
Thats exactly the solution, thank you!
This shows to me not to trust much to the compiler's allocation!!! |
|
|
Alex Guest
|
|
Posted: Mon Oct 04, 2004 8:50 am |
|
|
Don't you have to switch between banks when you use the #locate in different banks ? |
|
|
Ttelmah Guest
|
|
Posted: Mon Oct 04, 2004 10:15 am |
|
|
Alex wrote: | Don't you have to switch between banks when you use the #locate in different banks ? |
No.
That is part of the 'point' about *=16. Once this is set as a preprocessor directive, the compiler uses a 16bit address for the RAM. It then automatically switches banks as needed. You could, if you wanted just to store a single array in one of the higher banks, not bother to use this directive (which would then limit all the compilers 'own' accesses to the bottom bank), and manually switch banks yourself, for the accesses needing the higher bank(s) (and switch back as well). The advantage of this is that the main code would be quicker and smaller without the bank switch instructions.
Best Wishes |
|
|
|
|
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
|