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

#org necessary when #ROM in header

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



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

#org necessary when #ROM in header
PostPosted: Mon Mar 19, 2012 6:02 am     Reply with quote

Hello,

In my application, I use some memory to keep some variables.

I use
Code:
#org 9984, 30080 {}

To define the memory block.

Afterwards, this memory will be filled with data with a PC app using rs232

my pc app can generate a header file containing all the data for the memory.
so I include this header file into my project when I need to program a lot of chips with the same variables.

Code:
#ROM 9984 = { 53030 }
#ROM 9986 = { 48611 }
#ROM 9988 = { 44871 }
#ROM 9990 = { 41666 }
#ROM 9992 = { 38888 }
#ROM 9994 = { 36458 }
#ROM 9996 = { 34313 }
#ROM 9998 = { 32407 }
#ROM 10000 = { 30701 }
#ROM 10002 = { 29166 }
#ROM 10004 = { 27777 }
...........


my code is:
Quote:
#org 9984, 30080 {}
#include "Project.h"


when I compile this in 038 it runs fine
but in 104 i constantly get
Quote:
Memory not available at requested location


when I only use the include line, I get
Quote:
Out of ROM, A segment or the program is too large


when using only #org, I will not be able to include the variables...

why do I get this error in 104?
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Mon Mar 19, 2012 6:40 am     Reply with quote

You cannot have the #ROM and #ORG ranges overlap in a single compiled program (well, you shouldn't be able to have them overlap...some compiler versions may not catch it).

If you are using the #ROM for all of the memory locations in that range, you don't need the #ORG.

However, if say for example, you don't want the program using locations 9984 to 30079, but only fill out the ROM locations manually for 9984 to 10005, you can do something like:

Code:


#ROM 9984 = { 53030 }
#ROM 9986 = { 48611 }
#ROM 9988 = { 44871 }
#ROM 9990 = { 41666 }
#ROM 9992 = { 38888 }
#ROM 9994 = { 36458 }
#ROM 9996 = { 34313 }
#ROM 9998 = { 32407 }
#ROM 10000 = { 30701 }
#ROM 10002 = { 29166 }
#ROM 10004 = { 27777 }
#ORG 10006,30079{}





If you plan on filling up the entire memory section with #ROM, then you shouldn't need the #ORG at all. Just use it to section off any gaps/leftovers that you don't want the main program using.

EDIT:
It sounds like making a bootloader. If it is your app that is populating the memory location, then just use the #ORG 9984,30079{} in the bootloader to make sure none of the bootloader code goes there and the #ROM's in the application to populate it. If instead you want the bootloader to populate it and the app to simply use the variables, then do it the other way (#ROM's in the bootloader and #ORG in the application).

Also, as a general note, it is much better to use hexadecimal addresses for something like this since the PIC memory table documentation is in that format already.
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

PostPosted: Wed May 02, 2012 3:35 am     Reply with quote

Hello All,

I tried Jeremiah's suggestion.

when I use the ORG statement, my code compiles correctly.
Code:
#org 9984, 30080 {}




However when I use the ROM statement, I get OUT of ROM errors...
Code:

#ROM 9984 = {10000}
#ROM 9986 = {10000}
#ROM 9988 = {10000}
...
...
...
#ROM 30074 = {10000}
#ROM 30076 = {10000}
#ROM 30078 = {10000}
#ROM 30080 = {10000}


Any thoughts?
Thanks in advance
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed May 02, 2012 6:09 am     Reply with quote

That usually means you either are already using that ROM space with something else, your program is too big with those statements, or that your chip doesn't have that much addressable ROM. It could also be a compiler bug depending on your compiler revision.

For example, I took your original example:
Code:

#ROM 9984 = { 53030 }
#ROM 9986 = { 48611 }
#ROM 9988 = { 44871 }
#ROM 9990 = { 41666 }
#ROM 9992 = { 38888 }
#ROM 9994 = { 36458 }
#ROM 9996 = { 34313 }
#ROM 9998 = { 32407 }
#ROM 10000 = { 30701 }
#ROM 10002 = { 29166 }
#ROM 10004 = { 27777 }


