• AVR Freaks

Using Flash Area :)

Page: 12 > Showing page 1 of 2
Author
BasePointer
Senior Member
  • Total Posts : 161
  • Reward points : 0
  • Joined: 2003/11/07 12:42:11
  • Location: Turkey
  • Status: offline
2009/03/16 06:33:19 (permalink)
0

Using Flash Area :)

Hi,

We are using PIC24FJ256GA106. I know a flash page is 512 instructions (512*3=1536bytes) to erase. And 64 instructions (64*3=192bytes) to write at a time.

Actually I need 512bytes flash area totally. I have a structure named TNVRAM (sizeof it is 512byte). This strucure is in RAM. I periodically(every month) want to copy this variable to flash area and read back if any corruption occurs on the variable in RAM (checked via CRC).

So, to do this, I need that:
1. How can I tell the linker(C30 v3.11) to reserve 1536bytes by beginning from 0x600 to 0xBFF (totally 1536bytes, a page, here seems as User Flash Program Memory)? The linker shoud not place any code to this space.
2. How can I define a constant variable and tell compiler(C30 v3.11) that the address of this variable will be 0x600?


const TNVRAM *BACKUP_NV_PTR = (const TNVRAM*)0x000600; ??
_PERSISTENT TNVRAM NV;

3. Can I use BACKUP_NV_PTR such as normal constants? For example:


NV.SeriNo = BACKUP_NV_PTR->SeriNo; // (unsigned long)

4. How can I erase the flash page between 0x600 to 0xBFF (1536 bytes)?
5. How can I copy the content of NV in RAM to BACKUP_NV in flash?
6. What changes if I place this constant to 0x2A000 instead of 0x600? (last page of PIC24FJ256GA106 that doesnt include config words)

7. I don't want to use DEE Emulation library of microchip. I don't like it at all. and I don't know why :)


Thank you so much for your helps,
BP.
post edited by BasePointer - 2009/03/24 06:51:40
#1

