|
|
View previous topic :: View next topic |
Author |
Message |
Blob
Joined: 02 Jan 2006 Posts: 75 Location: Neeroeteren, Limburg, Belgium
|
#org necessary when #ROM in header |
Posted: Mon Mar 19, 2012 6:02 am |
|
|
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: 1345
|
|
Posted: Mon Mar 19, 2012 6:40 am |
|
|
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
|
|
Posted: Wed May 02, 2012 3:35 am |
|
|
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: 1345
|
|
Posted: Wed May 02, 2012 6:09 am |
|
|
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
|
|
Posted: Wed May 02, 2012 7:26 am |
|
|
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: 1345
|
|
Posted: Wed May 02, 2012 8:17 am |
|
|
#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
|
|
Posted: Thu May 03, 2012 1:45 am |
|
|
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: 19496
|
|
Posted: Thu May 03, 2012 5:06 am |
|
|
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: 1345
|
|
Posted: Thu May 03, 2012 5:47 am |
|
|
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
|
|
Posted: Thu May 03, 2012 6:07 am |
|
|
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: 19496
|
|
Posted: Thu May 03, 2012 8:15 am |
|
|
#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
|
|
Posted: Thu May 03, 2012 8:36 am |
|
|
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: 1345
|
|
Posted: Thu May 03, 2012 11:13 am |
|
|
#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
|
SOLVED |
Posted: Mon May 07, 2012 6:09 am |
|
|
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 |
|
|
|
|
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
|