In a random project of mine and it works fine. If you need further help, then you need to provide the following info:
1. The PIC you are using
2. The compiler revision you are using
3. A small compilable program that shows the problem. Don't give us all your code, just a main with some #ROM statements and all the fuses and #use you typically use.

EDIT:
For example, in 4.131 the following compiles fine:
Code:

#case

/*Start of USER defined area*/
#include <24FJ256GA106.h>

#DEVICE *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOJTAG                   //JTAG disabled
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES PR                       //Primary Oscillator

/*End of USER defined area*/

#ROM 9984 = { 53030 }
#ROM 9986 = { 48611 }
#ROM 9988 = { 44871 }
#ROM 9990 = { 41666 }
#ROM 9992 = { 38888 }
#ROM 9994 = { 36458 }
#ROM 9996 = { 34313 }
#ROM 9998 = { 32407 }
#ROM 10000 = { 30701 }
#ROM 10002 = { 29166 }
#ROM 10004 = { 27777 }

void main(){

}


I'm using the PIC24FJ256GA106 though.
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

PostPosted: Wed May 02, 2012 7:26 am     Reply with quote

Hello,

the compiler version is 4.104
pic 18f2620

I can not make a small sample program for you,

I I take some code away, there is no OUT of ROM error...


what I want to do is this:

I have a system that can be used in several applications.
The basic firmware will be the same, only some data will be different for every application.

So I reserve some ROM to store this data. using the #ORG statement
Code:
#org 9984, 30080 {}

As I understand correctly the compiler will insert nothing here.

when I use this, my program compiles and runs fine.

Afterwards I can fill the reserved memory with data using RS232
But this takes a lot of time if I have to do it for a complete batch.

So I would like to insert my data at programming time, inserted in the HEX file.

I was thinking the way to do is using #rom address = {data}

But when I use this for the whole org region, it will not compile.

I get a compile error,
Quote:
Out of ROM, A segment or the program is too large


And a list with all entries the compiler is trying to insert the code:

Quote:
Seg 02700-02700, 0000 left, need 09AC
Seg 02702-02702, 0000 left, need 09AC
Seg 02704-02704, 0000 left, need 09AC
Seg 02706-02706, 0000 left, need 09AC
Seg 02708-02708, 0000 left, need 09AC
Seg 0270A-0270A, 0000 left, need 09AC
Seg 0270C-0270C, 0000 left, need 09AC
Seg 0270E-0270E, 0000 left, need 09AC
Seg 02710-02710, 0000 left, need 09AC
Seg 02712-02712, 0000 left, need 09AC
Seg 02714-02714, 0000 left, need 09AC
Seg 02716-02716, 0000 left, need 09AC
...
..
.


Can the problem be that the #ROM segments are counted as program memory space and the #ORG is not?

The manual says that an error is generated as #rom and #org overlap...
But compiler 4.093 allows you to use #org and #rom overlapped.
With this version my program compiles and runs ok and the data is loaded

Thanks
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Wed May 02, 2012 8:17 am     Reply with quote

#ROM statements are definitely counted as program memory. I'm not sure the #ORG is when you use {} because that just tells the compiler NOT to use that location for anything.

It sounds like some of your existing code is in the locations you want to use so when you use the #ROM statements, it overlaps with other code, but that is just a guess. Try taking out both the #ROM and the #ORG statements, compile it, and look at the list file and symbol tables. See if any of the program memory used corresponds with the #ROM addresses you are using. Remember, they tend to use HEX notation while you are using decimal notation, so make sure you are comparing apples to apples.

My GUESS is that the code normally uses some of those locations until you put in the #ORG, which forces them to some other location and frees the spots up for the #ROM statements (although with the warnings).

I don't know what kind of data you are trying to store in ROM, but have you considered using "const" on a variable:

Code:

const unsigned int16 mydata[256] = {0,1,2,3,4,15000,...}