24 Replies Related Threads

    cawilkie
    Administrator
    • Total Posts : 1977
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    RE: Using Flash Area :) 2009/03/16 10:51:28 (permalink)
    0
    From the docs, not tried but I'm sure you can try it and read the same docs I did.


    #include <libpic30.h>

    /* in FLASH, 1024 bytes (1536 if we inlcude the upper byte)
    starting at address 0x600... see section on attribute in the C30 compiler
    guide */
    char buffer[1024] __attribute__((space(prog),address(0x600)));

    char ram_buffer[1536];

    /* See section 4.7 or libraries guide, and the example at the end of the
    chapter */

    main() {
    _prog_addressT p;
    char *source = ram_buffer;

    _init_prog_address(p, buffer); /* get address in program space */
    _erase_flash(p); /* erase a page */

    while (source < &ram_buffer[1536]) {
    _write_flash24(p, source); /* write first row with 16-bit data */
    p+= _FLASH_ROW*2;
    source += _FLASH_ROW*2;
    }
    }


    Q. What do you think needs to be changed to move the buffer?

    Enjoy.
    #2
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/16 12:01:20 (permalink)
    -2 (1)
    Which document? Microchip's C30 documents are like a bad soup.

    unsigned char nv_buffer[1024] __attribute__((space(prog), address(0x600)));

    void BACKUP_NV_Write(void)
    {
      _prog_addressT  p;
      unsigned char *source = (unsigned char*)&NV;
      unsigned int size = sizeof(TNVRAM);
     
      _init_prog_address(p, nv_buffer);
      _erase_flash(p);
     
      while(size--)
      {
        _write_flash24(p, source);
        p+= _FLASH_ROW*2;
        source += _FLASH_ROW*2;
      }
    }
     

    Map File:

    External Symbols in Program Memory (by address):
    ...
    0x000556                  __DefaultInterrupt
    0x000600                  _nv_buffer    <------------------------ this is ok, but
    0x000a00                  __resetPRI    <------------------------ what is this at 0x0A00?
    0x000a1e                  __psv_init
    0x000a2e                  __data_init
    ...


    How can I declare a pointer for a "const TNVRAM" in flash? I don't want to copy whole const data to ram. I just want to reach some items of it like a const data.

    10x,
    BP. 
    post edited by BasePointer - 2009/03/16 12:21:55
    #3
    cawilkie
    Administrator
    • Total Posts : 1977
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    RE: Using Flash Area :) 2009/03/16 15:24:05 (permalink)
    0
    C30 users guide for the attributes and what they do.
    The libraries guide for library functions and what they do.

    Do you care what __resetPRI is if your buffer is where you want it to be and it is the correct length? Chances are there are lots of external symbols that are unknown.

    FLASH is a strange beast, it can be accessed through PSV or by copying parts out - there are some functions provided for copying data in and out.
    PSV is described in the data sheets and the compiler guide attributes describe how to access them.

    Unfortunately these guides are not users manuals (really) but provide reference for the compiler features.

    Regards
    Calum
    #4
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/19 04:52:52 (permalink)
    0
    Hi,

    I'm getting address error trap with _erase_flash(p) with the codes below.
    I also wonder differences between "const" identifier and "space(prog)" attribute. Aren't they same?
     


    #define   FLASH_BACKUP_ADDR   0x000600
     
     _PERSISTENT TNVRAM       NV;
      unsigned char nv_buffer[1536] __attribute__((space(prog), address(FLASH_BACKUP_ADDR)));
     
     
    void BACKUP_NV_Write(void)
    {
      _prog_addressT  p;
      unsigned char *source = (unsigned char*)&NV;
      signed int size = sizeof(TNVRAM);
     
      _init_prog_address(p, nv_buffer);
      _erase_flash(p);    // <======== generates address error trap
     
      while(size > 0)
      {
        size -= _FLASH_ROW*2;
        _write_flash24(p, source);
        p+= _FLASH_ROW*2;
        source += _FLASH_ROW*2;
      }
    }
     
    unsigned char CreateBP(void)
    {
      BACKUP_NV_Write();
     
      if( memcmp((const unsigned char*)FLASH_BACKUP_ADDR, (unsigned char*)&NV, sizeof(TNVRAM)) == 0)
       return(1);
     
      return(0);
    }
     
    post edited by BasePointer - 2009/03/24 09:36:49
    #5
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 06:51:27 (permalink)
    0
    Hi again,
     
    Why ticket system doesn't work, I'm waiting a reply for a week.
    I still can't solve the problem. Is "const unsigned char*" a valid pointer type for a constant data in flash?
    What about the type _prog_addressT, there is no info in manuels about it at all.
     
    #6
    aschen0866
    Super Member
    • Total Posts : 4478
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 07:12:58 (permalink)
    0
    #define   FLASH_BACKUP_ADDR   0x000600
     
     _PERSISTENT TNVRAM       NV;
      unsigned char nv_buffer[1586] __attribute__((space(prog), address(FLASH_BACKUP_ADDR)));
     
     
    void BACKUP_NV_Write(void)
    {
      _prog_addressT  p;
      unsigned char *source = (unsigned char*)&NV;
      signed int size = sizeof(TNVRAM);
     
      _init_prog_address(p, nv_buffer);
      _erase_flash(p);    // <======== generates address error trap
     

    When calling _erase_flash(), the address must be the beginning of a Flash page. For PIC24F, it would be 0, 0x400, 0x800, 0xC00, ...etc.
    #7
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 08:26:30 (permalink)
    0
    ORIGINAL: BasePointer
    We are using PIC24FJ256GA106. I know a flash page is 512 instructions (512*3=1536bytes) to erase. And 64 instructions (64*3=192bytes) to write at a time. 

     
    Isn't a page 1536 byte (512 instructions) ? That means 0x600, 0xC00, 0x1200 etc..?
     
    10x,
    BP.
    #8
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 08:49:42 (permalink)
    0
     
    Well, I dont understant why but I moved start address to 0x0C00 that is dividable by both 1024 and 1536, and address error has gone. But memcmp() function never tells data in flash and data in ram are same. What do you think about this?
     
    10x,
    BP.
     
     
    #9
    guymc
    Administrator
    • Total Posts : 769
    • Reward points : 0
    • Joined: 2004/06/08 07:14:37
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 09:51:26 (permalink)
    0
    But memcmp() function never tells data in flash and data in ram are same. What do you think about this?

    It seems that you are confused by the fact that program memory and data memory are two different address spaces.

    Certain library functions can accept arguments from both, such as _write_flash24(), and _memcpy_p2d24().

    The standard C function memcmp() can accept arguments from data memory only.

    For now your best bet is to copy the data back into RAM, and then compare.

    Cheers..
    post edited by guymc - 2009/03/24 09:52:27
    #10
    aschen0866
    Super Member
    • Total Posts : 4478
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 09:54:45 (permalink)
    0
    512 instructions per page and each instruction can only take one even address, therefore 512 x 2 = 1024 and the address range will be 0 - 0x3FF.
    #11
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 10:07:57 (permalink)
    0
    ORIGINAL: guymc

    But memcmp() function never tells data in flash and data in ram are same. What do you think about this?

    It seems that you are confused by the fact that program memory and data memory are two different address spaces.

    Certain library functions can accept arguments from both, such as _write_flash24(), and _memcpy_p2d24().

    The standard C function memcmp() can accept arguments from data memory only.

    For now your best bet is to copy the data back into RAM, and then compare.

    Cheers..

     
    Hi,
     
    I don't want to copy whole constant data to ram to compare. For example, the code below returns 1. It compares buff1 in ram and buff2 in flash succesfully.
     
    const unsigned char buff2[] = "Hello Every Body!";
    unsigned char compare(void)
    {
      unsigned char buff1[] = "Hello";
     
      if( memcmp(buff1, buff2, 5) == 0)
        return(1);
     
      ..
    }
    #12
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 10:13:21 (permalink)
    0
    ORIGINAL: aschen0866

    512 instructions per page and each instruction can only take one even address, therefore 512 x 2 = 1024 and the address range will be 0 - 0x3FF.

     
    Hi,
     
    Well, as I said the address error has gone but I'm looking at program memory with REALICE, the address 0x0C00 still seems as all zero after BACKUP_NV_Write() function.
     
    10x,
    BP.
    #13
    guymc
    Administrator
    • Total Posts : 769
    • Reward points : 0
    • Joined: 2004/06/08 07:14:37
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 11:02:34 (permalink)
    0
    Hi,

    I don't want to copy whole constant data to ram to compare. For example, the code below returns 1. It compares buff1 in ram and buff2 in flash succesfully.

    const unsigned char buff2[] = "Hello Every Body!";
    unsigned char compare(void)
    {
    unsigned char buff1[] = "Hello";

    if( memcmp(buff1, buff2, 5) == 0)
    return(1);

    ..
    }

    In this example, buff2 has been allocated in space(auto_psv). The compiler manages access to this variable automatically, using the PSV window. In your earlier example, nv_buffer is allocated in space(prog), which is not accessible via ordinary C statements, or standard library functions.

    Refer to chapter 2.3.1 and 4.14 in the C30 manual for an explanation of why these use cases are different.

    Future versions of the compiler may utilize variables in program memory more easily. But for now, some tasks are awkward to deal with.

    Hope this helps...
    #14
    cawilkie
    Administrator
    • Total Posts : 1977
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 14:21:24 (permalink)
    0

    ORIGINAL: BasePointer

    ORIGINAL: aschen0866

    512 instructions per page and each instruction can only take one even address, therefore 512 x 2 = 1024 and the address range will be 0 - 0x3FF.


    Hi,

    Well, as I said the address error has gone but I'm looking at program memory with REALICE, the address 0x0C00 still seems as all zero after BACKUP_NV_Write() function.

    10x,
    BP.



    Did you re-read program memory after the erase? The IDE doesn't automatically re-read FLASH when you stop (that would take a long time if done every time).

    Regards
    Calum
    #15
    cawilkie
    Administrator
    • Total Posts : 1977
    • Reward points : 0
    • Joined: 2003/11/07 12:49:11
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 14:23:54 (permalink)
    0

    ORIGINAL: BasePointer

    Hi,

    I'm getting address error trap with _erase_flash(p) with the codes below.
    I also wonder differences between "const" identifier and "space(prog)" attribute. Aren't they same?
     


    #define   FLASH_BACKUP_ADDR   0x000600
     
     _PERSISTENT TNVRAM       NV;
      unsigned char nv_buffer[1536] __attribute__((space(prog), address(FLASH_BACKUP_ADDR)));
     
     
    void BACKUP_NV_Write(void)
    {
      _prog_addressT  p;
      unsigned char *source = (unsigned char*)&NV;
      signed int size = sizeof(TNVRAM);
     
      _init_prog_address(p, nv_buffer);
      _erase_flash(p);    // <======== generates address error trap
     
      while(size > 0)
      {
        size -= _FLASH_ROW*2;
        _write_flash24(p, source);
        p+= _FLASH_ROW*2;
        source += _FLASH_ROW*2;
      }
    }
     
    unsigned char CreateBP(void)
    {
      BACKUP_NV_Write();
     
      if( memcmp((const unsigned char*)FLASH_BACKUP_ADDR, (unsigned char*)&NV, sizeof(TNVRAM)) == 0)
       return(1);
     
      return(0);
    }
     



    This array is too big, 1536 chars in FLASH would occupy 1536/2*3 or 2304 bytes of FLASH. The compiler does not make use of the upper byte.
    #16
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 23:29:24 (permalink)
    0
    ORIGINAL: cawilkie
    This array is too big, 1536 chars in FLASH would occupy 1536/2*3 or 2304 bytes of FLASH. The compiler does not make use of the upper byte.

     
    Hi,
     
    According to the map file, compiler has exactly reserved 1536 byte for nv_buffer[1536] has space(prog) attribute.
    I can write there a data has size 1024 bytes in ram because compiler doesn't use third byte in flash. Is there something that I missed?
     

     External Symbols in Program Memory (by address):
                      ...
                      0x000c00                  _nv_buffer
                      0x001200                  _HEX
                      ...

    #17
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/24 23:47:47 (permalink)
    0
    ORIGINAL: cawilkie

    Did you re-read program memory after the erase? The IDE doesn't automatically re-read FLASH when you stop (that would take a long time if done every time).

    Regards
    Calum

     
    Hi Calum,
     
    Thanks, after reading, I could saw written data:
     

    Attached Image(s)

    #18
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/25 00:05:45 (permalink)
    0
    ORIGINAL: BasePointer

    ORIGINAL: cawilkie

    Did you re-read program memory after the erase? The IDE doesn't automatically re-read FLASH when you stop (that would take a long time if done every time).

    Regards
    Calum


    Hi Calum,

    Thanks, after reading, I could saw written data:




     
    I really puzzled so much after seeing this image  [&:] The address increments 2 by 2 but image shows three bytes for every word. Yes I know PIC24 has 3 byte address bus, but why does address pointer increment 2 by 2 instead of 3?
    #19
    BasePointer
    Senior Member
    • Total Posts : 161
    • Reward points : 0
    • Joined: 2003/11/07 12:42:11
    • Location: Turkey
    • Status: offline
    RE: Using Flash Area :) 2009/03/25 00:42:58 (permalink)
    0
    Hi again,
     
    I think I understand how flash addressing works. I modified the code like below. It exactly write NV in ram to flash as if it was a const. I hope to reach this area with a pointer to constant. I know area 0x0C00 is in PSV window and hope the compiler can handle it automatically. memcmp() still returns 0 with the usage below.
     
     
      #define   FLASH_BACKUP_ADDR   0x000C00
      _PERSISTENT TNVRAM          NV; 
     
      // this will reserve 1024 word in flash, not 1024 byte!
      // every word can hold 2 bytes with _write_flash16() function
      // so we can use this space to store 2048byte data in ram
      unsigned char nv_buffer[1024] __attribute__((space(prog), address(FLASH_BACKUP_ADDR)));
     
    void BACKUP_NV_Write(void)
    {
      _prog_addressT  p;
      unsigned char *source = (unsigned char*)&NV;
      signed int size = sizeof(TNVRAM);
     
      _init_prog_address(p, nv_buffer);
      _erase_flash(p);  // erase 1024 words!
     
      while(size > 0)
      {   
        _write_flash16(p, source);
       
        size -= _FLASH_ROW*2;
        p += _FLASH_ROW*2;
        source += _FLASH_ROW*2;
      }
    }
     
    unsigned char CreateBP(void)
    {
      BACKUP_NV_Write();
     
      if( memcmp((const unsigned char*)FLASH_BACKUP_ADDR, (unsigned char*)&NV, sizeof(TNVRAM)) == 0)
       return(1);
     
      return(0);
    }
     
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5