|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24EP Out of rom question [CLOSED] |
Posted: Thu Oct 21, 2021 1:02 pm |
|
|
Device: PIC24EP512GP806
Compiler: 5.026
Hi all,
I realize my function is too big but how do I really interpret the following below... in a sense that how many bytes am I overflowing by... or how many bytes do I need to get rid of by looking at the following?
I can probably free-up some space by modifying some plain english fprintf to user output but I'd really like to know how to calculate the excess bytes from the message below:
Seg 40000-4FFFE, C62C left, need 0CD7A
Seg 50000-557FE, 5800 left, need 0CD7A
Seg 00000-00002, 0000 left, need 0CD7A Reserved
Seg 00004-001FE, 0000 left, need 0CD7A Reserved
Seg 00200-0FFFE, 0000 left, need 0CD7A
Seg 10000-1FFFE, 0000 left, need 0CD7A
Seg 20000-2FFFE, 000C left, need 0CD7A
Seg 30000-3FFFE, 0000 left, need 0CD7A
Out of ROM, A segment or the program is too large [function name]
Thanks!
Ben
Last edited by benoitstjean on Mon Oct 25, 2021 8:31 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 21, 2021 8:55 pm |
|
|
Here is the math:
Code: |
CD7A Your routine needs this many ROM words.
- C62C Only this much ROM is left available in the largest free area.
-------------
74E Your routine is too big by this many ROM words.
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Fri Oct 22, 2021 1:24 am |
|
|
Can you compile it before your last change?.
If so, then select the 'statistics' tab. This will show the total ROM, RAM etc.,
but more importantly will then have little pie charts below this showing
'functions'. Below this will be a list of the functions, in descending order of
size. It is the top ones in this list that will be where the problem will then
appear.
It does sound as if you are walking into the 'put everything in one piece'
approach. For example I've got a PIC24 program here that uses 324000
bytes of ROM, but the statistics have my largest function at just 4% of the
ROM size.
You have a single entity that is CD7A in size. If you can split this down
so some small part of it can be put elsewhere, there is then a reasonable
amount of space left. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Oct 22, 2021 4:41 am |
|
|
Hi guys,
Thanks for the info. Your responses go along what I had in mind.
For sure this function is too big but I can probably split it into three sections. This function treats responses to AT commands: responses that start with +, OK responses and unsollicited responses that do not fit into the two previous categories. It'll complicate things a bit that should work.
Thanks for your time and help.
Cheers!
Ben |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Fri Oct 22, 2021 4:49 am |
|
|
I'm thinking....
Seg 40000-4FFFE, C62C left, need 0CD7A
That segment of ROM is 65,534 bytes in size,
You 'need 0CD7A' ,which is 52,602 bytes.
So it should fit but...there's already some used , as only 'C62C left', 50,732
You actually have the physical space ( 2 segment have enough bytes),but a function cannot span 2 segments.
Now you could try to rearrange the order of your functions.In the past this would make it all fit. This might allow the compiler to make better use of ROM. I have no idea if the newer compiler 'sees' the 'it should fit, if I rearrange things', feature but I suspect it doesn't.
If that doesn't work, then you will have to break up the long function, into smaller 'subfuctions'. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Fri Oct 22, 2021 10:31 am |
|
|
You may also find you can massively reduce usage, by simply using
you own routines for things inside the function. Generally, CCS tends to
'inline' it's own functions, whereas if you encapsulate these in your own
functions this is avoided. Result much smaller code. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Oct 22, 2021 12:12 pm |
|
|
Hmmm, well I tried cutting down this massive function and it didn't change a thing... however, I found something interesting.
Without going into details, this massive function (Function A) parses AT responses received from a modem. As explained in my initial post, the modem can return to the PIC three types of messages: some that start with a '+' e.g. +SERVERSTOP, +CSQ, +CMT etc, others are simple 'OK' responses and others are called unsollicited responses - responses I am not expecting suchas an incoming call (RING) or a missed call (MISSED_CALL).
For the '+' messages, I have a total of 42 to check against and as soon as the correct one is found, then the code in that message is processed and Function A exits. So I took all '+' messages out of function A and put them in a separate function (Function B) then in Function A, where these messages were checked, instead, I now call Function B.
Well turns-out that it still doesn't solve the issue. So now, I went by elimination and 'framed' each message check with a bunch of #ifdef's / #endif's:
#ifdef CMT <code> #endif
#ifdef SERVERSTOP <code> #endif
#ifdef NETOPEN <code> #endif
#ifdef CSQ <code> #endif
At the very begining of Function B, I have 42 #define's that enable or not these #ifdef:
#define _CMT
#define _SERVERSTOP
#define NETOPEN <-- This one is enabled, doesn't have the _ in front
#define _CSQ
In the example above, I was testing if the NETOPEN message was problematic. But at first, I disabled all messages and recompiled. I ended-up at 75%. Then I started going by batch and enabling a few at a time. Each time, the % usage was increasing by only 2-3.... until I hit the +CMT message which, as soon as enabled, I got the OUT OF ROM error. At the end, I re-enabled every message except +CMT and was still compiling at 75%. Then, as soon as I re-enabled +CMT, I got the error.
Inside that +CMT message (which is generated when an incoming SMS arrives), I do a bunch of things like extract the 'from' number, message, date and time. Then a bunch of checks are done like if the SMS arrived while the modem was IP connected or not and so on. If all checks go through and the message is ready to be processed, then the very last line before exiting the +CMT message is a function called SMS_ProcessMessage( ClientNumber, Message );.
If I disable this function and recompile, the ROM usage drops to 75%. If I re-enable this function, then I get the error.
The only thing I can think that may resolve this particular problem as a quick fix is to start a timer and on expiry, then call that function... but it's not the most elegant way of fixing the problem...
What now? How can this happen? Any suggestion?
Thanks!
Ben
[EDIT] Went back to a month old version of code that compiles just fine although I was at 93% and if I comment-out that line, well surprise surprise, my ROM usage drops to 75%! This is driving me crazy! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Fri Oct 22, 2021 12:47 pm |
|
|
Ok, maybe I'm crazy( don't reply !) but...
why not use a 42 long switch, that if the 'case' is found, then calls a function specific to that 'case' ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 22, 2021 12:53 pm |
|
|
It seems to me that you have got functions within functions within
functions. So the one CMT function actually has a ton of code in it.
What if you put #separate in front of the CMT function.
Would it then compile ?
Or put it in front of the SMS_ProcessMessage() function.
Also, what is your stack usage vs. the amount available ?
Look at the top of the .LST file to get this info. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Fri Oct 22, 2021 1:10 pm |
|
|
@Temtronic: Can't do a switch on text strings... unless there's a trick I am not aware of!
@PCM Programmer: You are correct, I realized that SMS_ProcessMessage() is also a big function and this is where it's starting to be beyond my comprehension... but I thought that if you had a function - even if big - it would simply "jump" to that function therefore not cause any problems?
From the top of my LST file from the last successful compile. I guess because at the moment, it does not compile and I get the error:
ROM used: 261170 bytes (75%)
Largest free fragment is 65536
RAM used: 27550 (52%) at main() level
31331 (59%) worst case
Stack used: 1458 locations (146 in main + 1312 for interrupts)
Stack size: 2048
[EDIT] As for the #separate command, I've never used that. It appears I must add parameters? Says "ERROR a numerical parameter must appear here"...
[EDIT 2] Also, I tried a sloppy "patch" by starting a timer and upon expiry, then call SMS_ProcessMessage() but that still won't compile and give me the out of rom error! Argh!
[EDIT 3] I went into SMS_ProcessMessage() and disabled a few SMS commands and it now compiles.... soooo the question is.... how do I keep my code but don't run into this problem! I guess I can always fiddle around with SMS_ProcessMessage() next week... or unless a better solution is available?
Thanks guys!
Ben |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Fri Oct 22, 2021 2:21 pm |
|
|
Used to be (OK early Hayes modems..... AT responses had numbers as well as text for the replies) don't know if there's a list of text vs numbers for new modems.
Hmm..maybe you could make up your own table though ?
Get a response from modem, decode text response into a number, then use that number as the 'case' of a switch, that then jumps to the appropriate 'function' code ?
I know a few extra steps, but it would break down the code into smaller pieces, might allow the compiler to fit it into ROM. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Fri Oct 22, 2021 3:53 pm |
|
|
The #separate must appear in front of the function declaration as well as in front of the function definition. Try again. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Sat Oct 23, 2021 1:10 am |
|
|
Yes. It is critical to understand that the stuff you separate, needs to be
declared as such. The compiler always defaults to inlining pretty much
everything unless you explicitly tell it not to. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Sun Oct 24, 2021 7:20 am |
|
|
Thanks for the details, will try this tomorrow morning when I get to work. |
|
|
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Mon Oct 25, 2021 5:54 am |
|
|
Alrighty.... so this #separate pre-processor direction is new to me and way above my head to be honest.
How do I use it exactly?
Do I need to put any parameters? I am using compiler version 5.026.
I have #separate on the line just before the function call and I get the following two errors:
*** Error 51 "c:\{folder}\{filename.c}" Line 6100(0,1): A numeric expression must appear here
*** Error 51 "c:\{folder}\{filename.c}" Line 9317(0,1): A numeric expression must appear here {Function_Name}
If I look in the CCS online help page 174, it appears that for PCD (second example), this pre-processor directive requires parameters and this is where I am at a complete loss:
Examples:
#separate
swapbyte (int*a, int*b){
int t;
t=*a
*a=*b;
*b=t;
}
[PCD]
#separate ARG=W0:W7 AVOID=W8:W15 DND=W8:W15
swapbyte (int*a, int*b){
int t;
t=*a
*a=*b;
*b=t;
}
In my main project's header file, I use #build ( stack = 2048 ).
Any recommendations? Thanks for your time and help.
Benoit |
|
|
|
|
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
|