As long as you work with it as an array (and not a pointer), you would have access to the data. Usually #ROM is used for special situations like manually overriding the IVT tables, bootloader setup variables, etc. If you just need regular variable data, then const is typically a better fit.
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

PostPosted: Thu May 03, 2012 1:45 am     Reply with quote

Indeed,

my lst file shows that the function (which the compiler is complaining about to be to long) falls in the memory region I want to reserve.

I was thinking of this solution:

1 I compile with the #ORG
2 I look at my lst file and I will copy all the addresses of all functions
3 I org the functions in my program
4 i replace the main org by my rom list

Is this an option?


I tried following:

instead of making a list of
Code:
#ROM address_1 = {data_1}
#ROM address_2 = {data_2}
#ROM address_3 = {data_3}
...
#ROM address_n-2 = {data_n-2}
#ROM address_n-1 = {data_n-1}
#ROM address_n = {data_n}


I did
Code:
#ROM address_1{data_1, data_2, data_3,...,data_n-2,data_n-1,data_n}


And that does compile without error...

But it is quite difficult to have a bit of overview, I prefer to have a list
I don't see the difference between the list and the row...
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu May 03, 2012 5:06 am     Reply with quote

I think you need to use the following layout:

Code:

#org 9984, 30080 {}
#ORG DEFAULT
#ROM 9984 = { 53030 }
#ROM 9986 = { 48611 }
#ROM 9988 = { 44871 }
#ROM 9990 = { 41666 }
#ROM 9992 = { 38888 }
#ROM 9994 = { 36458 }
#ROM 9996 = { 34313 }
#ROM 9998 = { 32407 }
#ROM 10000 = { 30701 }
#ROM 10002 = { 29166 }
#ROM 10004 = { 27777 }

The key point is that the #ORG 9984, 30080, says to reserve this memory from use by the compiler. You then tell the compiler to go 'back' to using default layouts for it's stuff, and place the #ROM statements after this.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Thu May 03, 2012 5:47 am     Reply with quote

One thing you can do is this:

Code:

#include <blah.h>
#FUSES  blah
...

#ORG start_address_for_code, (address_1 - 1) default
//most of your code here, functions, #use, etc
#ORG default

#ROM address_1 = {data_1}
#ROM address_2 = {data_2}
#ROM address_3 = {data_3}
...
#ROM address_n-2 = {data_n-2}
#ROM address_n-1 = {data_n-1}
#ROM address_n    = {data_n}

#ORG (address_n + 2), (getenv("PROGRAM_MEMORY")-1) default
//remaining code here.  I recommend your main in this last block
#ORG default



Though for simplicity if you can change your ROM addresses around, I would suggest placing your ROM values at the beginning of where code is allowed. That's 0x200 for PIC24's...not sure where that is for PIC18's, but you could check your list file to see where code starts:

This is an example I cooked up for the PIC24. You would need to modify for your chip and data of course
Code:

#case

/*Start of USER defined area*/
#include <24FJ256GA106.h>

#DEVICE *=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOJTAG                   //JTAG disabled
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOIOL1WAY                //Allows multiple reconfigurations of peripheral pins
#FUSES NOCKSFSM                 //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES PR                       //Primary Oscillator

/*End of USER defined area*/

//In PIC24, code starts at 0x200 normally, so put ROM statements here
#ROM 0x0200 = { 53030 }
#ROM 0x0202 = { 48611 }
#ROM 0x0204 = { 44871 }
#ROM 0x0206 = { 41666 }
#ROM 0x0208 = { 38888 }
#ROM 0x020a = { 36458 }
#ROM 0x020c = { 34313 }
#ROM 0x020e = { 32407 }
#ROM 0x0210 = { 30701 }
#ROM 0x0212 = { 29166 }
#ROM 0x0214 = { 27777 }



#use delay(clock=22118400)
#use rs232(UART1,errors,baud=9600,bits=8,stop=1,parity=N)

