Subject:
gplink throws away configuration (PIC18F458)
From:
Ian Jackson ####@####.####
Date:
16 Dec 2005 12:57:30 +0000
Message-Id: <17314.47536.168248.364456@davenant.relativity.greenend.org.uk>
I've been using gputils on Debian with a PIC18F458 (and odyssey as the
programmer). I'm currently using gputils 0.13.3 (actually, Debian's
0.13.3-1). I'm having some problems with gplink leaving out the
configuration section from my output .hex files, which confused me for
a bit before I realised what was happening.
As you can see from the complete transcript below:
gpasm -p18f458 -c test.asm
gpasm -p18f458 -c config.asm
gplink test.o config.o
produces an a.hex file which doesn't conttain the configuration.
gpvo config.o suggests that the config.o is right. Using gpasm in
absolute mode like this works:
gpasm -p18f458 test.asm
gpasm -p18f458 config.asm
./merge-hex test.hex config.hex >merged.hex
merge-hex is a small Perl script I wrote which effectively
concatenates hex files (but checking for overlaps). I've attached
that too.
-davenant:d> cat test.asm
org 0
movlw 0x14
end
-davenant:d> cat config.asm
; -*- fundamental -*-
include /usr/share/gputils/header/p18f458.inc
; __config _CONFIG1L, 0xff
__config _CONFIG1H, _OSCS_OFF_1H & _ECIO_OSC_1H
__config _CONFIG2L, _BOR_ON_2L & _PWRT_ON_2L & _BORV_45_2L
__config _CONFIG2H, _WDT_OFF_2H
; __config _CONFIG3L, 0xff
; __config _CONFIG3H, 0xff
__config _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_ON_4L
; __config _CONFIG4H, 0xff
__config _CONFIG5L, 0xff
__config _CONFIG5H, 0xff
__config _CONFIG6L, 0xff
__config _CONFIG6H, 0xff
__config _CONFIG7L, 0xff
__config _CONFIG7H, 0xff
end
-davenant:d> gpasm -p18f458 -c test.asm
-davenant:d> gpasm -p18f458 -c config.asm
-davenant:d> gpvo config.o
COFF File and Optional Headers
Processor Type 18f458
Time Stamp Fri Dec 16 12:43:52 2005
Number of Sections 1
Number of Symbols 11
Characteristics 0
Section Header
Name .config
Address 0x300000
Size of Section 0
Number of Relocations 0
Number of Line Numbers 0
Flags 0x1020
Executable code.
Absolute.
Symbol Table
Name Section Value Type Class NumAux
.file DEBUG 0 0 103 1
file = config.asm
line included = 0
.file DEBUG 0 0 103 1
file = /usr/share/gputils/header/p18f458.inc
line included = 3
.list DEBUG 0x1 0 108 0
.nolist DEBUG 0x3 0 108 0
.list DEBUG 0x6b3 0 108 0
.eof DEBUG 0 0 107 0
.config .config 0x300000 0 109 1
length = 1075017816
number of relocations = 11832
number of line numbers = 28265
.eof DEBUG 0 0 107 0
-davenant:d> gplink test.o config.o
message: using default linker script "/usr/share/gputils/lkr/18f458.lkr"
-davenant:d> cat a.hex
:020000040000FA
:02000000140EDC
:00000001FF
-davenant:d> gpdasm -p18f458 a.hex
000000: 0e14 movlw 0x14
-davenant:d> objdump -s -b ihex a.hex
a.hex: file format ihex
Contents of section .sec1:
0000 140e ..
-davenant:d> gpasm -p18f458 test.asm
-davenant:d> cat test.hex
:020000040000FA
:02000000140EDC
:00000001FF
-davenant:d> gpdasm -p18f458 test.hex
000000: 0e14 movlw 0x14
-davenant:d> objdump -s -b ihex test.hex
test.hex: file format ihex
Contents of section .sec1:
0000 140e ..
-davenant:d> gpasm -p18f458 config.asm
-davenant:d> cat config.hex
:020000040000FA
:020000040030CA
:04000000FFFDF2FE10
:08000600FBFFFFFFFFFFFFFFFE
:00000001FF
-davenant:d> gpdasm -p18f458 config.hex
60000000: fdff dw 0xfdff ;unknown opcode
60000002: fef2 dw 0xfef2 ;unknown opcode
60000006: fffb dw 0xfffb ;unknown opcode
60000008: ffff dw 0xffff ;unknown opcode
6000000a: ffff dw 0xffff ;unknown opcode
6000000c: ffff dw 0xffff ;unknown opcode
-davenant:d> objdump -s -b ihex config.hex
config.hex: file format ihex
Contents of section .sec1:
300000 fffdf2fe ....
Contents of section .sec2:
300006 fbffffff ffffffff ........
-davenant:d> ./merge-hex test.hex config.hex >merged.hex
0-1 300000-300003 300006-30000d
-davenant:d> cat merged.hex
:020000040000FA
:02000000140EDC
:020000040000FA
:020000040030CA
:04000000FFFDF2FE10
:08000600FBFFFFFFFFFFFFFFFE
:020000040000FA
:00000001FF
-davenant:d> gpdasm -p18f458 merged.hex
000000: 0e14 movlw 0x14
60000000: fdff dw 0xfdff ;unknown opcode
60000002: fef2 dw 0xfef2 ;unknown opcode
60000006: fffb dw 0xfffb ;unknown opcode
60000008: ffff dw 0xffff ;unknown opcode
6000000a: ffff dw 0xffff ;unknown opcode
6000000c: ffff dw 0xffff ;unknown opcode
-davenant:d> objdump -s -b ihex merged.hex
merged.hex: file format ihex
Contents of section .sec1:
0000 140e ..
Contents of section .sec2:
300000 fffdf2fe ....
Contents of section .sec3:
300006 fbffffff ffffffff ........
-davenant:d>
#!/usr/bin/perl -w
# See http://www.precma.it/download/intelhex.pdf
#
# Written by Ian Jackson in November/December 2005.
# I hereby waive my copyright in this file. - Ian Jackson 16.12.2005.
# $Id: merge-hex,v 1.4 2005/12/16 12:51:32 ian Exp $
use strict qw(refs vars);
our ($lba,$sba,$loc,$eof,%once);
$lba=$sba=0;
sub once {
my ($r) = @_;
my ($o);
$o= \$once{$_[0]};
if (!defined $$o) { $$o= $loc; return; }
die sprintf("%s: %s: clash at 0x%x (1st)\n".
"%s: %s: clash at 0x%x (2nd)\n",
$0, $$o, $r, $0, $loc, $r);
}
sub bad ($) { my ($m)=@_; die "$0: $loc: $m\n"; }
my ($drlo,$dri,$orgline,$la);
while (<>) {
$orgline= $_;
$loc= "$ARGV:$.";
chomp; # General Record Format, p5
s/^\:// or bad('no colon');
$_= lc $_;
m/[^0-9a-f]/ and bad("bad char ".ord($&));
length() & 1 and bad('odd length');
s/..$//; # chop checksum (we don't check this)
s/^..//; # chop reclen (we don't check this)
if (s/^000001//) { # End of File, p11
$eof= $orgline;
if ($lba) { $orgline= ":020000040000FA\n"; $lba=0; }
elsif ($sba) { $orgline= ":020000020000FC\n"; $sba=0; }
else { next; }
} elsif (s/^000004(....)$//) { $lba= hex($1)<<16; } # Ext'd Linear Addr, p6
elsif (s/^000002(....)$//) { $sba= hex($1)<<4; } # Ext'd Seg. Addr., p7
elsif (s/^(....)00//) { # Data Record, p8
$drlo= hex $1;
for ($dri=0; s/^..//; $dri++) {
bad('both LBA and SBA') if $lba && $sba;
if ($lba) { $la= ($lba+$drlo+$dri) & 0x0ffffffff; }
elsif ($sba) { $la= $sba + (($drlo+$dri) & 0xffff); }
else { $la= $drlo+$dri; }
#print STDERR ">$lba|$sba|$drlo|$dri|$la|$_<\n";
once($la);
}
}
elsif (s/^000005//) { once('start'); } # Start Linear Address, p9
elsif (s/^000003//) { once('start'); } # Start Segment Address, p10
else {
bad('unknown record or bad record');
}
print $orgline or die $!;
}
our ($lx,$ld);
$lx= 0;
$ld= '';
sub pf {
my ($f) = shift @_;
my ($s) = sprintf $f, @_;
if ($s =~ m/^\s/ && length($ld.$s) > 70) {
print STDERR $ld,"\n" or die $!; $ld= " ";
}
$ld.= $s;
}
sub pf_end () {
print STDERR $ld,"\n" or die $!;
}
my ($ca,$a1);
undef $la;
foreach $ca (sort { $a <=> $b } keys %once) {
next if defined($la) && $ca == ++$la;
defined($la) and
--$la != $a1 and
pf("-%x", $la);
pf(" %x", $ca);
$la=$a1=$ca;
}
if (!defined($la)) {
pf(" empty");
} elsif ($la != $a1) {
pf("-%x", $la);
}
pf_end();
die "$0: no input files or missing EOF markers\n" unless defined $eof;
print $eof or die $!;