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 support@ccsinfo.com

Error 71 out of ROM when using fat.c
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

Error 71 out of ROM when using fat.c
PostPosted: Tue Oct 30, 2018 7:37 am     Reply with quote

I am getting Error 71 out of ROM when I am trying to program my PIC16F19176 on v5.078 of CCS. From reading around here, I understand that I am running over the page boundaries of the program ROM with a single function while I am trying to use the fat.c library when I call fatopen()

Code:

Error#71  Out of ROM, A segment or the program is too large    set_file
  Seg 01000-017FF, 0473 left, need 00DF6
  Seg 01800-01FFF, 0800 left, need 00DF6
  Seg 02000-027FF, 0800 left, need 00DF6
  Seg 02800-02FFF, 0800 left, need 00DF6
  Seg 03000-037FF, 0800 left, need 00DF6
  Seg 03800-03FFF, 0800 left, need 00DF6
  Seg 00000-00002, 0000 left, need 00DF6 Reserved
  Seg 00003-00003, 0001 left, need 00DF6
  Seg 00004-0007D, 0000 left, need 00DF6 Reserved
  Seg 0007E-007FF, 0013 left, need 00DF6
  Seg 00800-00FFF, 001F left, need 00DF6


The function that is too big is set_file() and it appears that it is fatsetpos() that set_file() calls that is the killer. So, I added #separate before the function prototype and another #separate before the function definition just in case it tried to compile inline. The program compiles now, except that I get stack underflow reset (determined using restart_cause()).

Here is my main function where I call fatopen()
Code:

char myname[] = "name.txt";
FILE mystream;

int main(int argc, char** argv)
{
    fat_init();                         // returns with no error
    disp_fat_stats();                   // displays correct stats based on what I read off the card from a hex editor

    int16 cause =  restart_cause();     // returns 0x0F7F
    fprintf(PC, "restart cause: %lx\r\n", cause);

    fprintf(PC, "attempting to open file\r\n");
    int error = fatopen(myname, "r", &mystream);    // It appears stack underflow occurs here
    fprintf(PC, "fat error: %x\r\n", error);        // code never gets here because of stack underflow

    while (1)
    {

    }
    return 0;
}


Here is where I have added #separate:
Code:
#separate
signed int fatsetpos(FILE* stream, fatpos_t* position); //function prototype

#separate
signed int fatsetpos(FILE* stream, fatpos_t* position) //function definition
{
    // CCS fat.c driver code
}


My question is: Do you guys have any rules on how #separate should be used to prevent this underflow error.

Secondly: I couldn't find this "page size" limitation inside the PIC datasheet in the Memory Organization section. I could only find the total program ROM of 16k words.

Please let me know if I am missing any info that would help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 8:35 am     Reply with quote

First thing, your restart cause may be wrong....

Restart_cause, generally _should_ be called before any function that affects any of the registers holding the restart information. Hence right at the start of the program, not after calling the fat_init, and display functions.
It may be OK, but is very much 'not guaranteed to be right', if you call it later as you are doing. It is dependant on register values that are changed by several things. However the stack underflow/overflow ones would normally not be changed, so this indication is probably real.

You don't show your SPI setup for the card being used?. The fat system is dependant on having the SPI correctly setup with drivers for this.

Fitting FAT filesystem code into a PIC16, is going to be pushing things...
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 30, 2018 8:59 am     Reply with quote

Thanks for the quick reply.

I moved the following line to the very front of main.
Code:
int16 cause = restart_cause();

The restart cause is unchanged.

For SPI setup, I use these setup parameters that mmcsd.c needs:

Code:
#PIN_SELECT SDI1=PIN_C4
#PIN_SELECT SDO1=PIN_C1
#PIN_SELECT SCK1=PIN_C3

#use fast_io(c)
#define MMCSD_PIN_SCL     PIN_C3 //o
#define MMCSD_PIN_SDI     PIN_C4 //i
#define MMCSD_PIN_SDO     PIN_C1 //o
#define MMCSD_PIN_SELECT  PIN_A3 //o


