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

CCS TAKES LONG BLANK BLOCK OF MEMORY

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
manoel_filho
Guest







CCS TAKES LONG BLANK BLOCK OF MEMORY
PostPosted: Tue May 02, 2006 8:37 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 02, 2006 8:45 am     Reply with quote

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







PostPosted: Tue May 02, 2006 9:03 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue May 02, 2006 5:23 pm     Reply with quote

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







PostPosted: Wed May 03, 2006 7:16 am     Reply with quote

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







PostPosted: Wed May 03, 2006 8:57 am     Reply with quote

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







PostPosted: Wed May 03, 2006 11:11 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 03, 2006 11:55 am     Reply with quote

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







PostPosted: Wed May 03, 2006 1:25 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 03, 2006 1:55 pm     Reply with quote

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







PostPosted: Mon May 08, 2006 7:03 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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