📄 linker.txt
字号:
#pragma sectionDef EEPROM:eedata 0xF00000 - 0xF000FF PROTECTED
#pragma sectionDef APPSEC:appdef1 0x1000 - 0x102F
#pragma sectionDef PROG
d) Code definition will be adjusted automatically to ensure that
there are no overlapping.
e) When a variable is located at a fixed address, the compiler
will automatically EXCLUDE this address from the default bank
definition in the script file. The largest free region in the
bank will be defined, and made available for allocation by
MPLINK. It is important that the main C module knows all fixed
RAM definitions. Otherwise it is required to make a manual
definition in the script file to exclude "unknown" locations
from normal allocation.
It is also possible to make the linker script file manually,
although this should normally not be preferred. MICROCHIP supplies
sample linker script files for each device with the file extension
'lkr' (look in the MPLAB directory). When making a linker script file
for a specific project, this file can be copied and edited to suit
the needs of CC8E.
The sample MPLINK script files must be changed slightly if the
interrupt function is written in C. The reason is that the interrupt
functions must start at addresses 8 and 0x18 when using CC8E. It
could be possible to use a vector at address 8 / 0x18, but this
slows down interrupt response.
CHANGE 1: Interrupt routine in C WITH a separate logical section.
CC8E generates a partial script file when using the -r2 command line
option (or -r2[=]<file.lkr>). This file is written if (and only if)
CC8E compiles a module with an interrupt service routine. The
generated script file may look like:
CODEPAGE NAME=intserv18 START=0x18 END=0x31
CODEPAGE NAME=page START=0x32 END=0x7FFF
The required change in the main script file is then:
INCLUDE module1.lkr // change to right module/script file name
CHANGE 2: Interrupt routine in C WITHOUT a separate logical section.
Example change:
CODEPAGE NAME=vectors START=0x0 END=0x7 PROTECTED
// NEW VALUE ^------
CODEPAGE NAME=page START=0x8 END=0x7FFF
// NEW VALUE ^------
CHANGE 3: If INTERRUPTS are not used, then the first code page can
start at address 4. Example change:
CODEPAGE NAME=vectors START=0x0 END=0x3 PROTECTED
// NEW VALUE ^------
CODEPAGE NAME=page START=0x4 END=0x7FFF
// NEW VALUE ^------
CHANGE 4: LOGICAL sections must be added. Note that if a logical RAM
section is missing, then the variables that belongs to this section
will be put in the "default" section. MPLINK gives no error on
missing logical sections in the script file and the program will
fail.
SECTION NAME=STARTUP ROM=vectors // Reset vector
SECTION NAME=ISERVER8 ROM=intserv8 // High priority interrupt
SECTION NAME=ISERVER18 ROM=intserv18 // Low priority interrupt
SECTION NAME=PROG ROM=page // code space
SECTION NAME=IDLOCS ROM=idlocs // ID locations
SECTION NAME=CONFIG ROM=config // Configuration bits location
SECTION NAME=EEDATA ROM=eedata // EEPROM data
SECTION NAME=ACSRAM RAM=accessram // ACCESS RAM
SECTION NAME=BANK0 RAM=gpr0 // RAM bank 0
SECTION NAME=BANK1 RAM=gpr1 // RAM bank 1
SECTION NAME=BANK2 RAM=gpr2 // RAM bank 2
SECTION NAME=BANK3 RAM=gpr3 // RAM bank 3
SECTION NAME=BANK4 RAM=gpr4 // RAM bank 4
SECTION NAME=BANK5 RAM=gpr5 // RAM bank 5
CHANGE 5: modifications when using ICD2:
CODEPAGE NAME=page START=.. END=0x7DBF
CODEPAGE NAME=debug START=0x7DC0 END=0X7FFF PROTECTED
DATABANK NAME=gpr5 START=0x500 END=0x5F3
DATABANK NAME=dbgspr START=0x5F4 END=0x5FF PROTECTED
*****
- logical code blocks:
STARTUP startvector
ISERVER8 logical section for the high priority interrupt
ISERVER18 logical section for the low priority interrupt
PROG code space
CONFIG config word
IDLOCS id-locations
EEDATA EEPROM data
- logical RAM blocks:
ASCRAM Access RAM
BANK0 bank 0
BANK1 bank 1
BANK2 bank 2
BANK3 bank 3
BANK4 bank 4
BANK5 bank 5
..
BANK15 bank 15
- command line options:
- bank naming
-rb0 : BANK0 is the name of the frist RAM bank (default)
-rb1 : BANK1 is the name of the frist RAM bank
- separate interrupt logical section (named ISERVER8/ISERVER18)
-r2 : use name of current module (<module>.lkr)
-r2[=]<file.lkr> : use defined file name
EXAMPLE WITH 2 MODULES
----------------------
This example demonstrates the syntax only.
// ********************************************************
// MODULE1.C
#pragma chip PIC18F452
#include "globdef1.h"
#include "int18xxx.H"
void _highPriorityInt(void);
#pragma origin 0x8
interrupt highPriorityIntServer(void)
{
// W, STATUS and BSR are saved to shadow registers
// handle the interrupt
// 8 code words available including call and RETFIE
_highPriorityInt();
// restore W, STATUS and BSR from shadow registers
#pragma fastMode
}
#pragma origin 0x18
interrupt lowPriorityIntServer(void)
{
// W, STATUS and BSR are saved by the next macro.
int_save_registers
/* NOTE : shadow registers are updated, but will be
overwritten in case of a high-priority interrupt.
Therefore #pragma fastMode should not be used on
low-priority interrupts. */
// save remaining registers on demand (error/warning)
//uns16 sv_FSR0 = FSR0;
//uns16 sv_FSR1 = FSR1;
//uns16 sv_FSR2 = FSR2;
//uns8 sv_PCLATH = PCLATH;
//uns8 sv_PCLATU = PCLATU;
//uns8 sv_PRODL = PRODL;
//uns8 sv_PRODH = PRODH;
//uns24 sv_TBLPTR = TBLPTR;
//uns8 sv_TABLAT = TABLAT;
// handle the interrupt
// ..
// restore registers that are saved
//FSR0 = sv_FSR0;
//FSR1 = sv_FSR1;
//FSR2 = sv_FSR2;
//PCLATH = sv_PCLATH;
//PCLATU = sv_PCLATU;
//PRODL = sv_PRODL;
//PRODH = sv_PRODH;
//TBLPTR = sv_TBLPTR;
//TABLAT = sv_TABLAT;
int_restore_registers // W, STATUS and BSR
}
/* IMPORTANT : GIEH/GIE or GIEL should normally NOT be
set or cleared in the interrupt routine. GIEH/GIEL are
AUTOMATICALLY cleared on interrupt entry by the CPU
and set to 1 on exit (by RETFIE). Setting GIEH/GIEL to
1 inside the interrupt service routine will cause
nested interrupts if an interrupt is pending. Too deep
nesting may crash the program ! */
void _highPriorityInt(void)
{
// save registers on demand
// restore registers on demand
}
bank0 char a;
bit b1, b2;
static char *ppm;
shrBank char sr;
void sub( bank1 char ax)
{
bank1 char i; /* a local variable */
/* generate pulses */
for (i = 0; i <= ax+1; i++) {
out = 1;
nop2();
out = 0;
a ++; // increment global variable
}
}
void main( void)
{
PORTA = 0b0010;
TRISA = 0b0001;
if (TO == 1 && PD == 1 /* power up */) {
clearRAM(); // set all RAM to 0
a = 5;
b1 = 1;
}
ppm = 0;
sr ++;
a = reverse(sr); // call assembly routine
b2 = !b1;
do {
if (in == 1)
break;
sub(a&3);
} while (a < 200);
}
// ********************************************************
// File: globdef1.h
// GLOBAL DEFINITIONS TO BE INCLUDED IN ALL C MODULES
// names assigned to port pins
#pragma bit in @ PORTA.0
#pragma bit out @ PORTA.1
// module1.c
extern bank0 char a;
// module2.asm
extern bank1 char result;
extern char reverse( char W);
; ********************************************************
; MODULE2.ASM
#INCLUDE "P18F452.INC"
BANK1 UDATA
result RES 1 ; result holder
tmp RES 1 ; temporary location
count RES 1 ; loop counter
GLOBAL result
PROG CODE
reverse
GLOBAL reverse
movlb 1
movwf tmp
movlw 8
movwf count
loop rrcf tmp, F, 1
rlcf result, F, 1
decfsz count, F, 1
goto loop
movf result, W, 1
return
END
// ********************************************************
// File: 18F452.LKR
// This example linker script file is for use with the -r2 option.
// However, it is recommended to instead use the -rsc option to let
// the compiler automatically generate and update the whole script!
LIBPATH .
CODEPAGE NAME=vectors START=0x0 END=0x7 PROTECTED
CODEPAGE NAME=intserv8 START=0x8 END=0x17
INCLUDE module1.lkr
// *** File 'module1.lkr' is generated by the compiler when
// *** using option -r2, and defines 'intserv18' and 'page'.
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=0x7F
DATABANK NAME=gpr0 START=0x80 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
ACCESSBANK NAME=accesssfr START=0xF80 END=0xFFF PROTECTED
SECTION NAME=STARTUP ROM=vectors // Reset vector
SECTION NAME=ISERVER8 ROM=intserv8 // High priority interrupt
SECTION NAME=ISERVER18 ROM=intserv18 // Low priority interrupt
SECTION NAME=PROG ROM=page // code space
SECTION NAME=IDLOCS ROM=idlocs // ID locations
SECTION NAME=CONFIG ROM=config // Configuration bits location
SECTION NAME=EEDATA ROM=eedata // EEPROM data
SECTION NAME=ACSRAM RAM=accessram // ACCESS RAM
SECTION NAME=BANK0 RAM=gpr0 // RAM bank 0
SECTION NAME=BANK1 RAM=gpr1 // RAM bank 1
SECTION NAME=BANK2 RAM=gpr2 // RAM bank 2
SECTION NAME=BANK3 RAM=gpr3 // RAM bank 3
SECTION NAME=BANK4 RAM=gpr4 // RAM bank 4
SECTION NAME=BANK5 RAM=gpr5 // RAM bank 5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -