Thanks again, JMGross!

I believe the problem I'm chasing is just my lack of understanding of how a
given microcontroller architecture is defined to msp430-gcc toolchain. Since
last week, I experimented with a procedure to create a trivial C program,
compile it to assembly language, then grab that assembly language, rewrite
it into a simple test application (basically, keeping the basic format
intact, but substituting my own assembly language source code), and send
that along to the assembler/linker/object converter. This produced my trial
assembly program, preceeded by another 64 byte code area beginning at E000
(not based on my source code, so presumably supplied by the linker), and a
set of vectors at FFE0..FFFF, also defined by the linker (not my source
code). From this experiment, I realized that the command line
option -mmcu=msp430x1232, the argument to .arch (or both) are creating
definition for memory layout specific to this device (EEPROM begins at E000,
vectors are at FFE0, RAM is at 0200, and so on), among other things. If I
can customize these parameters prior to assemble-link-converter, I'm pretty
sure this tool will work out satisfactorily for my application. Essentially
the problem I'm working to solve is being able to reconfigure a
remotely-located (physically inaccessible, connected to a PC only by a
serial port) target microcontroller where JTAG is not available, so I am
using a homebrew loader/monitor to accept Intel hex from the serial port and
place it in flash memory; in this case I have two (or more) small
executables in the chip's flash memory at the same time, and I need the
ability to fit these in flash memory space "manually".

I appreciate your time/advice and patience of those on the list with my
pursuit,

Dave

> Message: 6
> Date: Thu, 13 Aug 2009 20:29:11 +0200
> From: "JMGross" <[email protected]>
> Subject: [Mspgcc-users] Message: 6
Date: Thu, 13 Aug 2009 20:29:11 +0200
From: "JMGross" <[email protected]>
Subject: [Mspgcc-users] Re: Unexpected output from msp430-gcc
assembler (simple problem?)
To: "MSPGCC mailing list," <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="ISO-8859-1"


Hi!

Yes and no, I guess there are two things mixe dup here.

First, U0TXBUF, if defined as a constant, should be assembled directly. It
isn't, so for some reason it is not interpreted as a predefined constant but
as a yet unknown symbol.

Unknown sybols are treated as zero values and added to a 'relocation table'
which is part of the object file. It is the job of a linkter to pick all
symbols in all object files of a project and put their addresses into the
'zero'
placeholders in the other object files, as referenced in the relocation
table.
It is sort of a 'hey linker, if you happen to find out where this "U0TXBUF"
is, pleas put its address at location xxxx in this object file' message.

Depending on the assembler implementation (I don't know the mspgcc assembler
well) it is possible that any forward reference (a symbol that refers to a
location later in the source file) can be treated as unknown or
external reference annd needs a linker to be resolved. (so-called
one-pass-assembler). Or the assembler fails to determine the final address
of a symbol because it refers to a location with a yet unknown address (e.g.
a ocde with its own .org or .segment directive). Since the destination finds
its final place at linkign time, it's also up to the linker to propagate its
final address to every location where it is used. The assembler
generates a relocation table entry and leaves the binary value zero.

As long as you do not have unknown symbols (e.g. if you only have one single
source file, a contiguous block of code and no libraries), you don't really
need the linker. There shouldn't be any unresolved external
symbols.

But apparently there are. The question is: why?
Somehow, U0TXBUF is unknown to the assembler. This might have several
reasons: Either the preprocessor isn't run, so the token 'U0TXBUF' isn't
replaced by its defined value, or the include file with the definition
isn't included at all.

With the .arch directive you tell the assembler which processor you use (and
therefore which binary values will result from the mnemonics you write). But
it does not include any definitions.
This are two completely separate things. The processor type must be known
because different processors might have different optimisations, including
errata, microcode bugs etc. of wich the assembler needs to take
care and perhaps create workarounds. It doe snot tello the assembler about
functional specifics like I/O modules and ports, amount and location of RAM
and FLASH etc. Just about the microprocessor core itself. The
programmer needs to take care of this - or use a properly configured linker.
The port definitions, however, are just equations (like the .eq directive)
and inlcuding the proper file is not necessary for the assembler. It just
makes things easier for the programmer. So it is NOT done automatically -
and the file(s) can have any name.

When using a linker, specifying the used processor is necessary to tell the
linker which processor specific configuration table to use. This includes
the information, where on the choosen processor the ram starts and
ends and the flash starts and ends.

