View previous topic :: View next topic |
Author |
Message |
niccolo.calandri
Joined: 20 May 2016 Posts: 10
|
Int8 Rom problem |
Posted: Sat Apr 29, 2017 10:08 am |
|
|
Code: |
int8 rom number=10;
char mess[20]="";
number=0;
sprintf(mess,"%d",number);
usb_cdc_puts(mess);
number=1;
sprintf(mess,"%d",number);
usb_cdc_puts(mess)
|
Why my output is
0
0
???
and not
0
1
?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sat Apr 29, 2017 12:07 pm |
|
|
Declaring it as rom, means it can't be written to/changed.
However the compiler is looking ahead at your code, and seeing the first value being assigned after the declaration, and putting this in at compile time, instead of the 10 in the declaration.
The code then can't change it. |
|
|
niccolo.calandri
Joined: 20 May 2016 Posts: 10
|
|
Posted: Sat Apr 29, 2017 2:55 pm |
|
|
Ok, Thanks Ttelmah,
if I need to store a variable in the Rom. How can i do it? How can i write in rom? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Apr 29, 2017 3:43 pm |
|
|
Post your PIC and your compiler version. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Apr 29, 2017 6:04 pm |
|
|
I also thought 'rom' meant read-only, but I ran it in MPLAB 8.92 simulator
and it worked. So then I ran it in hardware and it also worked.
This is with compiler version 5.071. The test program shown below
displays the following output in TeraTerm:
The .LST file shows the compiler is writing to program memory,
This is the initialization of 'number'. It's value is set when the PIC is
programmed by the Pickit 3:
Code: |
int8 rom number=10;
ROM data:
00FFFE: 0A
|
At run-time, 'number' is changed to 0:
Code: |
...... number=0;
001CA: CLRF @@1B
001CC: CLRF TBLPTRU
001CE: SETF TBLPTRH
001D0: MOVLW FE
001D2: MOVWF TBLPTRL
001D4: CLRF FSR0H
001D6: MOVLW @@1B
001D8: MOVWF FSR0L
001DA: MOVLW 01
001DC: MOVWF @WRITE_PROGRAM_MEMORY.P2
001DE: MOVLB 0
001E0: RCALL 0024
|
Next, it's changed to 1:
Code: |
...... number=1;
00220: MOVLW 01
00222: MOVWF @@1B
00224: CLRF TBLPTRU
00226: SETF TBLPTRH
00228: MOVLW FE
0022A: MOVWF TBLPTRL
0022C: CLRF FSR0H
0022E: MOVLW @@1B
00230: MOVWF FSR0L
00232: MOVLW 01
00234: MOVWF @WRITE_PROGRAM_MEMORY.P2
00236: RCALL 0024
|
Test program:
Code: |
#include <18F46K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//======================================
void main()
{
int8 rom number=10;
char mess[20]="";
number=0;
sprintf(mess,"%d",number);
puts(mess);
number=1;
sprintf(mess,"%d",number);
puts(mess);
while(TRUE);
} |
|
|
|
niccolo.calandri
Joined: 20 May 2016 Posts: 10
|
|
Posted: Sun Apr 30, 2017 12:00 am |
|
|
So maybe is my PIC?
PIC18F26J50 - Compiler version:
Do you know if I have to set some fuses? I use ICD and CCS 5.070.
Moreover, I test again my code. What is happening to me is that when i try to set the variable the number is always SET to 0. Why?
I want used the program memory to store some variable. Because I want shut down the PIC and when power suppply is recovered I want be sure that the variable is correct.
Do you use a different method? |
|
|
hmmpic
Joined: 09 Mar 2010 Posts: 314 Location: Denmark
|
|
Posted: Sun Apr 30, 2017 2:12 am |
|
|
When i use "rom" to store something, I thereafter use "read_program_memory" to get it back into a var. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Apr 30, 2017 2:22 am |
|
|
Interesting. Looks like the compiler has added the feature to allow direct writing to ROM without using the program memory commands.
However 'think about it'. Problem is that you can't just erase a word of ROM.
You can change a bit from '1' to '0' by writing, but can't change a bit from '0' to '1', without erasing a whole page.
Now in your example, you have 'b00001010'. This you can then write to '0b00000000', by writing. However you can't then change it to '0b00000001', without erasing the whole page in the ROM.....
The 'write program memory' function, that it's using, will erase a page, if you write to the first address in a page. So looks as if PCM_Programmers example, has his ROM value stored at the first address of a page, while yours doesn't.....
Now obviously you can make this work, by explicitly locating the ROM value to an address at the start of a page. However you then have the 'caveat', that everything else in this page will also be erased.
So realistically you need to store all the values you want in ROM that you are going to change, in one page of memory, then have a routine that reads them all into RAM, changes the one you want, and writes the whole page back. Given the new ability to do this with a rom 'variable', declare yourself a structure that is going to contain everything you want stored this way. Then to change a value, copy this structure into RAM, change the value you want, and write the whole structure back.
On your chip a page (the smallest area that can be erased), is 1024 bytes.
Remember that every time you erase a page, it uses one 'life' of the program memory. 10000 lives only. So make sure if you have several values to change you do them 'all in one go', not 'one at a time'....
Alternatively, much more economically on lives, CCS supply a set of code in the drivers, that allows you to treat a page using functions like EEPROM. This uses a flag to 'walk' through the page storing changes, and only erases the page when it runs out of space. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Sun Apr 30, 2017 2:33 am |
|
|
hmmpic wrote: | When i use "rom" to store something, I thereafter use "read_program_memory" to get it back into a var. |
Beware. Two diiferent meanings of 'ROM'....
#ROM, locates numbers at a particular location in program memory. These are not variables, and have to be accessed by read_program_memory.
rom as being shown here, is an alternative form of the 'const' declaration. This also locates values in the rom, but allows them to be directly read as a variable. Also supports pointers to the rom memory.
As we have now discovered CCS have also added the ability to write to these (sometime recently), but haven't actually told us this, and also have not handled the limitations of ROM memory, regarding writing. It's be hard for them to handle this, because of the sheer amount of RAM involved in saving a page. |
|
|
niccolo.calandri
Joined: 20 May 2016 Posts: 10
|
|
Posted: Sun Apr 30, 2017 10:24 am |
|
|
Ok! I understand it.
Now it is perfectly clear to me! Thanks to much |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Apr 30, 2017 11:37 am |
|
|
Ttelmah wrote: |
Alternatively, much more economically on lives, CCS supply a set of code
in the drivers, that allows you to treat a page using functions like
EEPROM. This uses a flag to 'walk' through the page storing changes, and
only erases the page when it runs out of space.
|
Ttelmah is talking about the CCS driver file, virtual_eeprom.c, which is
explained on this CCS page, with a short sample program of how to use it:
http://www.ccsinfo.com/newsdesk_info.php?newsdesk_id=192
The virtual_eeprom.c file is in your CCS compiler \Drivers folder. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon May 01, 2017 12:22 am |
|
|
Thanks PCM_programmer.
I've been posting for a couple of weeks 'without the compiler', since I was away. Had to rely on memory, and unlike an EEPROM, mine tends to forget 'details'... |
|
|
dan king
Joined: 22 Sep 2003 Posts: 119
|
|
Posted: Mon May 01, 2017 1:23 pm |
|
|
maybe you need to implement some wear levelling ;) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Mon May 01, 2017 1:26 pm |
|
|
I think it's all getting towards the life limit.... |
|
|
|