I am confident that my SPI setup to MMCSD is correct. I have been able to use SD card as generic memory when it is unformatted. Formatted as FAT32, I get this from disp_fat_stats():
Code:
First FAT starts at: 0x4000
Data Starts At: 0x003B8400
Root Directory Is At: 0x003B8400
Bytes Per Cluster: 0x1000


If I printf in fat_init() when it is reading the fat info, it is the same as what I see when I manually get the numbers looking through a hex editor.

Anyway to me, your last line is the most telling of what you think of what I'm trying to do :P

It's probably worth looking into using a PIC18 (or maybe even higher) and upgrading my compiler from PCM. Better to change things around here in the prototyping stage rather than applying a bunch of bandaids and having a headache in the future... Along this line, is it worth it to just go straight for the PIC24? This way I can keep using this kind of chip without worrying in the future that I run up against limitations.

I will go take a look at what's available, but do you have any suggestions yourself on what to pay attention to? Also, where in the datasheet would I find these limitations on how large a function can be?

Thanks again!


Last edited by dluu13 on Tue Oct 30, 2018 9:10 am; edited 1 time in total
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 9:09 am     Reply with quote

If you're going to get into 18 series PICs, I recommend the PIC18F46K22. It's been my 'GOTO' PIC for several years. LOTS of I/O including 2 HW UARTS, 2 SPI, 64MHz speed AND good for BOTH 3 AND 5 volt operation. NO need to buy 'L' version of PICs. I've yet to run out of memory too !

Now there's probably a newer PIC BUT if you stick with one, you'll be able to save a LOT of time after you create YOUR known good library of drivers and functions.

Jay
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 30, 2018 9:14 am     Reply with quote

Haha this thread has gone off topic now, but the real story was that I was using an underpowered MCU anyway...

Thanks for that recommendation. I will take a good look at that datasheet. 2 HW UARTS is a huuuge plus for me.

Would you recommend just skipping to PIC24?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 9:51 am     Reply with quote

It's very difficult to give a simple answer to this.

In this case, 99% of PIC 16's, would not actually have enough memory to perform FAT operations. With the 512byte sector buffer, and the sheer size of the code they would struggle.

The PIC18 is quite a large jump forwards. Linear ROM addressing, so no need for 'pages', generally much larger ROM/RAM sizes, and hardware multiply that does noticeably improve the overall speed.

The PIC24/30/33 families can be rivetingly fast by comparison, with speeds like 40MIPS in some cases, again more RAM & ROM. However some of this does come at some costs:
1) Generally much higher power consumption.
2) You often lose at least one pin for the Vcore line.
3) Need for data to be word aligned can lead to issues sometimes with byte sized data.
4) Code is generally bulkier, and much more RAM gets used.
5) Generally lack EEPROM, so code memory (or an external memory) has to be used for non-volatile storage. This is bulky and quite complex.

However they are very quick. It is impressive to be doing things requiring a timing like 200nSec, and actually be having to add delay cycles to get this....
The power use though is noticeably high when compared to PIC16/18 chips.

It is surprising how often building a PIC24 project you still find yourself using a PIC16/18 to do some further I/O.

Some of the newer PIC18's with relocatable peripherals are very nice chips, and the flexibility of this is really nice, especially the chips with DMA. Being able to program something like the ADC to automatically take a sequence of readings and store these is very nice.

I note though that you are using a chip with direct LCD drive. This is a limited ability (remarkably few chips offer this), so if this is needed your choices are very limited.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 30, 2018 10:53 am     Reply with quote

Luckily I don't use the LCD panel.

Wow there's an incredible amount of RAM and ROM on the PIC24 as well, compared to the PIC16 and 18.

I will read some more datasheets, but I am leaning towards the PIC18 for the moment.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 11:56 am     Reply with quote

It's worth also adding that as the chip complexity rises, the design quality needed from your board also goes up.
An old PIC16 or one of the 5v PIC18's can be thrown onto a crude breadboard and run quite well. A full speed PIC24, running the core at under a couple of volts, needs much more careful power rail design, smoothing, and really good ground design for reliability. A 'caveat'....
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 30, 2018 12:17 pm     Reply with quote