In your source file, you jsut tell the assembler to put the following code
explixitely at 0xe080. So the result is a 64K block of binary data with the
assembled code at 0xe080.
When using a linker, you'd rather tell the assembler to put the code into an
arbitrary 'segment' with the name "text". The linker then looks into the
configuration table and finds out that "text" is from 0xe000 to 0xff80
and generates a proper binary with all code assigned to the text segment
placed into this area.
I'm not sure about the '.text' directive just after the '.org'. It could be
a shortcut for settign the segment, but I must admit that this confuses me a
little, as this would override the '.org' address and put the code
somewhere in the text segment, which absolute address is not known. This
would explain why the reference to the later used 'message' is not
immediately resolved - it is unknown at which absolute address
'message' will be after all is placed into the yet unspecified text segment.

So ensure that the include files are really included. I just double-checke
the inlude files and found that U0TXBUF is equal to U0TXBUF_ when in
assembly mode, so you can use the labels without underscore.
Also ensure that the assembler is preceded with a precompiler run to resolve
all these labels (but I guess, mspgcc will do so automatically).
The #include precompiler directive in you code snipped is empty. It does not
generate an error, so I guess the precompiler is run, but since it has no
filename appended, it just includes nothing.

my makefiles contain the following line for doing assembly source to object
files:

msp430-gcc -x assembler-with-cpp -c -mmcu=msp430x1232 -I. f.s -o f.o

next step is linking through gcc

msp430-gcc -mmcu=msp430x1232 f.o -o f.elf

here, instead of just 'f.o', any number of files can be given. They will be
all put together., all code (except code with a fixed .org instead of a
destination segment) chained up in the appropriate memory areas, all
references between these files solved and replaced itn the object data and
so on.

I automatically create a full disassembler listing of the resulting file
with

msp430-objdump -DS f.elf > f.lst

final step is the conversion of the elf file in a HEX file for flashing:

msp430-objcopy -O ihex f.elf f.hex

you can replace the 'ihex' by 'binary' if you want a binary output file (see
msp430-objdump --help)

I'm not sure that the above commands are 100% correct as I have them
'manually' extracted from my standard makefile (which is a bit mroe complex
and uses lots of text replacements for path and names and such.
But it looks right ;)

Also, I'm not an assembly programmer at all (well, I did it once, for the
C64/6502 processor and later for GEOS on the PC, but this was espire, an
object-oriented assembler, and everything was different). So all what I
have written here might differ from the 'final truth' a bit. So everyone is
inveited to correct me where I missed the point.
But I guess it will give you a good start understanding what you're dealing
with.


JMGross


