• AVR Freaks

Copying from a space(prog) array to RAM

Author
DarioG
Allmächtig.
  • Total Posts : 54081
  • Reward points : 0
  • Joined: 2006/02/25 08:58:22
  • Location: Oesterreich
  • Status: offline
2008/04/23 01:46:09 (permalink)
0

Copying from a space(prog) array to RAM

I'm trying to send a large array to TCP/IP
http://forum.microchip.com/fb.aspx?m=332421

but can't copy correctly its bytes to RAM, for further sending to TCP socket.

I'm using code like in this piece of example:

#include "stdio.h"
#include "libpic30.h"

void display_mem(char *p, unsigned int len) {
int i;
for (i = 0; i < len; i++) {
printf(" %d", *p++);
}
printf("\n");
}

char __attribute__((space(prog))) dat[] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

char buf[10];

int main() {
int i;
_prog_addressT p;

/* method 1 */
_init_prog_address(p, dat);
(void) _memcpy_p2d16(buf, p, 10);

display_mem(buf,10);

/* method 2 */
_init_prog_address(p, dat);
p = _memcpy_p2d16(buf, p, 4);
p = _memcpy_p2d16(&buf[4], p, 6);

display_mem(buf,10);
}


but I don't get the proper bytes. I tried basically method 1 - but can't see the differences between the 2.

My array is declared in a similar way:

extern const BYTE __attribute__((space(prog))) image1_bmp[];

I also don't understand exactly what is the meaning of "copies 16 bits of data from each address in program memory to data memory." or 24 bits...
Does it mean that it copies "n 16bits words" or "n 24bits words" until the desired number of bytes is reached?

