View previous topic :: View next topic |
Author |
Message |
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
16F1508 returns great address |
Posted: Sat Apr 05, 2014 2:19 pm |
|
|
Hello
I am just verifying the address of variable location.
Code: |
void main()
{
int r;
while(1)
{
delay_ms(300);
printf("\r%lxh %lud",&r,&r);
}
} |
This is printed:
Since I established that the last user RAM location is 16F I am confused.
How come I get such a great address? _________________ A person who never made a mistake never tried anything new. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 06, 2014 12:17 am |
|
|
Are you using #device *=16?.
If not, then the maximum address is only an 8bit value, so when you treat the address as a 16bit value (with 'l'), the top byte means nothing.
Separately though CCS uses high address values for the ROM space now.
If you have:
Code: |
#device *=16 //immediately after your processor definition
void main()
{
int r;
rom int p=16; //declare an addressable variable in rom
int16 address;
while(TRUE)
{
delay_ms(300);
address=&r;
//print this address how you want here
address=&p;
//then this one
}
}
|
You will see how CCS is using high addresses for the rom space. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 06, 2014 12:29 am |
|
|
But in his code, 'r' is in ram and the .SYM shows that it's at address 0021.
If his program is compiled for a 16F886, it displays 0x21 correctly.
But for the 16F1508 or 16F1847, etc., it doesn't display 0x21 as it should.
If you modify the test program so that &r is loaded into a 16-bit variable,
and then you look at the .LST file, you see the compiler breaking up the
0021 address into two components of 01 and 20. Why does it do this
for 16F1508 etc. ? (Tested with vs. 5.023). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 06, 2014 1:04 am |
|
|
Yes.
Adding the SYM data is of course vital.
Gets more interesting. This is wrong right back to 4.141. It is mishandling the split point for what is the 'bank' and what is the address in the bank. Addresses are allowed to be a 7bit value in each bank, instead it is behaving as if it is a 5bit value, so moves bit 5 up into the bank select area....
It's getting it wrong when used as well (doesn't sort it out at this point).
You can see it really clearly, if you move a variable up above address 0x30. In this case 'fred' at 0x39:
Code: |
.................... address=&fred;
0032: MOVLW 20
0033: MOVWF 37
0034: MOVLW 19
0035: MOVWF 36
|
So 5 bits of the address are being retained (0x19), but the higher bits are being treated as the bank address.....
Ouch.
Worse it is not even putting the bank addresses in the right place (high nibble instead of low).
Double ouch.
Even more annoyingly, the ram page size doesn't seem to have a setting in the device editor, so it can't even be fixed that way.
Needs rapid reporting.
I must admit, on a couple of PIC16 chips, when I do use 'rom', I've seen extra bits appear at the top of the address (presumably the compiler is using these as flags), and assumed this was what was being seen..... |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Sun Apr 06, 2014 3:07 am |
|
|
Quote: |
Are you using #device *=16?.
If not, then the maximum address is only an 8bit value |
I am not using #device *=16.
Moreover, when I try to print the address as 8bit int (" %u",&r);, I get this error: Print format type is invalid.
of course I can assign the addres to an 8bit int, but then I lose some data for sure.
in this case:
Code: | void main()
{
int r;
unsigned int8 add;
add = &r;
printf(" %u",add);
} |
Printed: Which is also not inside GPR boundaries.
Second thought, Why do I need BANK number (attached to the address), if the address of each variable stored in GPR or SFR is unique?
Thank you for replies! _________________ A person who never made a mistake never tried anything new. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 06, 2014 4:28 am |
|
|
The point about *=16, is you need this to actually 'use' more than an 8bit address. The actual address 'type' remains as a 16bit value when printed/used though. So you need this to access the '0x16F' of RAM memory.
The key point is that the compiler (in all versions I've tried), is making a right (rude word at this point!), of the address, and as explained, is treating the memory pages as being only 32bytes in length (they are actually 128 bytes). So the address being used at 33, gets cut up into '1', and a bank address. It then gets this wrong as well....
Report it to CCS. It is surprising no-one had spotted it before.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 06, 2014 11:23 am |
|
|
I wrote up the bug in detail and emailed it to CCS support just now.
I would guess they'll fix it in the next release. I pointed them to
this thread and your comments, for more explanation of the exact
mechanism involved in the bug. I told them it apparently affects
all 16F-series "enhanced" PICs. (Based on my testing). |
|
|
rikotech8
Joined: 10 Dec 2011 Posts: 376 Location: Sofiq,Bulgariq
|
|
Posted: Sun Apr 06, 2014 12:39 pm |
|
|
Quote: | So you need this to access the '0x16F' of RAM memory. |
I see clealy, not using *=16 is all my bad. Thank you about that!
What still not clear to me is: Do I need the bank address in case it is right placed (high nibble). I mean, using pointers, the bank address is not relevant, isn't it?
Maybe this is a bit beyond the topic, but if each address in the RAM has its own unique address, why do I need information about the bank at all? Is it useful for me as a "programmer" to know in which bank is stored a certain register?
I repeat myself because I am not sure if you understand my issue?
Its my English teacher's fault! _________________ A person who never made a mistake never tried anything new. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Sun Apr 06, 2014 12:47 pm |
|
|
That is how PIC16 memory is addressed.
The bank address is like the page number, and the rest is the word count in the page.
Every memory address has both a low part and a bank address (even if this is zero), and both parts are needed to actually address the byte.
What is going wrong is because the compiler is treating the 'bank' as if it is only 32 bytes long, it is getting a non zero bank address, for every usable address in memory. So 0x21 (which should have '21' in the count, and '0' in the bank address), ends up with '1' in the count, and an incorrect value in the bank address. Result it accesses the wrong byte, and the value returned as the address is 'insane'.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 07, 2014 11:54 am |
|
|
Here is the response from CCS tech support:
Quote: |
The Enhanced 16 parts have two addressing modes. The SYM file shows
the physical address but anytime we use the FSR the logical address is
used. The & operator returns the logical address because the result will
eventually end up in the FSR.
Physical 0x0021 is the same location as logical 0x2001.
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Apr 07, 2014 12:00 pm |
|
|
Interesting....
Doesn't appear to agree with the values the data sheet shows to write to the FSR registers, to access the location. Question is does it work?.
Somebody needs to try on a real chip, and 'walk through' an area of memory with the pointers and see what is returned.
Ah. Their 'terminology' disagrees with Microchips....
They are accessing it through the 'linear data memory' area. Starts at address 0x2000, and gives direct access to the RAM starting at address 0x20, _and omitting the shared areas_, so gives a single linear area of RAM starting at this point. |
|
|
|