void some_function(){
   int8 value = 0;
   value = getc();
}

void main(){
   some_function();
}


The benefit of this method is you don't need the #ORG statements to keep things in the right place (at least on test programs).
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

PostPosted: Thu May 03, 2012 6:07 am     Reply with quote

Setting the default keyword does stop the out of rom error,

but it still gives me warnings: Memory not available at requested location (for every address in the range)

As I understand the manual correctly:
Quote:
If the keyword DEFAULT is used then this address range is used for all functions user and compiler generated from this point in the file until a #ORG DEFAULT is encountered (no address range). If a compiler function is called from the generated code while DEFAULT is in effect the compiler generates a new version of the function within the specified address range.

Setting the range using default will place all the #roms in that range till default is met again:
Code:

#ORG 9984, 30080 DEFAULT //setting the memory region to use for following code
#include "app_data.h" // all data entries (#ROM address_n = {data_n}, n =9984->30080)
#ORG 9984, 30080 DEFAULT //stop using orged range


this also gives all the Memory not available at requested location warnings
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu May 03, 2012 8:15 am     Reply with quote

#ORG DEFAULT _without a memory range_, is what you use to turn it off. With a memory range specified you are still saying 'put everything in here'.....

Best Wishes
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

PostPosted: Thu May 03, 2012 8:36 am     Reply with quote

sorry forgot to delete the second range when copy-pasting the code

should be this:
Code:
#ORG 9984, 30080 DEFAULT //setting the memory region to be skipped by compiler
#include "app_data.h" // all data entries (#ROM address_n = {data_n}, n =9984->30080)
#ORG DEFAULT //stop using orged range


But as I stated, no luck using this neither with only
Code:
#ORG 9984, 30080 {} //setting the memory region to use for following code
#ORG DEFAULT //stop using orged range
#include "app_data.h" // all data entries (#ROM address_n = {data_n}, n =9984->30080)
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Thu May 03, 2012 11:13 am     Reply with quote

#ORG will have no effect on the #ROM itself. #ORG is for the rest of your code. It tells the compiler that any generated code should be within a certain address range. #ROM will place code where you tell it too regardless of the #ORG. The general idea is:


#org start,stop default
code
#org default

#ROM's

#org start,stop default
more code
#org default

Where the #ORG's keep the code out of the ROM range. Did you look at my previous suggestion of moving the #ROM statements to a different address? I think it will make your work easier.
Blob



Joined: 02 Jan 2006
Posts: 75
Location: Neeroeteren, Limburg, Belgium

View user's profile Send private message

SOLVED
PostPosted: Mon May 07, 2012 6:09 am     Reply with quote

I changed my #org list of over 10000 entries
Code:
#ROM address_1 = {data_1}
#ROM address_2 = {data_2}
#ROM address_3 = {data_3}
...
#ROM address_n-2 = {data_n-2}
#ROM address_n-1 = {data_n-1}
#ROM address_n    = {data_n}
n = 9984 -> 30080 (n in steps of 2 - 16bit)


into a shorter list of only 68 entries by ordering my data in groups

Code:
#ROM address_1 = {data_1, data_2, ...} //data group 1
#ROM address_K = {data_K, data_K+1, ...} //data group K
#ROM address_L = {data_L, data_L+1, ...} //data group L
#ROM address_M = {data_M, data_M+1, ...} //data group M
...


The total amount of memory to be written stays the same,
But only the structure of the list is different

The code compiles and runs without errors or warnings,

I also don't have to use the #org range like jeremiah stated before
Quote:
If you are using the #ROM for all of the memory locations in that range, you don't need the #ORG.


So my guess is, that there is a limit to the number of #rom statements allowed


Best regards,
Blob

PS @Jeremiah:
Quote:
Though for simplicity if you can change your ROM addresses around, I would suggest placing your ROM values at the beginning of where code is allowed.

I preferred not to move the location, since I would have to change quite a few firmware versions. Also my PC- user interface uses the same locations in its tables.
For future projects, I will sure take it in account
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