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! > > > > > > ------------------------------ > > -------------------------------------------------------------------------- ----
