Help with modifing PIC linker file

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
I need to be able to allocate a 512 byte string in my program. From what I have leaned, I need to preallocate a 512 byte region with a custom linker file.

I understand it would be something like this:

Rich (BB code):
DATABANK   NAME=myMSD      START=0x600          END=0x7FF          PROTECTED

But when I look at the default linker file, I am not sure what to put for the starting address of my databank.

Can I just eliminate one or more of the gprX entries and fit it in there?

The device has 3.8K of RAM.


Rich (BB code):
// File: 18lf27j53_g.lkr
// Generic linker script for the PIC18LF27J53 processor

#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN

LIBPATH .

#IFDEF _CRUNTIME
  #IFDEF _EXTENDEDMODE
    FILES c018i_e.o
    FILES clib_e.lib
    FILES p18lf27j53_e.lib

  #ELSE
    FILES c018i.o
    FILES clib.lib
    FILES p18lf27j53.lib
  #FI

#FI

#IFDEF _DEBUGCODESTART
  CODEPAGE   NAME=page       START=0x0               END=_CODEEND
  CODEPAGE   NAME=debug      START=_DEBUGCODESTART   END=_CEND        PROTECTED
#ELSE
  CODEPAGE   NAME=page       START=0x0               END=0x1FFF7
#FI

CODEPAGE   NAME=config     START=0x1FFF8           END=0x1FFFF        PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED

#IFDEF _EXTENDEDMODE
  DATABANK   NAME=gpre       START=0x0               END=0x5F
#ELSE
  ACCESSBANK NAME=accessram  START=0x0               END=0x5F
#FI

DATABANK   NAME=gpr0       START=0x60              END=0xFF
DATABANK   NAME=gpr1       START=0x100             END=0x1FF
DATABANK   NAME=gpr2       START=0x200             END=0x2FF
DATABANK   NAME=gpr3       START=0x300             END=0x3FF
DATABANK   NAME=gpr4       START=0x400             END=0x4FF
DATABANK   NAME=gpr5       START=0x500             END=0x5FF
DATABANK   NAME=gpr6       START=0x600             END=0x6FF
DATABANK   NAME=gpr7       START=0x700             END=0x7FF
DATABANK   NAME=gpr8       START=0x800             END=0x8FF
DATABANK   NAME=gpr9       START=0x900             END=0x9FF
DATABANK   NAME=gpr10      START=0xA00             END=0xAFF
DATABANK   NAME=gpr11      START=0xB00             END=0xBFF

#IFDEF _DEBUGDATASTART
  DATABANK   NAME=gpr12      START=0xC00             END=_DATAEND
  DATABANK   NAME=dbgspr     START=_DEBUGDATASTART   END=_DEND           PROTECTED
#ELSE //no debug
  DATABANK   NAME=gpr12      START=0xC00             END=0xCFF
#FI

DATABANK   NAME=gpr13      START=0xD00             END=0xDFF
DATABANK   NAME=gpr14      START=0xE00             END=0xEAF
DATABANK   NAME=sfr14      START=0xEB0             END=0xEFF          PROTECTED
DATABANK   NAME=sfr15      START=0xF00             END=0xF5F          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60             END=0xFFF          PROTECTED



#IFDEF _CRUNTIME
  SECTION    NAME=CONFIG     ROM=config
  #IFDEF _DEBUGDATASTART
    STACK SIZE=0x100 RAM=gpr11
  #ELSE
    STACK SIZE=0x100 RAM=gpr12
  #FI
#FI
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
What am I missing.

Here is my modified linker file:

Rich (BB code):
// File: 18f27j53_g.lkr
// Generic linker script for the PIC18F27J53 processor

#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN

LIBPATH .

#IFDEF _CRUNTIME
  #IFDEF _EXTENDEDMODE
    FILES c018i_e.o
    FILES clib_e.lib
    FILES p18f27j53_e.lib

  #ELSE
    FILES c018i.o
    FILES clib.lib
    FILES p18f27j53.lib
  #FI

#FI

#IFDEF _DEBUGCODESTART
  CODEPAGE   NAME=page       START=0x0               END=_CODEEND
  CODEPAGE   NAME=debug      START=_DEBUGCODESTART   END=_CEND        PROTECTED
#ELSE
  CODEPAGE   NAME=page       START=0x0               END=0x1FFF7
#FI

CODEPAGE   NAME=config     START=0x1FFF8           END=0x1FFFF        PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE          END=0x3FFFFF       PROTECTED

#IFDEF _EXTENDEDMODE
  DATABANK   NAME=gpre       START=0x0               END=0x5F
#ELSE
  ACCESSBANK NAME=accessram  START=0x0               END=0x5F
#FI

DATABANK   NAME=gpr0       START=0x60              END=0xFF
DATABANK   NAME=gpr1       START=0x100             END=0x1FF
DATABANK   NAME=gpr2       START=0x200             END=0x2FF
DATABANK   NAME=gpr3       START=0x300             END=0x3FF
DATABANK   NAME=gpr4       START=0x400             END=0x4FF
DATABANK   NAME=gpr5       START=0x500             END=0x5FF


DATABANK   NAME=myMSD      START=0x600             END=0x7FF          PROTECTED   
    
