|
|
View previous topic :: View next topic |
Author |
Message |
manoel_filho Guest
|
CCS TAKES LONG BLANK BLOCK OF MEMORY |
Posted: Tue May 02, 2006 8:37 am |
|
|
Hi.
During development, the CCS compiler start to say "one segment of this program is too large" but I only uses 58% of the program memory, and the routine i try to insert is only 3 bytes wise. other strange point is that whem i go to program memory, a large block of memory is blank, and the codes restart again. I realy don�t know what happens, I use CCS with MPLAB 7.31, and 16f876A. My program uses a lot of printf function to write to a LCD.
Can somebody help me? |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue May 02, 2006 8:45 am |
|
|
That's happened to me before. One section, of your code, is too large probably due to your printf statements. Printf creates a BUTT load of code and if you have a lot of them in your main() then this can happen. The code fits into Blocks of memory and if one of your routines is too large it would 'spill' out of that block. Try splitting your printf's into a separate routine and then call it from your main().
Ronald |
|
|
manoel_filho Guest
|
|
Posted: Tue May 02, 2006 9:03 am |
|
|
You tell me that i shound not have printf function on mais section, is that correctly? I will get all my printf function out of main block, and call them for a sub routine, will that work?
What is the best way to use the printf ?
thanks a lot. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue May 02, 2006 5:23 pm |
|
|
You can have printf statements in your main() but you need to keep your code 'modular'. Bunch the code that does one type of thing in a routine and call it from main when you need to. Then, bunch other code that does some different stuff together in a routine. If your main() is a long heafty section of your code, with very few separate routines, then you could run out of memory without using all of the available memory in the PIC. Try splitting things up a bit and see if it works. I had some printf()'s in my main that had some long strings and I ran out of memory. I simply put them in their own routine, called them from main() where I originally had them and things were okay.
Ronald |
|
|
manoel_filho Guest
|
|
Posted: Wed May 03, 2006 7:16 am |
|
|
Hi.
Does SPRINTF replace PRINTF without this memory lost? I start to think that I didn�t buy the best compiler on the market!!! Please tell me that I�m wrong. |
|
|
Ttelmah Guest
|
|
Posted: Wed May 03, 2006 8:57 am |
|
|
It is not a matter of 'losing' memory.
The PIC (on the older 16/12 devices), has the program memory split up into blocks. Think think of it like a book, which is printed in a series of sections, and where the company typesetting the book, _must_ be able to split it into these sections to print. If you wrote a story, as a single 'long' chapter, they would be unable to fit it into the sections. If instead you split it into 'chapters' (subroutines in computer terms), the company, can instead split the text at these points, and work out how to get it all into the sections. The size of the 'sections', varies wth different processors.
Now PRINTF was mentioned, because this can be a very large user of memory. This has nothing really to do with it's printing ability (this only uses a few bytes), but with the amount of work involved, in actually formatting the values to send. Imagine that you wanted to actually output a number yourself, without using 'printf'. Even for a simple integer, you would need repeated division/subtractions/multiplications, then convertion of the individual digits to ASCII. SPRINTF, has exactly the same overhead. If (worse), you use floating point arithmetic, a simple 'print', can become thousands of instructions, and instructions like sin/cos etc., are also heavy users.
In a very real sense, you have to learn to be somewhat structured in your programming. As another poster has said, you need to actually split up the code into subroutines, which then allows the compiler to deal with the _processor_ limitations in this regard.
The manual describes what this error means, and gives a description of how to deal with it, while much more complete descriptions have appeared here.
I is very important to understand, that unlike compilers on a PC, where if code is a few hundred bytes larger than your available memory, it is not a 'fatal' error, since the OS, can 'swap' memory onto disk, on the PC, you have to design your programs within the limitations of the hardware.
Best Wishes |
|
|
manoel_filho Guest
|
|
Posted: Wed May 03, 2006 11:11 am |
|
|
Ok,
Thanks a lot, but I eliminated everything on the main section, the problem vanish, then I put just a little bit of the main section, the problem still missed, so I put one call to one subroutine and the problem appears again, with less size of course, but it appears again. I have to show several routines that involves printf function and, besides of 8k of 16f876A, I think it will not fit, because the compiler is not able to handle this "BOOK SIZE" like you said.
How must I proceed to solve this problem?, make every screen outside of main code, and call them by the name e.g.
I got a screen called
void screen_config_0()
{
cmd_lcd(0x80);
printf(esc_lcd,� main menu�);
}
main()
{
setup_timer_1 (t1_external | t1_div_by_1);
t1oscen=1;
adcon0=(0b11000001);
adcon1=(0b10001110);
set_tris_a(0b00111011);
set_tris_b(0b00000001);
porta=0x00;
portb=0x00;
ext_int_edge(0, H_TO_L);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER1);
lcd_init();
loop:
while(page==1)
{
do something here......
if(!menu)
{
clear_lcd();
screen_config_0(); //call subroutine
}
}
goto loop:
}
That�s it? This is the best way to use this kind of function?
Thanks a lot. |
|
|
jspencer
Joined: 22 Dec 2003 Posts: 57 Location: Boise, ID USA
|
|
Posted: Wed May 03, 2006 11:55 am |
|
|
Code: |
loop:
while(page==1)
{
do something here......
if(!menu)
{
clear_lcd();
screen_config_0(); //call subroutine
}
}
goto loop: |
Looks like you are mixing assembly and C if the above is from your source. Why not just do this:
Code: |
while (1) {
while(page==1)
{
do something here......
if(!menu)
{
clear_lcd();
screen_config_0(); //call subroutine
}
}
}
|
It's hard to know what you are trying to do with limited information. If you are using assembly mixed in with your C code you have to use the #asm and #endasm around your assembly code. |
|
|
manoel_filho Guest
|
|
Posted: Wed May 03, 2006 1:25 pm |
|
|
No, page is a variable tat can change his value during the system operation.
loop:
while(!page)
{
block of commands here;
if(!up)
{
another block of function here;
page=1;
}
}
while(page==1)
{
block of commands here;
if(!dw)
{
another block of function here;
page=2;
}
}
while(page==2)
{
and so on.....
}
goto loop;
}
I start to think that I have to change the way I do my programs flows, this is happening because my programs are getting more complex and bigger than when I started to work with microprocessors, I�m not kidding by now, and have to learn more about program flows, and program structures. May be this is the basic cause of my problems, I learn this way to program and its difficult to change.... |
|
|
Fro_Guy
Joined: 26 Apr 2006 Posts: 12
|
|
Posted: Wed May 03, 2006 1:55 pm |
|
|
Keep you main function in 1 bank and small. Take your code that you do have, and make subroutines out of them to make the main function small. In your code when u have a block of fyunctions, take each one of thoes blocks and put them into there own subroutine. Then the compiler should take care if switching banks
good luck[/code] |
|
|
manoel_filho Guest
|
|
Posted: Mon May 08, 2006 7:03 am |
|
|
hi.
I take the code out of the mais section, bissides of the error "one segment of this program is too large" vanishs, I still with one big block of memory blank. The part of the code that do this is a 5 variables adjustment that the user have to set up, 4 of then are int (8bits) end 1 is long int (16 bits). This is critical to my product work fine, and if anybody have an idea to reduce or eliminates this long blank on program memory, please advise.
the code is:
void car_setup()
{
w_d_t();
if(!aux_1)tela_car();
if(!menu&!deb)
{
zera_timer();
aux_blink++; //select the variable to be changed
tela_car();
if(aux_blink==6)aux_blink=0;
}
if(!aux_blink) //a variable
{
if(aux_1==40)seta_rigth(0x8b);
if(!up&!deb)
{
a++;
tela_car();
seta_rigth(0x8b);
}
if(!dw&!deb)
{
a--;
tela_car();
seta_rigth(0x8b);
}
}
if(aux_blink==1) //b variable
{
if(aux_1==40)seta_rigth(0xc0);
if(!up&!deb)
{
delay_ms(50);
b++;
tela_car();
seta_rigth(0xc0);
}
if(!dw&!deb)
{
delay_ms(100);
b--;
tela_car();
seta_rigth(0xc0);
}
}
if(aux_blink==2) //c variable
{
if(aux_1==40)seta_rigth(0x90);
if(!up&!deb&dw)
{
c++;
tela_car();
seta_rigth(0x90);
}
if(!dw&!deb)
{
if(up)delay_ms(100);
c--;
tela_car();
seta_rigth(0x90);
}
}
if(aux_blink==3) //d variable (long int)
{
if(aux_1==40)seta_rigth(0xcb);
if(!up&!deb)
{
delay_ms(50);
d++;
tela_car();
seta_rigth(0xcb);
}
if(!dw&!deb)
{
delay_ms(100);
d--;
tela_car();
seta_rigth(0xcb);
}
}
if(aux_blink==4) //e variable
{
if(aux_1==40)seta_rigth(0x9b);
if(!up&!deb)
{
delay_ms(50);
e++;
tela_car();
seta_rigth(0x9b);
}
if(!dw&!deb)
{
delay_ms(100);
e--;
tela_car();
seta_rigth(0x9b);
}
}
if(aux_blink==5) //out of configuration, returs to maism menu.
{
limpa_lcd();
tela_sai_car();
page=11;
}
}
This code provides the 5 variables adjustments on the LCD. dw, up and menu are 3 buttons that I use to modfy and change the valiable in adjustments.
tela_car is a function that shows the variables on LCD every time one changes occuors.
How can I ensure that the mais part is on bank1?, like said before for another frind.
Thanks. |
|
|
|
|
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
|