Specifying RAM address for variable in C

Status
Not open for further replies.

Rusttree

Member
I'm using SDCC v3.2.0.

The USB module in the PIC18F14K50 requires that all USB related data be put in RAM at addresses between 0x200 and 0x2FF. I've written a light-weight USB stack before, but I ended up using SDCC's absolute addressing syntax of:
Code:
varType __at (0x200) varName; //Puts variable varName at RAM address 0x200
Obviously, specifying the address of every variable related to USB is pretty clunky. Instead, I would like to tell the compiler which databank to put those variables in and let the linker do its job.

In the SDCC manual, on page 73, it shows an example of doing this. However, I haven't gotten it to successfully work. Here's my modified linker script. All I changed was adding the "SECTION" line at the bottom.
Code:
LIBPATH .

CODEPAGE   NAME=page       START=0x0               END=0x3FFF
CODEPAGE   NAME=idlocs     START=0x200000          END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000          END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000          END=0xF000FF       PROTECTED

ACCESSBANK NAME=accessram  START=0x0            END=0x5F
DATABANK   NAME=gpr0       START=0x60           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0x1FF
DATABANK   NAME=gpr2       START=0x200          END=0x2FF
DATABANK   NAME=sfr15      START=0xF40          END=0xF5F          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED

SECTION NAME=bank2 RAM=gpr2  #I added this line
And here's my basic program using the pragma syntax from the SDCC manual.
Code:
void main()
{
#pragma udata bank2 a
    unsigned char a;
    unsigned char* pa = &a;

    print16bitVal((int)pa);

    while(1);
}
It appears the #pragma isn't doing anything. Based on the printed value of (int)pa, the location of "a" appears to be in gpr0 with or without the #pragma. Incidentally, if I specify the absolute address using the __at command, then printing (int)pa gives me the correct value. So I know my pointers and print statement are working. Any ideas what I'm doing wrong?
 
One way of doing this in C is to put all data in a structure and initialize a pointer for the structure at address 0x200.

Code:
struct usb_data {
    char   foo;
    int    bar;
};

/* Define the pointer */
#define data (*(volatile struct usb_data*)0x200)

void main(void)
{
    /* access the data */
    data.foo = 0x01;
    data.bar = 4000;

    while(1)
    {
    }
}
 
I won't use the pic16 port of SDCC as it is still VERY unstable.


The MCS51 port seems to be fine...
 
misterT,
Clever workaround. I did end up figuring out the problem, though. I was trying to instantiate the variable as local to main(). For the variable to be located in the gpr2 databank, I needed to make it a global. Once I moved the instantiation outside of main(), it worked fine.

Ian Rogers,
I've actually done a lot of projects lately using the pic16 port on SDCC and haven't run into any real problems yet. Specifically, I wrote a USB stack (the project I'm improving on right now, actually) and a mini TCP/IP stack. Both pretty complex programs. What kind of instabilities have you encountered? Maybe I'm just not noticing them.
 
The web site tells me its unstable.... I'd love to start using SDCC for pic's.... As you are experiencing few problems I may start using it..... It has always done me well for the MCS51 port.

Thanks for that info...
 

Good if you got it working. It is better to let the compiler (linker) place the variable in the right memory location. That way the memory is actually allocated for the variables. My way just writes to an unallocated memory.. there is a risk that the compiler places other variables to the same memory location.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…