I'm tryin to build assembly project with MPASM/MPLINK for PIC16F628A. Microchip advice that it's better to stay on bank 0 and switch whenever you want different bank, and then get back to bank 0 (to minimise bank switching). That's why I want to put most GPR file registers in bank 0. Also most used SFR registers are in bank0. However the linker is trying to fit data starting from smallest databank which is GPR in bank 2. There is no way to tell the linker to start filling from bank 0, except make bank 2 protected in linker script. There should be better way...
UPDATE: For those who didn't understand the question (or didn't want): "How to reserve memory in bank 0 for PIC16F628A addresses from 0x20 to 0x6F in relocatable code mode in more than one file."
What I tried:
1.
file1.asm
FirstBank udata_ovr 0x20
register1 res 1
register2 res 1
file2.asm
FirstBank udata_ovr 0x20
register3 res 1
register4 res 1
Of course that doesn't do it because register1 overlaps with register3. I need register3 to be placed on unused bank.
2.
file1.asm
FirstBank udata
register1 res 1
register2 res 1
file2.asm
FirstBank udata
register3 res 1
register4 res 1
This will put all these registers in bank2
3.
file1.asm
FirstBank udata 0x20
register1 res 1
register2 res 1
file2.asm
FirstBank udata 0x20
register3 res 1
register4 res 1
results linker error
update 2: The reason I want to fit my variables in bank0 is because most commonly used SPF registers are in bank 0 and I don't need to switch between banks when I use them (which means less code). And no, I shared memory (70-7F) is not enough to fit all variables I need. It wouldn't be optimal to switch banks when I can fit all variables that I use in 99% of the code in bank 0.
Now it should be clear. If anyone that's discussing my feelings actually wants to help I'll still appreciate it.
P.S. I guess I missed the very important keyword "relocatable mode", so I apologize about that. But please keep your comments/answer on topic. If something is not clear ask and I'll try to change question to be more clear. Thanks to all that actually want to help.
Answer
This can be done using directives in both the assembler source and in the linker script. When you use the udata
primitive, the label becomes the section name.
Consider the following example source files similar to what you have provided:
file1.asm
SomeSection udata
register1 res 1
register2 res 1
SomeOtherSection udata
register5 res 1
end
file2.asm
SomeSection udata
register3 res 1
register4 res 1
end
In file1.asm, there will be two output sections generated by the assembler named SomeSection
and SomeOtherSection
. You can verify this by turning on the output map file and looking at the listed section names.
The next step is to tell the link where those sections should be placed in memory, this requires a change to the default linker script.
Locate and copy the default linker script for your device (16f627a_g.lnk
) to your project directory and add it in the Linker Script
project settings.
At the bottom of the linker script you'll notice a set of SECTION
specifiers like this:
SECTION NAME=PROG ROM=page // ROM code space
SECTION NAME=IDLOCS ROM=.idlocs // ID locations
SECTION NAME=DEVICEID ROM=.device_id // Device ID
SECTION NAME=DEEPROM ROM=eedata // Data EEPROM
Add your own section names here and the destination RAM bank.
SECTION NAME=SomeSection RAM=gpr0
SECTION NAME=SomeOtherSection RAM=gpr2
You can verify in the map output file that your variables have been placed in the correct location. From the example above, registers1-4 go into gpr0, register5 goes into gpr2.
No comments:
Post a Comment