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

Help me understand const

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



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

Help me understand const
PostPosted: Wed Oct 19, 2022 12:40 pm     Reply with quote

Hi,

I read a lot about values in rom here but still do not completely understand why sometimes I can read from rom, while other times I cannot.

For example:

Code:

int8 mp2667_regs2[7][2] = { 0x00, 0x64, 0x01, 0x06, 0x02, 0x04, 0x03, 0x09, 0x04, 0xa3, 0x05, 0x4a, 0x06, 0x02 };

for (i=0;i<7;i++){

      i2c_transfer_out(MP2667_I2C_ADDRESS, mp2667_regs2[i], 2);
      
}


works as expected by shifting out over i2c 7 registers with their payload, but

Code:

const int8 mp2667_regs2[7][2] = { 0x00, 0x64, 0x01, 0x06, 0x02, 0x04, 0x03, 0x09, 0x04, 0xa3, 0x05, 0x4a, 0x06, 0x02 };

for (i=0;i<7;i++){

      i2c_transfer_out(MP2667_I2C_ADDRESS, mp2667_regs2[i], 2);
      
}


does not. It compiles fine but it transfers 0x00 for registers and payload. I am struggling to understand why I seem to be unable to feed i2c_transfer_out() an array in rom. Is this a special requirement with i2c_transfer_out(), is it a PIC-Harvard-architecture thingy or is it just standard C that I don't get?

Kind regards,

Paul
PrinceNai



Joined: 31 Oct 2016
Posts: 453
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Oct 19, 2022 2:05 pm     Reply with quote

Just a thought. Is it possible that this function doesn't trigger an error when trying to access ROM with a pointer, since function definition in help file states: wData - Pointer to data to transfer to device?
For the fun of it, try with:

#device PASS_STRINGS = IN_RAM after your device definition.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Wed Oct 19, 2022 11:51 pm     Reply with quote

Tried that, no difference. No compilation errors and 00's where I expected something else.

Another thing I don't get is that (in my example) the version with the 'const' statement shows less rom used than the version where I leave out the 'const' (1174 vs 1244).

Ram shows exactly what I expected: 68 bytes with 'const' and 82 without it. As the table is 14 bytes long that is something I do understand.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Oct 20, 2022 1:51 am     Reply with quote

Yes, it is a Harvard architecture 'thing', but also how CCS handles const
(by default).

Understand that with the Harvard architecture, there are two separate
memory spaces. One in the ROM, and one in the RAM. 'Pointers', in C
are addresses of values. Now in a Von-Neumann architecture processor,
all of the memory (ROM and RAM), is in the same address space. So
an 'address' is the same whether things are in ROM or RAM. However
with Harvard, there is an address '0' in ROM, and another address '0' in
RAM.
By default CCS stores it's const's in ROM. So if you try to hand an address
of an element in ROM to a function expecting an address in RAM, it cannot
work....
Now this differs from how const is handled in ANSI. Here a const does not
mean a value stored in ROM (since most code in most processors is actually
in RAM), instead it means a RAM value that by default is to some extent
protected from being 'written'. How much protection there actually 'is'
depends on the architecture of the processor. Generally you often can
overwrite const values using pointer access, except on chips that have
hardware page protection.
CCS's use of const, predates ANSI, and was very sensible to allow a value
to be genuinely code in the ROM, without any RAM involved. However a
lot of modern code assumes the ANSI syntax.

So the first thing is you can make the code work by simply switching to
ANSI mode in the compiler. The variable will then be stored in RAM, and
a RAM pointer can then be constructed. This though will use as much RAM
as just declaring the value without const.

Now the limitation of not being able to construct pointers to ROM, can
(to a limited extent), be overridden by the 'PASS_STRINGS' option. This
creates a 'cheat', where integer arrays can be passed through a tiny RAM
buffer, and given a dynamic RAM address for functions.
This should work for what you show. Are you sure you are doing this
correctly?.
What is your compiler version?. This option historically was faulty on
quite a lot of compilers. It works correctly for me on 5.110.
That the compiler is not warning that you are attempting to create a
pointer to a constant, suggests to me that you may well have one of
the faulty versions. On the current compiler it does warn.

You could do the function and keep the values in ROM, by having a two
byte RAM buffer and copying the values into this as each is wanted,
then handing the address of this to the function.
Woody



Joined: 11 Sep 2003
Posts: 75
Location: Warmenhuizen - NL

View user's profile Send private message

PostPosted: Thu Oct 20, 2022 2:29 am     Reply with quote

Ttelmah,

Thank you for this very clear explanation!

Compiler version is 5.107. (Waiting for US$ to fall before renewing :-))

I implemented your suggestion of using a 2 byte buffer yesterday; that works without problems but it made me wonder why it did not work in the original fashion.

I'll try the 'PASS_STRINGS' option again to make sure I did not ef up during my first test and renew the compiler as well.

Paul
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Thu Oct 20, 2022 3:13 am     Reply with quote

I think (if I remember correctly), 5.107, was one of the recent versions that
was having a problem with the sizes of pointers to ROM being handled
incorrectly.

The buffer is the safe way to go. Very Happy
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