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

rom space of two const arrays overlap

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



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

rom space of two const arrays overlap
PostPosted: Sat Jan 17, 2015 5:40 am     Reply with quote

compiler: 5.025
Hardware: PIC18F46K22
IDE: MPLAB X

It is probably a compiler issue, but i'm not sure. Hence i post it and see who else encounter the same issue.

The symptom is when multiple const array defined in different compilation unit, the generated rom spaces of two arrays overlap.


User Memory space: rom
00FFF2-00FFFF b
00FFF2-00FFFF a

Below code is the a simple code fragment which demonstrates the issue:

main.c
Code:

#include <main.h>

int8 const b[] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2};

void main()
{
   int8 i;
   for(i=0; i<5;i++){}
      int8 c = b[0];
   }
}



This is another compilation unit: unit1.c
Code:

#include <main.h>

int8 const a[] = {1,1,1,1,1,1,1,1,1,1,1,1};



The header file: main.h

Code:

#include <18F46K22.h>
#device const=rom



The expected value of array a[i] is 1, however, the actual return value is 2. Hence i checked the symbol file and found the spaces/address of the two const array overlap.
Code:

ROM Allocation:
000004  @READ_PROGRAM_MEMORY
000024  main
000024  @cinit1
000046  @cinit2

User Memory space: rom
 00FFF2-00FFFF  b
 00FFF2-00FFFF  a


Note above symbol, array a and b are of the identical space, which also result in error in my project.

Is there anyone know this issue? Or it is just because an incorrect compilation switch is used?
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Sun Jan 18, 2015 8:53 am     Reply with quote

Of course they will.....

If you want to reserve space in one module for another, then you need to add the commands to the module to do this.

It looks as if you are compiling what are effectively two separate programs, and expecting the compiler to magically 'know' about the other. It won't.

Look at the example 'mcu.zip', which shows how to configure multiple compilation units.
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Sun Jan 18, 2015 9:50 am     Reply with quote

Thanks for replying, Ttelmah

The multiple compilation units work fine in my project except this rom space overlap issue. I checked the mcu.zip you mentioned but I didn't find anything about how to setup a const/rom configuration. However, i opened the project in mcu.zip with mplab X and defined two const arrays in two different c files respectively, the result is just the same to my own project: the rom space of two const arrays overlap.

I guess you are saying that the #device const=rom can not be used in multiple compilation units, because it causes the two const arrays are placed in the same rom space, this is how the #device const=rom designed. Am I right?

I checked all the documents CCS provided and also searched via google but I failed to find a document which describes how the #device const=rom behaves in multiple compilation units...

Ttelmah wrote:
Of course they will.....

If you want to reserve space in one module for another, then you need to add the commands to the module to do this.

It looks as if you are compiling what are effectively two separate programs, and expecting the compiler to magically 'know' about the other. It won't.

Look at the example 'mcu.zip', which shows how to configure multiple compilation units.
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Sun Jan 18, 2015 10:10 am     Reply with quote

I'm not sure how you are configuring the code, but by default the location for a const, is controlled by the 'default' in a build statement. If you are building a component separately from another, then you need to define where this sits to avoid constants overlapping.
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Sun Jan 18, 2015 10:33 am     Reply with quote

Two const arrays locate in separated rom spaces, which is expected, if #device const=rom is not defined in header.
Hence I think the abnormal behavior is caused by this directive.

Anyway, the purpose that I use #device const=rom is to work around another issue - Const array returns incorrect value when it is accessed in my project. I found if the #device const=rom is added in the header the const array returns correct value.

Ttelmah wrote:
I'm not sure how you are configuring the code, but by default the location for a const, is controlled by the 'default' in a build statement. If you are building a component separately from another, then you need to define where this sits to avoid constants overlapping.
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 19, 2015 4:30 am     Reply with quote

I'd guess you are trying to use pointers to the array?.
Look in the manual.
The standard 'const' behaviour, does not allow pointers to be constructed. The pass strings in RAM option allows them to be built. The alternative is to use rom, instead of const, which generates a rom constant, for which pointers can be built (but the pointers have to be declared as rom pointers).
A search here will find a lot about this. It is caused by the memory architecture of the PIC (Harvard, as opposed to Von Neumann). With the Harvard architecture, there are two separate memory spaces for rom, and ram, as opposed to the single linear architecture. Hence 'address 0' for example, is present in both memory spaces separately. So if you use a pointer to a const, it'll be looking at the wrong memory space. The 'pass strings' option tells the compiler to virtualise the access 'through' a temporary ram memory area. The rom pointer and rom declaration, instead tell the compiler to create the code to access the second memory space, without this virtualisation:
Code:

    int8 rom silly_data[] = {1,2,3,4,5,6,7,8,9}; //constant data
    int8 rom* ptr; //pointer to constant data
    int demo;
    ptr=&silly_data[4];

    demo=*ptr; //5 from the array.
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Mon Jan 19, 2015 7:09 am     Reply with quote