Or am I missing something? (I understand it has to do with the PIC's architecture...)

PS I changed Code Model to "large" otherwise I'd not have compiled the firmware. PIC is 24 HJ256GP610, ROM footprint is 40K (circa 50%).

GENOVA :D :D ! GODO
#1

18 Replies Related Threads

    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:08:13 (permalink)
    0
    each even program address (there are no odds) has 24 bits of data, not 16, so with the subroutine you are using you only get the 16, which is what you want.  Why aren't you using auto_psv?  Then you don't have to mess with any of this.
    #2
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:11:07 (permalink)
    0
    Thank you Occam!

    If you explain me a bit more about "auto_psv"... I'll be thankful. I'm just learning with it - I tried a space(psv) array but it would not fit (or other error I can't remember now).
    Would it work with a 20-30KB array or larger?

    GENOVA :D :D ! GODO
    #3
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:21:39 (permalink)
    0
    It does have a size limit, but for stepper motor sine commutation I use this without any trouble:

    const unsigned int steps[NUM_STEP_LOOKUP_ELEMENTS] __attribute__((space(auto_psv))) = {...};

    Are you using C30 3.02c?
    #4
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:27:46 (permalink)
    0
    I see: do you mean that, with auto_psv, I can access the array directly WITHOUT the memcpy thing?

    I can try...

    BTW: my compiler is still 3.01 - at least this in the readme, files are from June 2007. Is there a way to check the actual version of GCC? I tried "pic30-gcc -help" and it won't work...



    GENOVA :D :D ! GODO
    #5
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:43:16 (permalink)
    0
    There is probably some easy way to tell what version the compiler is, but I've never found it.  I look at the readme file to see the version in the notes.

    3.01 should have auto_psv access.  Why not just upgrade to 3.02c?  I've had no trouble with it and unless you are using transparent unions like zardoz I don;t know of other issues.
    #6
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:45:49 (permalink)
    0
    Done that in the meanwhile Smile

    But,
    do you mean that, with auto_psv, I can access the array directly WITHOUT the memcpy thing?


    I found these threads
    http://forum.microchip.com/tm.aspx?m=207021
    http://forum.microchip.com/tm.aspx?m=291290

    and looks like that, though still not completely sure ...

    The final point would be: with auto_psv i can reach 32K, but what if I wanted even more? space(prog) should do that, or am I wrong?

    GENOVA :D :D ! GODO
    #7
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 03:54:35 (permalink)
    0
    Correct, auto_psv allows direct access from the compiler.  What you will see is that the address for that variable has the MSBit set.  This tells the core to apply the PSV_PAGE to the upper bits of the address and then you are pointing to ROM.  In the IDE you will see a "P" in the field to the left of the variables.  This also means you are guaranteeing the compiler you will not mess with the PSV register stuff so it knows where it is at all times.

    If you want more you can us prog, but I'm not sure if it packs it 24 bits per memory address, you'll see every third byte missing in your array if it does.  My first guess is that it does not.  I'm fairly certain about that.  However, the compiler does pack 24 bits of data per program address for the initialization data for run-time initialized variables.  If you look at the crt*.s files in the compiler directory you can see them pulling it out at boot.
    #8
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 04:04:59 (permalink)
    0
    Ok, I'll try the auto_psv thing.

    In the meanwhile, with 3.02 C30, the above code is not compiling anymore...
    I'm checking the new docs now.

    GENOVA :D :D ! GODO
    #9
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 04:35:51 (permalink)
    0
    Hmmm, crazy...

    • 3.02c changed the way that the code to read from space(prog) works. I changed my code according to the release notes, but it still won't execute properly (i.e. garbage).
    • if I change the pointer to auto_psv and use a auto_psv pointer to access the array and send its bytes to TCPIP (*without* copying to RAM... should not be needed anymore...) , the WHOLE MPFS2 GETS SCRAMBLED and I can't even display home page ![:@]
    Didn't they say that "PIC18 memory was a complicated matter"? This does not look any better winkSmile

    GENOVA :D :D ! GODO
    #10
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 04:37:55 (permalink)
    0
    Are you using interrupts?
    #11
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 05:17:05 (permalink)
    0
    Hmmm, no, apart from Timer ones - just incrementing a counter (as from Microchip TCPIP stack)...

    should I save psv in that?

    GENOVA :D :D ! GODO
    #12
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 05:29:22 (permalink)
    0
    ORIGINAL: OccamMD

    There is probably some easy way to tell what version the compiler is, but I've never found it.  I look at the readme file to see the version in the notes.



    The Docs state:
    pic30-gcc --version

    should tell us, but I still get an error This language tool name is invalid

    launching the exe from BIN folder inside C30...

    I guess that the Target CPU has to be specified too...

    GENOVA :D :D ! GODO
    #13
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 05:45:38 (permalink)
    0
    Just make sure you have your interrupts set like this if you are not using an auto_psv variable within the interrupt:

    void __attribute__((interrupt, no_auto_psv)) _ADC1Interrupt(void)

    and like this if you are using an auto_psv variable:

    void __attribute__((interrupt, auto_psv)) _ADC1Interrupt(void)

    You can default to the last one for all if you want, just some overhead.
    #14
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 05:58:04 (permalink)
    0
    Yep, I checked that.
    Only a simple long variable is used down there, anyway I added the "auto_psv" thing.

    But now I'm checking the 24bit pointers in the Docs...

    GENOVA :D :D ! GODO
    #15
    OccamMD
    Super Member
    • Total Posts : 1692
    • Reward points : 0
    • Joined: 2005/06/17 08:41:06
    • Location: Tampa, FL
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 06:51:09 (permalink)
    0
    OK, make sure you have volatile for all your interrupt variables used by other things.

    As far as pointers, I believe for 24 bit pointers the compiler has a 16 bit pointer that references a "call island" at the end of it's local memory space to get past +/-32K jumps.  There is a thread in the C30 compiler forum I started and calum answered it.
    #16
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 08:15:11 (permalink)
    0
    Ok, I resolved to this approach (from http://forum.microchip.com/tm.aspx?m=332421 )


    void HTTPPrint_image2(void) {
        const BYTE __prog__ *imageptr;
        WORD count,len;
      BYTE myBuf[BMP_CHUNK_SIZE];
      int i;

        LED2_IO ^= 1;

        imageptr=image1_bmp;

      if(curHTTP.callbackPos < image1_bmp_size) {
            count = TCPIsPutReady(sktHTTP);
            len=mMIN(count, BMP_CHUNK_SIZE);
            if(len>0) {
                imageptr+=curHTTP.callbackPos;
                for(i=0; i<BMP_CHUNK_SIZE; i++) {
                    myBuf[i]=*imageptr++;
                    }
                TCPPutArray(sktHTTP, myBuf , len);
                curHTTP.callbackPos+=len;
                }
            }
        else {
            curHTTP.callbackPos=0;
            }

        }



    It uses "huge" space(prog) pointers, so it's good enough

    I still would like to find a way to do "memcpy" from __prog__ pointers to RAM...
    or maybe it's easier to write a TCPPutArray which deals with those pointers...


    @Occam: I removed the auto_psv saver from the interrupt handler, looks like it is not needed in this case.



    GENOVA :D :D ! GODO
    #17
    aschen0866
    Super Member
    • Total Posts : 4494
    • Reward points : 0
    • Joined: 2006/01/08 22:18:32
    • Location: San Diego
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 10:12:32 (permalink)
    0
    ORIGINAL: DarioG

    #include "stdio.h"
    #include "libpic30.h"
    ...
    char __attribute__((space(prog))) dat[] =
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    char buf[10];

    int main() {
    int i;
    _prog_addressT p;

    /* method 1 */
    _init_prog_address(p, dat);
    (void) _memcpy_p2d16(buf, p, 10);
    ...
    }


    Your "method 1" should work. I haven't tried it on a real piece of hardware, but it seems to be just fine with simulation.
     
    If you want to use the MSB of 24-bit Program Memory space, you'll need to create your data object in a separated assembly file, for example,


    .section *, code
    .global _foo
    _foo: .pbyte 0x00, 0x01, 0x02, 0x03
     

    Then use _memcpy_p2d24() to copy it to RAM.

    #include <P24FJ128GA006.h>
    #include <stdio.h>
    #include <libpic30.h>

    extern BYTE __attribute__((space(prog))) foo[4];
     
    int main(void)
    {
       char bar[4];
       _prog_addressT p;
     
       _init_prog_address(p, foo);
       _memcpy_p2d24(bar, p, sizeof(bar));
      
       while (1);
       return 0;


    #18
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Copying from a space(prog) array to RAM 2008/04/23 16:04:25 (permalink)
    0
    Thank you Aschen, your post explains "when" to use the 16bit ROM routine and the 24bit one.

    I will try it maybe tomorrow - My code as posted above, with the explicit loop, does work -  though maybe a bit slow.
    I also had probably declared my pointer badly, i.e. "const char __attribute__((space(prog))) *imageptr" instead of "const BYTE __prog__ *imageptr;" ... I'm not sure of this, and there were no warning.

    GENOVA :D :D ! GODO
    #19
    Jump to:
    © 2019 APG vNext Commercial Version 4.5