• AVR Freaks

Hot!Question about reserving space in flash with XC16

Author
jeff_d
Starting Member
  • Total Posts : 45
  • Reward points : 0
  • Joined: 2017/12/11 08:49:30
  • Location: 0
  • Status: offline
2019/11/12 09:47:52 (permalink)
0

Question about reserving space in flash with XC16

I've inherited some code which uses RTSP to save operating parameters in the same (only) 32k page with instruction space and we've discovered this was not the best choice. So I've developed a contingency plan and it requires backing up some critical values to a static part of flash. The boot loader can't be updated and was split into two sections with the second section containing a bunch of unused space I'd like to use. I'm investigating preserving factory setting here to enable a "restore to factory state". Previously the unused memory in this page was being written as 0x000000.  So in order to use this memory I would have to use RTSP to initialize and rewrite this page.  But this is also the last page of flash which includes the the configuration bits, and Microchip advises against RTSP the page containing configuration settings.
 
My solution would be to rework the boot loader to get the assembler and linker to leave unused memory initialized (0xFFFFFF) and then use the unused space to preserve factory settings using RTSP methods.
 
I'm running into a problem with defining the space so XC16 can reference this memory for the builtin table access functions which I'll need for the write. I've written the RTSP assembly routine to update one or more values in this unused space which can be called from C:

#define MFG_PARAMETERS_ADDR (0x5700)
const uint16_t const StaticMfgParameterFlash[] __attribute__ ((keep, space(psv), address(MFG_PARAMETERS_ADDR)));


flashUpdate (__builtin_tblpage(StaticMfgParameterFlash), __buildin_tbloffset(StaticMfgParameterFlash), buff_ptr, write_count);

 
I'm branching into new ground with C and need some help with the StaticMfgParameterFlash defintion so that it's an empty array (with no defined storage space) exists at 0x5700 in memory.
With the code above the compiler zeros the 16-bit value at 0x5700 which prevents any future writes to this location. I'd like to keep this space to the unmodified 0xFFFFFF. I'm not sure how this can be done.
 
I can create a pointer and assign that to 0x5700 and pass that value to tblpage and tbloffset, but in doing that I'm concerned it may have some negative impact. Defining it as I've done in the code above the compiler is responsible for correctly getting the address to the tblpage and tbloffset. The pointer option eliminates the compiler from using what it determines as the correct address which I'd like to avoid that if possible.
 
Is there a way to define StaticMfgParameterFlash so that it has no defined space but exists at a specific address in program space? TIA
#1

6 Replies Related Threads

    du00000001
    Just Some Member
    • Total Posts : 3225
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/12 10:00:16 (permalink)
    +1 (1)
    Why not (dummy-) initialize StaticMfgParameterFlash[] to 0xFFs ?

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #2
    jeff_d
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2017/12/11 08:49:30
    • Location: 0
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/12 13:23:53 (permalink)
    0
    That's an excellent question!
    Thanks for the extremely simple solution, I need to go repair my ego.
    I just need to figure out how to fill the upper byte in C, off to RTF(XC16)M ...
     
    #3
    DuaneH
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2009/10/15 11:49:22
    • Location: Sandy, UT
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/12 13:58:05 (permalink)
    0
    When you store variables in flash memory, be sure you take into account the smallest block which can be erased.  To save 1 byte, you have to read that entire block, change the value which needs to be updated, erase the block, and then re-write the whole block.  Another consideration will be write endurance if this is updated often, as program space is typically specified for 100K writes max.  If it's once a day, no issue. If you're doing real-time logging, things can hit the limit very quickly.

    duaneh
    #4
    cawilkie
    Administrator
    • Total Posts : 1993
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/13 07:31:07 (permalink)
    +1 (1)
    You may also find the attribute "noload" helpful.  It will reserve the space but not initialise it.  However, any solution other than explicitly initialising it will depend upon how the programming device has initially programmed the part.  Make sure it does a bulk-erase first and not just erasing the programmed areas.
     
    You will not be able to initialise the upper byte from C, easily.   This can be done in assembly very easily, if needed.
     
    Regards
    Calum
    #5
    jeff_d
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2017/12/11 08:49:30
    • Location: 0
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/13 10:08:24 (permalink)
    0
    Thanks for the responses. I've done some more work and got two solutions...
     
    Calum, thanks for the noload option I had not used that and was able to create a gap like this:
    char __attribute__((space(prog), address(0x005690), noload, keep, unused)) StaticMfgParameterFlash[0x150];

    The keep is documented as working, but the compiler says the directive is ignored. I thougth it prevent the variable from being removed when "remove unused" option is enabled.
     
    As you suggested, it's pretty easy in assembly to fill the upper byte:
        .section *,code, address(0x5690)
        .global __StaticMfgParameterFlash
        .fillupper 0xFF                         ; fill upper byte with 0xFF (resulting "instructions" will be NOPR)
        .word   0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF

    Hex file correctly has 24-bit 0xFFFFF values.
     
    I think there is a way to do it in C, but as you said... it's isn't as easy.
    #6
    jeff_d
    Starting Member
    • Total Posts : 45
    • Reward points : 0
    • Joined: 2017/12/11 08:49:30
    • Location: 0
    • Status: offline
    Re: Question about reserving space in flash with XC16 2019/11/13 10:33:47 (permalink)
    0
    duaneh
    When you store variables in flash memory, be sure you take into account the smallest block which can be erased.  To save 1 byte, you have to read that entire block, change the value which needs to be updated, erase the block, and then re-write the whole block.  Another consideration will be write endurance if this is updated often, as program space is typically specified for 100K writes max.  If it's once a day, no issue. If you're doing real-time logging, things can hit the limit very quickly.

    Yeah, totally familiar with this. The page size erase (in a page with configuration bits) is what I'm attempting to work around by reserving space which, if written, gets written as 0xFFFFFF so it can be later changed with the tblwrl/h functions. I only want to write into this region once and the hex file contains values for this region. I need the hex file to have a gap or filll with 0xFFFFFF, and I'm not sure the mfg tools used work with the gap.
     
    The part I'm using has a 10,000 guranteed erase durabiltiy, which I think indicates it's pretty old/inexpensive flash. I've worked with flash memory for a long time and can't recall being concerned with erase counts until using this part.
    #7
    Jump to:
    © 2019 APG vNext Commercial Version 4.5