No, i know the pointer to const issue/limitation.
My usage is almost the same as below code, no pointer is involved.
Code:

const BYTE b[] = {1,2,3,4};
void foo()
{
   int8 i;
   for(i=0; i<5;i++){
      int8 c = b[i];        //<=b[i] doesn't return the correct value
      ...
   }
}

By searching the forum, i found one or two similar cases were reported, but no solution found.

Once I thought it may be caused by some error I made in another place and impact this const array. But by analyzing the generated ASM code i found the ASM of two const array are almost identical except the data address from where the program memory is read. One works fine, another doesn't.

Ttelmah wrote:
I'd guess you are trying to use pointers to the array?.
Look in the manual.
The standard 'const' behaviour, does not allow pointers to be constructed. The pass strings in RAM option allows them to be built. The alternative is to use rom, instead of const, which generates a rom constant, for which pointers can be built (but the pointers have to be declared as rom pointers).
A search here will find a lot about this. It is caused by the memory architecture of the PIC (Harvard, as opposed to Von Neumann). With the Harvard architecture, there are two separate memory spaces for rom, and ram, as opposed to the single linear architecture. Hence 'address 0' for example, is present in both memory spaces separately. So if you use a pointer to a const, it'll be looking at the wrong memory space. The 'pass strings' option tells the compiler to virtualise the access 'through' a temporary ram memory area. The rom pointer and rom declaration, instead tell the compiler to create the code to access the second memory space, without this virtualisation:
Code:

    int8 rom silly_data[] = {1,2,3,4,5,6,7,8,9}; //constant data
    int8 rom* ptr; //pointer to constant data
    int demo;
    ptr=&silly_data[4];

    demo=*ptr; //5 from the array.
[/code]
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Mon Jan 19, 2015 7:27 am     Reply with quote

Hi there,
I found a easy way to reproduce the issue:
Code:

const BYTE a[] = {1,2,3,4,5,6};
const BYTE b[] = {11, 12,13,14,15,16};

void main(){
    systemInit();//init the system if it is necessary
    for(int i = 0; i< sizeof(a)/sizeof(BYTE) ; i++){
        printf("a = %u, b=%u \r\n", a[i], b[i]);
    }
}



My compiler is 5.025, IDE is mplab X.
The output is:
Code:

a = 1, b=0
a = 2, b=0
a = 3, b=0
a = 4, b=0
a = 5, b=0
a = 6, b=0
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 19, 2015 8:35 am     Reply with quote

Have just tried that code in MPLAB (not X), with 5.025, and it merrily gives:
Code:

a = 1, b=11
a = 2, b=12
a = 3, b=13
a = 4, b=14
a = 5, b=15
a = 6, b=16

Cut and pasted from the UART window.
Gives the same if IN_RAM is selected or not.

Used 5.025, since this is what you have.
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Mon Jan 19, 2015 10:45 am     Reply with quote

Interesting discovery:

If I compiled in a single compilation unit, the result is just what I expected:
Code:

a = 1, b=11
a = 2, b=12
a = 3, b=13
a = 4, b=14
a = 5, b=15
a = 6, b=16


However, when another compilation unit with any content is added into project, the result is incorrect:
Code:

a = 1, b=0
a = 2, b=0
a = 3, b=0
a = 4, b=0
a = 5, b=0
a = 6, b=0


I hope i am wrong but all clues indicate it should be a compiler issue.
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 19, 2015 1:46 pm     Reply with quote

I do have to ask 'why' you are using the multiple compilation units?.
As has been outlined in the past, CCS is at heart a single pass compiler. It optimises better when only used this way. Given that it usually takes perhaps 100* as long to program the chip as the compiler takes for even a 50000 line program, using multiple compilation units is not normally done.
chenzhuo



Joined: 17 Jan 2015
Posts: 8
Location: 美国

View user's profile Send private message AIM Address

PostPosted: Mon Jan 19, 2015 8:46 pm     Reply with quote

From software engineering perspective, i'd like to separate my code into several different module, hence the source code conflict could be avoided when collaborate with my partner and also code is of more readability.
Yes, i have realized that CCS as embedded chip compiler is of a lot of limitation/restrictions that prevent my project from utilizing some typical technology. For example the pointer to function can not nest, and pointer to function has difficulty in complex structure. Although all of them could be worked around but it really gave me a lot of troubles and funs.

Anyway, thank you Ttelmah. You really help me to identify the issue, as the root cause now is clear then I can find a workaround.

Ttelmah wrote:
I do have to ask 'why' you are using the multiple compilation units?.
As has been outlined in the past, CCS is at heart a single pass compiler. It optimises better when only used this way. Given that it usually takes perhaps 100* as long to program the chip as the compiler takes for even a 50000 line program, using multiple compilation units is not normally done.
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