Thanks for that tip. Yeah, I saw the way you referenced the speeds and figured that it probably won't run with the way I've just thrown everything on the breadboard haphazard-like.

Just a slightly unrelated question: How would the PIC18 do if I one day decide to try and hook it up to internet with TCPIP? For example, I have noticed that there is a tcp.h include in the modbus tcpip driver. However, I haven't been able to find a tcp.h around in the driver folder or in any ccs folder.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 12:34 pm     Reply with quote

dluu13 wrote:

For example, I have noticed that there is a tcp.h include in the modbus
tcpip driver. However, I haven't been able to find a tcp.h around in the
driver folder or in any ccs folder.

To work on someone's question, I temporarily had vs. 5.050 installed.
I searched the Drivers folder and it had tcp.h in it.

I then cleaned out that folder and installed vs. 5.081. Result: No tcp.h.
They took it out. You could email CCS support and ask them why.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 30, 2018 12:36 pm     Reply with quote

Ok I will contact them about that myself then. Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 30, 2018 12:39 pm     Reply with quote

The physical TCP/IP driver is dependant on what interface chip you are using. So ENC28J60.C, S7600.H etc..
There are examples for sending email and doing a basic web page using the PIC18. There should be ex_email.c, and ex_websc.c in the example directory with the compiler. Until a couple of years ago, they were a separate download, but now they are part of the standard examples.
asmallri



Joined: 12 Aug 2004
Posts: 1630
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Oct 30, 2018 4:36 pm     Reply with quote

dluu13 wrote:
Thanks for that tip. Yeah, I saw the way you referenced the speeds and figured that it probably won't run with the way I've just thrown everything on the breadboard haphazard-like.

Just a slightly unrelated question: How would the PIC18 do if I one day decide to try and hook it up to internet with TCPIP? For example, I have noticed that there is a tcp.h include in the modbus tcpip driver. However, I haven't been able to find a tcp.h around in the driver folder or in any ccs folder.


Unless you are already intimately familiar with the PIC18F family, go straight to the PIC24. It is far better suited to medium and high complexity applications require network and storage stacks.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Wed Oct 31, 2018 7:07 am     Reply with quote

Thanks Andrew,

From a quick glance over the PIC24 PCD compiler manual, it looks like programming the PIC uses a similar paradigm to the PIC18 and PIC16. In your experience, from a programming perspective, what is the major difference, in case I have missed it? Ttelmah mentioned that the code size is "bulkier". Does anybody have an example of that?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Wed Oct 31, 2018 9:56 am     Reply with quote

There are several things that are a little cumbersome on the PIC24 family.

Every separate interrupt has it's own handler (good), but it means there has to be save/restore code in every interrupt handler. The interrupt table itself is very large. Then there is an basic int16 organization to the RAM, which can make it slightly harder to work with 'bytes'. A pointer for instance cannot be used for word accesses if it points to an odd address.
A 'minimum' PIC24 program, will probably occupy over a KB of ROM (for vectors etc.), while a similar small program on a PIC18, might well only occupy a couple of hundred bytes...
However once you talk more complex code, the balance tends to swing the other way. The hardware div instruction in particular (on chips offering this), massively reduces the size of maths libraries. The single instruction code block repeat with counter is also more efficient. On RAM, you need less 'scratch', but conversely a lot more stack (since on the PIC24's this is used for data as well as calls).
One area that is very cumbersome, is the use of program memory as a substitute for EEPROM. The page size for this is very large, and the organization as three bytes present out of every four makes code to use this bulky. Use an external EEPROM, and this goes away!...

It really does depend on the size of your projects. If 80% are quite small, the PIC18 is probably the better chip. However if many are large, the PIC24 has the edge.

However. I'm just doing a relatively small little controller, Only probably a couple of thousand lines of code. However I'm using a PIC24 for it. Why?. Because the particular sensor involved needs a huge amount of maths. Probably a few hundred maths instructions involving int32, int64, and probably in a couple of cases float. Ugh. On a PIC18, performance would be slow. However using DMA for the sampling, and a 40MIPS core, performance should not be an issue....
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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