> To: "MSPGCC mailing list," <[email protected]>
> Message-ID: <[email protected]>
> Content-Type: text/plain; charset="ISO-8859-1"
>
>
> Hi!
>
> Yes and no, I guess there are two things mixe dup here.
>
> First, U0TXBUF, if defined as a constant, should be assembled directly. It
isn't, so for some reason it is not interpreted as a predefined constant but
as a yet unknown symbol.
>
> Unknown sybols are treated as zero values and added to a 'relocation
table' which is part of the object file. It is the job of a linkter to pick
all symbols in all object files of a project and put their addresses into
the 'zero'
> placeholders in the other object files, as referenced in the relocation
table.
> It is sort of a 'hey linker, if you happen to find out where this
"U0TXBUF" is, pleas put its address at location xxxx in this object file'
message.
>
> Depending on the assembler implementation (I don't know the mspgcc
assembler well) it is possible that any forward reference (a symbol that
refers to a location later in the source file) can be treated as unknown or
> external reference annd needs a linker to be resolved. (so-called
one-pass-assembler). Or the assembler fails to determine the final address
of a symbol because it refers to a location with a yet unknown address (e.g.
> a ocde with its own .org or .segment directive). Since the destination
finds its final place at linkign time, it's also up to the linker to
propagate its final address to every location where it is used. The
assembler
> generates a relocation table entry and leaves the binary value zero.
>
> As long as you do not have unknown symbols (e.g. if you only have one
single source file, a contiguous block of code and no libraries), you don't
really need the linker. There shouldn't be any unresolved external
> symbols.
>
> But apparently there are. The question is: why?
> Somehow, U0TXBUF is unknown to the assembler. This might have several
reasons: Either the preprocessor isn't run, so the token 'U0TXBUF' isn't
replaced by its defined value, or the include file with the definition
> isn't included at all.
>
> With the .arch directive you tell the assembler which processor you use
(and therefore which binary values will result from the mnemonics you
write). But it does not include any definitions.
> This are two completely separate things. The processor type must be known
because different processors might have different optimisations, including
errata, microcode bugs etc. of wich the assembler needs to take
> care and perhaps create workarounds. It doe snot tello the assembler about
functional specifics like I/O modules and ports, amount and location of RAM
and FLASH etc. Just about the microprocessor core itself. The
> programmer needs to take care of this - or use a properly configured
linker.
> The port definitions, however, are just equations (like the .eq directive)
and inlcuding the proper file is not necessary for the assembler. It just
makes things easier for the programmer. So it is NOT done automatically -
> and the file(s) can have any name.
>
> When using a linker, specifying the used processor is necessary to tell
the linker which processor specific configuration table to use. This
includes the information, where on the choosen processor the ram starts and
> ends and the flash starts and ends.
>
> In your source file, you jsut tell the assembler to put the following code
explixitely at 0xe080. So the result is a 64K block of binary data with the
assembled code at 0xe080.
> When using a linker, you'd rather tell the assembler to put the code into
an arbitrary 'segment' with the name "text". The linker then looks into the
configuration table and finds out that "text" is from 0xe000 to 0xff80
> and generates a proper binary with all code assigned to the text segment
placed into this area.
> I'm not sure about the '.text' directive just after the '.org'. It could
be a shortcut for settign the segment, but I must admit that this confuses
me a little, as this would override the '.org' address and put the code
> somewhere in the text segment, which absolute address is not known. This
would explain why the reference to the later used 'message' is not
immediately resolved - it is unknown at which absolute address
> 'message' will be after all is placed into the yet unspecified text
segment.
>
> So ensure that the include files are really included. I just double-checke
the inlude files and found that U0TXBUF is equal to U0TXBUF_ when in
assembly mode, so you can use the labels without underscore.
> Also ensure that the assembler is preceded with a precompiler run to
resolve all these labels (but I guess, mspgcc will do so automatically).
> The #include precompiler directive in you code snipped is empty. It does
not generate an error, so I guess the precompiler is run, but since it has
no filename appended, it just includes nothing.
>
> my makefiles contain the following line for doing assembly source to
object files:
>
> msp430-gcc -x assembler-with-cpp -c -mmcu=msp430x1232 -I. f.s -o f.o
>
> next step is linking through gcc
>
> msp430-gcc -mmcu=msp430x1232 f.o -o f.elf
>
> here, instead of just 'f.o', any number of files can be given. They will
be all put together., all code (except code with a fixed .org instead of a
destination segment) chained up in the appropriate memory areas, all
> references between these files solved and replaced itn the object data and
so on.
>
> I automatically create a full disassembler listing of the resulting file
with
>
> msp430-objdump -DS f.elf > f.lst
>
> final step is the conversion of the elf file in a HEX file for flashing:
>
> msp430-objcopy -O ihex f.elf f.hex
>
> you can replace the 'ihex' by 'binary' if you want a binary output file
(see msp430-objdump --help)
>
> I'm not sure that the above commands are 100% correct as I have them
'manually' extracted from my standard makefile (which is a bit mroe complex
and uses lots of text replacements for path and names and such.
> But it looks right ;)
>
> Also, I'm not an assembly programmer at all (well, I did it once, for the
C64/6502 processor and later for GEOS on the PC, but this was espire, an
object-oriented assembler, and everything was different). So all what I
> have written here might differ from the 'final truth' a bit. So everyone
is inveited to correct me where I missed the point.
> But I guess it will give you a good start understanding what you're
dealing with.
>
>
> JMGross
>
> ----- Urspr?ngliche Nachricht -----
> Von: david feldman
> An: [email protected]
> Gesendet am: 13 Aug 2009 00:57:29
> Betreff: [Mspgcc-users] Re: Unexpected output from msp430-gcc assembler
(simple problem?)
>
>
> Hello JMGross, thank you for the reply.
>
> I now think the problem is that the assembling/linking process is somehow
incomplete. In the example below, I'm just referring to a symbol which is in
the same source file:
>
> .arch msp430x1232
> #include
> .org 0xE080
> .text
> main: mov #message, R14
>         jmp  main
> message: .ascii "hello world"
> .byte 0
> .end
>
> The instruction "mov #message, R14" is getting assembled as "3E 40 00 00"
>
> In a nutshell, the assembler is rendering "mov #message, R14" as "mov #0,
R14".
>
> I suspect this is closer to the root cause of my problem.
>
> My source code is the file "f.s" and it is being compiled with the command
"msp430-gcc -c f.s -o f.out
> ", then converted to intel hex using "msp430-objcopy -O ihex f.out f.hex"
>
> The msp430x12x2.h file is located in /usr/msp430/include, where it
appeared when I first installed msp430-gcc with apt-get (on a Ubuntu 9.04
system.)
>
> There are no error messages from the command line launch of msp430-gcc.
>
> Is there a linking step I am missing? Perhaps there is a symbol table
containing the address of message: in the above example, or &U0TXBUF in my
initial example, which is not getting applied to the
> object code?
>
> Thanks again for the patience of those on the reflector!
>
> Dave
>
> >Hi!
>
>
>
>
>
> ------------------------------
>
> --------------------------------------------------------------------------
----


Reply via email to