View previous topic :: View next topic |
Author |
Message |
Torello
Joined: 29 Sep 2006 Posts: 120
|
int8 ROM array |
Posted: Wed Mar 04, 2015 7:13 am |
|
|
Hi,
In a pretty large program ~75K I use this
Code: |
int8 ROM BootMark[2]= {0x00,0x00};
int8 ROM GpsHw[2]={0x00,0x00};
|
In the .sym file I see the memory addresses where the arrays are.
Code: |
User Memory space: rom
017FFE-017FFF BootMark
017FFC-017FFD GpsHw
|
Also I verified in the CCS device programmer that those locations are set to 0x00 in the hex file.
Using read_program_eeprom(GpsHw); I get crap.
Printing the GpsHw reference it -only- returns the LS-Word 7FFC
I tried all kinds of typecasts to get the full address but nada.
Any thoughts what is happening here?
I need the address because I want to write this word also. _________________ Regards, Edwin. PCWHD v5.114 |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Wed Mar 04, 2015 8:00 am |
|
|
What chip?.
I see AsmBoy raises the same question, and a few others.
However, it does get complex, since some things use byte addresses, and some int16...
Big problem though is just how complex writing the bytes is going to be.
Remember on larger devices, the program memory is always organised as large pages. You have to erase an entire page.
So modifying the values, becomes:
Read the entire page to RAM
Modify the bytes in RAM, leaving the others unchanged.
Erase the whole page, and write the page back.
Now the compiler will automatically erase a page, if you write to the first byte of the page. So it'll be enormously easier if these values are placed at the start of a page containing nothing else than the 'constant' values. Look at #locating them. However also remember that on most of these chips the very top of memory contains configuration data, so locate them a page 'clear' of this data.
read_program_eeprom, returns the entire word at the address.
Beware also that a pointer, may not actually be the physical address. Use label_address. |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Wed Mar 04, 2015 8:22 am |
|
|
Pic18LF4685;
Found a solution that works.
Code: |
#define ProgMemSiz (getenv("PROGRAM_MEMORY"))
#define FlsEraSiz (getenv("FLASH_ERASE_SIZE"))
#define BootMark (ProgMemSiz-(FlsEraSiz*1))
#define GpsHw (ProgMemSiz-(FlsEraSiz*2))
#rom int8 BootMark={0,0}
#rom int8 GpsHw={0,0}
|
Thanks all, _________________ Regards, Edwin. PCWHD v5.114 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Wed Mar 04, 2015 9:25 am |
|
|
OK. Not a terribly large chip then (was thinking of things like PIC24's and up), so doesn't have the problem of config data at the top of memory.
Sensible solution, and now means you know exactly where things are, and how much you have to erase. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Mar 04, 2015 10:58 am |
|
|
and i have to ask:
how often do you plan to rewrite the prog memory?
because rewriting it even ONCE makes me anxious-
especially since without a fall-back fail safe design approach
- any mission critical function for the MCU could be in doubt.
i've perhaps been where you are and
greatly prefer a high-rel external SPI eeprom,
with recorded check values and a
safety fallback in the main MCU code should read back error be detected.
I am involved with medical electronics and
in short i would never do what you want to do. |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Wed Mar 04, 2015 12:27 pm |
|
|
Hi Asmboy,
Thanks for the warning. I do agree, but make a pragmatic exception. The bootmark I use to distinguish a plain MCLR / power reboot or the same after a firmware update.
In latter situation I need to set a lot of variables with default values.
So I flash program the bootmark 0x0000 At at Mclr or Power boot I read this value. Anything but 0xEBEB will trigger an default init.
After successful initialization I write this 0xEBEB once
The other variable is just a Quick test thing that will be removed again.
Ttelmah also thanks! _________________ Regards, Edwin. PCWHD v5.114 |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Mar 04, 2015 1:03 pm |
|
|
Quote: |
After successful initialization I write this 0xEBEB once |
it was quite clear that this was no class assignment, and
the word ONCE is reassuring ..... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Thu Mar 05, 2015 1:43 am |
|
|
In which case, you should move the bootmark.
Thing to remember is that the standard routines, erase the whole page, when you write to the first byte in the page.
You need to:
1) Erase page.
2) Write all the data, except the bootmark.
3) Verify the data.
4) Now write the bootmark.
Having the Bootmark at the start of the page makes this awkward. Better to place it as the last word in the page. |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Thu Mar 05, 2015 2:22 am |
|
|
But it is just a single bootmark (ak. flag). The initialization data self in not in this page. The design pattern you describe I more a less use for data-structures stored in eeprom. Only there the actual location is of the flag is not important as eeprom can be written random.
I still think my initial problem might be a CCS bug. I'll write a small test program to see if it occurs there also. If it does I submit it. _________________ Regards, Edwin. PCWHD v5.114 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Thu Mar 05, 2015 3:02 am |
|
|
The point is that you are writing a 'block' of configuration data.
The easiest way to do this (and more efficient on time, since it does a block write - remember that the chip is completely disable while every EEPROM write if being performed), is to use the 'write_program_memory' function. This _automatically erases when you write to the first byte of a page_.
So if you write all your config data, starting at the beginning of the page, a single page write operation erases, and writes all the data (instead of having to do separate writes for each word of the data).
You can then read this data, and if it is correct perform one 'write_program_eeprom' function to set the flag.
If the flag is at the start of the page, you have to do a separate erase, then write all the configuration word at a time, using separate writes, then perform the verify, and then go back and write the flag.
A lot slower, and more likely to cause problems.... |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Fri Mar 06, 2015 2:37 am |
|
|
WOW!
Back to the original problem. The write_program_eeprom(BootMark) has been in my code for many years. And I know it has been working.
Wrote a little test program and compiled it with old and new versions.
The oldest I have got available is 4.136
With this version it compiles OK !!
With version 5.020, 5.026, 5.042 it compiles WRONG!
I'm going to submit it to CCS.
Code: |
#include <18F4685.h>
#fuses INTRC_IO, NOFCMEN, IESO, PUT
#fuses NOBROWNOUT, NOWDT, NOPBADEN, LPT1OSC
#fuses MCLR, STVREN, NOLVP
#use delay(clock=4000000)
int8 ROM BootMark[2]= {0x00,0x00};
// Symbols file shows: User Memory space: rom 0x017FFE-0x017FFF BootMark
void main() {
int8 i;
int16 j;
int8 line[100];
sprintf(line,"Memory Address Reference Bug?\n");
j = read_program_eeprom(BootMark);
//see assembler code; compiler version >= 5.020 resolves this mem-ref as : 0x00FFFE
//see assembler code; compiler version 4.136 resolves this as should 0x017FFE
j = read_program_eeprom(0x17FFE);
//see assembler code; compiler resolves this as should: 0x017FFE
} |
Compilers output:
Code: |
>>> Compiler version 5.020, 5.026, 5.042
.................... j = read_program_eeprom(BootMark);
0009C: MOVFF FF2,6D
000A0: BCF FF2.7
000A2: CLRF FF8 //0x00 FALSE!!
000A4: SETF FF7 //0xFF FALSE!!
000A6: MOVLW FE //0xFE
000A8: MOVWF FF6
000AA: TBLRD*+
000AC: MOVF FF5,W
000AE: TBLRD*
000B0: MOVFF FF5,03
000B4: CLRF FF8
000B6: BTFSC x6D.7
000B8: BSF FF2.7
000BA: MOVWF 07
000BC: MOVFF 03,08
>>> Compiler version 4.136
.................... j = read_program_eeprom(BootMark);
0009E: MOVFF FF2,6D
000A2: BCF FF2.7
000A4: MOVLW 01 // 0x01 perfect!
000A6: MOVWF FF8
000A8: MOVLW 7F // 0x7F perfect!
000AA: MOVWF FF7
000AC: MOVLW FE // 0xFE perfect!
000AE: MOVWF FF6
000B0: TBLRD*+
000B2: MOVF FF5,W
000B4: TBLRD*
000B6: MOVFF FF5,03
000BA: CLRF FF8
000BC: BTFSC x6D.7
000BE: BSF FF2.7
000C0: MOVWF 07
000C2: MOVFF 03,08
|
_________________ Regards, Edwin. PCWHD v5.114 |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Fri Mar 06, 2015 4:41 am |
|
|
Pfieuw, this makes my Friday.
The "field" version of my firmware is far smaller then the test / debug version.
It does reach the wrongly written memory address 0x0FFFE _________________ Regards, Edwin. PCWHD v5.114 |
|
|
Torello
Joined: 29 Sep 2006 Posts: 120
|
|
Posted: Mon Mar 09, 2015 4:17 am |
|
|
Update: The bug is acknowledged by CCS:
Quote: | The problem you reported has been fixed and will be in the
next compiler release. |
On my answer question:
Does this bug also causes wrong code for other memory references?
With other words what is the impact?
They reported:
Quote: |
Only rom qualified arrays were affected. I suspect indexing will work, only an un-indexed reference should
have been a problem. |
_________________ Regards, Edwin. PCWHD v5.114 |
|
|
|