DATABANK   NAME=gpr8       START=0x800             END=0x8FF
DATABANK   NAME=gpr9       START=0x900             END=0x9FF
DATABANK   NAME=gpr10      START=0xA00             END=0xAFF
DATABANK   NAME=gpr11      START=0xB00             END=0xBFF

#IFDEF _DEBUGDATASTART
  DATABANK   NAME=gpr12      START=0xC00             END=_DATAEND
  DATABANK   NAME=dbgspr     START=_DEBUGDATASTART   END=_DEND           PROTECTED
#ELSE //no debug
  DATABANK   NAME=gpr12      START=0xC00             END=0xCFF
#FI

DATABANK   NAME=gpr13      START=0xD00             END=0xDFF
DATABANK   NAME=gpr14      START=0xE00             END=0xEAF
DATABANK   NAME=sfr14      START=0xEB0             END=0xEFF          PROTECTED
DATABANK   NAME=sfr15      START=0xF00             END=0xF5F          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60             END=0xFFF          PROTECTED

#IFDEF _CRUNTIME
  SECTION    NAME=CONFIG     ROM=config
  #IFDEF _DEBUGDATASTART
    STACK SIZE=0x100 RAM=gpr11
  #ELSE
    STACK SIZE=0x100 RAM=gpr12
  #FI
#FI

I modified my C code as follow:

Rich (BB code):
#pragma udata myMSD=0x600
volatile far char msd_buffer[512];
Yet I still get

Error - section 'myMSD' can not fit the absolute section. Section 'myMSD' start=0x00000600, length=0x0000022a


What am I missing?
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
Here is my map file:

Rich (BB code):
DATABANKS:
    Memory      Start        End              Section    Address Size(Bytes)
 ---------  ---------  ---------            ---------  ---------  ---------
      gpr0     0x0060     0x00ff                                           

      gpr1     0x0100     0x01ff                                           

      gpr2     0x0200     0x02ff                                           

      gpr3     0x0300     0x03ff                                           

      gpr4     0x0400     0x04ff                                           

      gpr5     0x0500     0x05ff                                           

     myMSD     0x0600     0x07ff                                           

      gpr8     0x0800     0x08ff                                           

      gpr9     0x0900     0x09ff                                           

     gpr10     0x0a00     0x0aff                                           

     gpr11     0x0b00     0x0bff                                           

     gpr12     0x0c00     0x0cff                                           

     gpr13     0x0d00     0x0dff                                           

     gpr14     0x0e00     0x0eaf                                           

     sfr14     0x0eb0     0x0eff          SFR_BANKED0     0x0eb8     0x0005
                                          SFR_BANKED1     0x0ebf     0x000f
                                          SFR_BANKED2     0x0ed1     0x0002
                                          SFR_BANKED3     0x0ee1     0x0004
                                          SFR_BANKED4     0x0ee6     0x0005
                                          SFR_BANKED5     0x0ef2     0x0003
                                          SFR_BANKED6     0x0ef7     0x0002
                                          SFR_BANKED7     0x0efc     0x0004

     sfr15     0x0f00     0x0f5f          SFR_BANKED8     0x0f00     0x0043
                                          SFR_BANKED9     0x0f44     0x0010


ACCESSBANKS:
    Memory      Start        End              Section    Address Size(Bytes)
 ---------  ---------  ---------            ---------  ---------  ---------
 accessram     0x0000     0x005f                                           

 accesssfr     0x0f60     0x0fff        SFR_UNBANKED0     0x0f60     0x00a0
 

ErnieM

Joined Apr 24, 2011
8,377
There is a section in the "MPLAB C18 Users Guide" (found in the MPLAB Help | Topics... area) named "Application: Creating Large Data Objects and the USART" that describes how to do this.

Change the linker script to remove two or more sections (such as 2 & 3), and make a new larger section:
Rich (BB code):
//DATABANK   NAME=gpr2       START=0x200             END=0x2FF
//DATABANK   NAME=gpr3       START=0x300             END=0x3FF

DATABANK   NAME=big        START=0x200             END=0x3FF PROTECTED
"PROTECTED" keeps the linker from using it unless explicitly called for.

To use this area define a variable in that area. You then can use a pointer to get there. (Note the #pragma to set the section).
Rich (BB code):
#pragma udata buffer_scn
static char msd_buffer[0x200];
#pragma udata

void main(void)
{
  // access the RAM section thru a pointer:
  char * buf_ptr = &msd_buffer[0];
  int i;
  // examples of use
  buf_ptr[5] = 10;
  for(i=0; i<=0x200; i++)
  {
    buf_ptr = i;
  }  
  while(1);  
}
 

ErnieM

Joined Apr 24, 2011
8,377
How does the section name apply in my code? Or is it just there in the linker file?
Rich (BB code):
#pragma udata buffer_scn
static char msd_buffer[0x200];
#pragma udata
The first #pragma instructs the linker to specifically use the "buffer_scn" area.

The second #pragma instructs the linker to use any open area.
 

Thread Starter

spinnaker

Joined Oct 29, 2009
7,830
Thanks I understand that part. My question was, what is the purpose of the Section keyword in the linker file. Because it does seem to work for me with no Section specified in the linker file.
 
Top