Forum: Compiler & IDEs MSP430: Assembler mit GNU-Toolchain


von uvok (Gast)


Lesenswert?

Hallo,

ich möchte ein kleines Programm für den MSP430G2231 in Assembler 
schreiben. Dazu hab ich hier in den Foren schon mal etwas gesucht und 
folgenden Quelltext zusammengebaut:
1
#include <msp430.h>
2
            .section    .text
3
RESET:      mov.w   #0x0280,R1              ; Initialize stackpointer - End of RAM
4
StopWDT:    mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop WDT
5
SetupP1:    bis.b   #BIT0,&P1DIR            ; P1.0  output
6
                                            ;
7
8
Mainloop:   xor.b   #BIT0,&P1OUT            ; Toggle P1.0
9
10
; Wait ~1s - 1000000 cycles
11
Wait:       mov.w   #050000,R15             ; Delay to R15
12
13
L1:         mov.w   #20, R14
14
L2:         dec.w   R14
15
            jnz     L2
16
17
            dec.w   R15                     ; Decrement R15
18
            jnz     L1                      ; Delay over?
19
20
            jmp     Mainloop                ; Again
21
22
no_int:     reti                                            ;
23
;--------------------------------------------------------------------
24
;           Interrupt Vectors Used
25
;--------------------------------------------------------------------
26
            .section    .vectors
27
            ;Adresse wird einfach angegeben
28
            .word no_int                     ; 0xFFE0
29
            .word no_int                     ; 0xFFE2
30
            .word no_int                     ; 0xFFE4
31
            .word no_int                     ; 0xFFE6
32
            .word no_int                     ; 0xFFE8
33
            .word no_int                     ; 0xFFEa
34
            .word no_int                     ; 0xFFEc
35
            .word no_int                     ; 0xFFEe
36
            .word no_int                     ; 0xFFF0
37
            .word no_int                     ; 0xFFF2
38
            .word no_int                     ; 0xFFF4
39
            .word no_int                     ; 0xFFF6
40
            .word no_int                     ; 0xFFF8
41
            .word no_int                     ; 0xFFFA
42
            .word no_int                     ; 0xFFFC
43
            .word RESET                      ; 0xFFFE (Reset)


Kpmpilieren wollte ich das ganze eigentlich mit
1
msp430-gcc -x assembler-with-cpp -mmcu=msp430g2231 -o ledasm.out  led.s

Leider erscheint dann die Fehlermeldung
1
d:/mspgcc/bin/../lib/gcc/msp430/4.6.1/../../../../msp430/bin/ld.exe: asm.o section `.vectors' will not fit in region `vectors'
2
d:/mspgcc/bin/../lib/gcc/msp430/4.6.1/../../../../msp430/bin/ld.exe: region `vectors' overflowed by 32 bytes
3
collect2: ld returned 1 exit status

Demnach wäre die erlaubte Größe der Section .vectors ja 0 Byte groß. Ein 
Disassembly des gleichen Programms in C hat Interruptvektortabelle 
allerdings.

Das Kompilieren und Linken mit folgendem Aufrug funktioniert zwar:
1
msp430-gcc -c -x assembler-with-cpp -mmcu=msp430g2231 -o asm.o led.s 
2
msp430-ld asm.o -L mspgcc\msp430\lib\ldscripts\msp430g2231

Ein msp430-objdump -D zeigt mir auch an, dass die Section .vectors da 
ist.
Aber wenn ich die gelinkte Datei mit mspdebug brennen will, wird nur die 
Section .text gebrannt, die Section .vectors nicht.
Die Vektortabelle enthält damit nur 0xffff, das Programm läuft damit 
nicht los...

Hat jemand einen Tip für mich, wie ich das Programm "richtig" 
kompilieren kann? Ich finde dazu keine Lösung...

Danke schonmal.

von Krapao (Gast)


Lesenswert?


von Krapao (Gast)


Lesenswert?

Wie schreibst du welche Datei mit mspdebug in den µC?

MSPDEBUG manual
http://mspdebug.sourceforge.net/manual.html

von uvok (Gast)


Lesenswert?

@Krapao

Das Linkerscript memory.x sieht so aus:
1
MEMORY {
2
  sfr              : ORIGIN = 0x0000, LENGTH = 0x0010 /* END=0x0010, size 16 */
3
  peripheral_8bit  : ORIGIN = 0x0010, LENGTH = 0x00f0 /* END=0x0100, size 240 */
4
  peripheral_16bit : ORIGIN = 0x0100, LENGTH = 0x0100 /* END=0x0200, size 256 */
5
  ram (wx)         : ORIGIN = 0x0200, LENGTH = 0x0080 /* END=0x0280, size 128 */
6
  infomem          : ORIGIN = 0x1000, LENGTH = 0x0100 /* END=0x1100, size 256 as 4 64-byte segments */
7
  infod            : ORIGIN = 0x1000, LENGTH = 0x0040 /* END=0x1040, size 64 */
8
  infoc            : ORIGIN = 0x1040, LENGTH = 0x0040 /* END=0x1080, size 64 */
9
  infob            : ORIGIN = 0x1080, LENGTH = 0x0040 /* END=0x10c0, size 64 */
10
  infoa            : ORIGIN = 0x10c0, LENGTH = 0x0040 /* END=0x1100, size 64 */
11
  rom (rx)         : ORIGIN = 0xf800, LENGTH = 0x07e0 /* END=0xffe0, size 2016 */
12
  vectors          : ORIGIN = 0xffe0, LENGTH = 0x0020 /* END=0x10000, size 32 as 16 2-byte segments */
13
  /* Remaining banks are absent */
14
  bsl              : ORIGIN = 0x0000, LENGTH = 0x0000
15
  far_rom          : ORIGIN = 0x00000000, LENGTH = 0x00000000
16
}
17
REGION_ALIAS("REGION_TEXT", rom);
18
REGION_ALIAS("REGION_DATA", ram);
19
REGION_ALIAS("REGION_FAR_ROM", far_rom);
20
PROVIDE (__info_segment_size = 0x40);
21
PROVIDE (__infod = 0x1000);
22
PROVIDE (__infoc = 0x1040);
23
PROVIDE (__infob = 0x1080);
24
PROVIDE (__infoa = 0x10c0);

Mit mspdebug schreib ich die a.out, die von msp430-ld erzeugt wird:
1
> mspdebug rf2500
2
 (mspdebug) prog a.out
3
 Erasing...
4
 Programming...
5
 Writing   38 bytes to f800 [section: .text]...

Das Disassembly (msp430-objsdump) sieht übrigens so aus
1
D:\> msp430-objdump -D a.out
2
3
a.out:     file format elf32-msp430
4
5
6
Disassembly of section .text:
7
8
0000f800 <__ctors_end>:
9
    f800:       31 40 80 02     mov     #640,   r1      ;#0x0280
10
11
0000f804 <StopWDT>:
12
    f804:       b2 40 80 5a     mov     #23168, &0x0120 ;#0x5a80
13
    f808:       20 01
14
15
0000f80a <SetupP1>:
16
    f80a:       d2 d3 22 00     bis.b   #1,     &0x0022 ;r3 As==01
17
18
0000f80e <Mainloop>:
19
    f80e:       d2 e3 21 00     xor.b   #1,     &0x0021 ;r3 As==01
20
21
0000f812 <Wait>:
22
    f812:       3f 40 00 50     mov     #20480, r15     ;#0x5000
23
24
0000f816 <L1>:
25
    f816:       3e 40 14 00     mov     #20,    r14     ;#0x0014
26
27
0000f81a <L2>:
28
    f81a:       1e 83           dec     r14
29
    f81c:       fe 23           jnz     $-2             ;abs 0xf81a
30
    f81e:       1f 83           dec     r15
31
    f820:       fa 23           jnz     $-10            ;abs 0xf816
32
    f822:       f5 3f           jmp     $-20            ;abs 0xf80e
33
34
0000f824 <no_int>:
35
    f824:       00 13           reti
36
37
Disassembly of section .vectors:
38
39
0000ffe0 <_efartext+0xffe0>:
40
    ffe0:       24 f8           and     @r8,    r4
41
    ffe2:       24 f8           and     @r8,    r4
42
    ffe4:       24 f8           and     @r8,    r4
43
    ffe6:       24 f8           and     @r8,    r4
44
    ffe8:       24 f8           and     @r8,    r4
45
    ffea:       24 f8           and     @r8,    r4
46
    ffec:       24 f8           and     @r8,    r4
47
    ffee:       24 f8           and     @r8,    r4
48
    fff0:       24 f8           and     @r8,    r4
49
    fff2:       24 f8           and     @r8,    r4
50
    fff4:       24 f8           and     @r8,    r4
51
    fff6:       24 f8           and     @r8,    r4
52
    fff8:       24 f8           and     @r8,    r4
53
    fffa:       24 f8           and     @r8,    r4
54
    fffc:       24 f8           and     @r8,    r4
55
    fffe:       00 f8           and     r8,     r0

von Krapao (Gast)


Lesenswert?

Du hast einen Konflikt mit dem C-Startup File, welches sich selbst um 
die .vectors kümmert.

Mein Toolchain-Aufruf mit -nostartfiles verhindert, dass das C-Startup 
zu dem ASM-File gelinkt wird:
1
set PATH=bin;$PATH
2
msp430-gcc -v -nostartfiles -x assembler-with-cpp -mmcu=msp430g2231 -o led.out led.S
3
msp430-objdump -D led.out > led.txt

-v soll anzeigen, was gcc wie aufruft.

.S (S groß) ist für ASM-Sourcen besser, .s (s klein) sind von GCC 
erzeugte, temporäre ASM-Files, die ein make clean löscht!

Und das Batchfile (objdump) erzeugt als Ausgabe (led.txt)
(Der falsche Labelname __ctors_end statt RESET ist vielleicht ein Bug, 
aber nicht relevant für die Funktion)
1
led.out:     file format elf32-msp430
2
Disassembly of section .text:
3
4
0000f800 <__ctors_end>:
5
    f800:  31 40 80 02   mov  #640,  r1  ;#0x0280
6
7
0000f804 <StopWDT>:
8
    f804:  b2 40 80 5a   mov  #23168,  &0x0120  ;#0x5a80
9
    f808:  20 01 
10
11
0000f80a <SetupP1>:
12
    f80a:  d2 d3 22 00   bis.b  #1,  &0x0022  ;r3 As==01
13
14
0000f80e <Mainloop>:
15
    f80e:  d2 e3 21 00   xor.b  #1,  &0x0021  ;r3 As==01
16
17
0000f812 <Wait>:
18
    f812:  3f 40 00 50   mov  #20480,  r15  ;#0x5000
19
20
0000f816 <L1>:
21
    f816:  3e 40 14 00   mov  #20,  r14  ;#0x0014
22
23
0000f81a <L2>:
24
    f81a:  1e 83         dec  r14    
25
    f81c:  fe 23         jnz  $-2        ;abs 0xf81a
26
    f81e:  1f 83         dec  r15    
27
    f820:  fa 23         jnz  $-10       ;abs 0xf816
28
    f822:  f5 3f         jmp  $-20       ;abs 0xf80e
29
30
0000f824 <no_int>:
31
    f824:  00 13         reti      
32
33
Disassembly of section .vectors:
34
35
0000ffe0 <_efartext+0xffe0>:
36
    ffe0:  24 f8         and  @r8,  r4  
37
    ffe2:  24 f8         and  @r8,  r4  
38
    ffe4:  24 f8         and  @r8,  r4  
39
    ffe6:  24 f8         and  @r8,  r4  
40
    ffe8:  24 f8         and  @r8,  r4  
41
    ffea:  24 f8         and  @r8,  r4  
42
    ffec:  24 f8         and  @r8,  r4  
43
    ffee:  24 f8         and  @r8,  r4  
44
    fff0:  24 f8         and  @r8,  r4  
45
    fff2:  24 f8         and  @r8,  r4  
46
    fff4:  24 f8         and  @r8,  r4  
47
    fff6:  24 f8         and  @r8,  r4  
48
    fff8:  24 f8         and  @r8,  r4  
49
    fffa:  24 f8         and  @r8,  r4  
50
    fffc:  24 f8         and  @r8,  r4  
51
    fffe:  00 f8         and  r8,  r0

von Krapao (Gast)


Lesenswert?

Das 1. Problem hast du ja selbst durch den expliziten Aufruf des Linkers 
in den Griff bekommen. Wie gesagt, das geht auch durch einen Aufruf des 
gcc mit besagter Option.

Zu dem 2. Problem: Wie das Programm vollständig in den MSP430 
schaffen...

> Mit mspdebug schreib ich die a.out, die von msp430-ld erzeugt wird:
>
>> mspdebug rf2500
> (mspdebug) prog a.out
> Erasing...
> Programming...
> Writing   38 bytes to f800 [section: .text]...

Hier ist für mich klar mspdebug der Übeltäter, der die vorhandene 
.vectors Section ignoriert. Eine Verwechselung a.out mit einer alten 
Version ohne .vectors schliesse ich mal aus. Hast du ein anderes 
Brenntool? Gibt es ggf. eine modernere Version des mspdebug als deine?

von uvok (Gast)


Lesenswert?

@Krapao

Danke für den Tip mit dem -nostartfiles, das Programm kann jetzt in 
einem Schritt kompiliert und gelinkt werden.

Mir ist zumindest kein anderes Brenntool bekannt (für Texas Instruments 
Launchpad). 0.18 ist auch die aktuelle Version, ich werd aber mal die 
Entwicklungsversion aus dem git probieren...

von Krapao (Gast)


Lesenswert?

Vielleicht bringt es was, das Problem im MSPDEBUG-Support Forum 
(http://develissimo.com/forum/36/) anzusprechen.

Ich werde bei Gelegenheit auch mal versuchen, das auf meiner Hardware 
nachzustellen.

von uvok (Gast)


Lesenswert?

Danke für den Link zum Forum, habe schon eine Anlaufstelle für 
mspdebug-Support gesucht.

Ich habe dort ein Thema zum Problem eröffnet:
http://develissimo.com/forum/topic/83982

Inzwischen hat jemand herausgefunden, dass der Section .vectors das 
LOAD-Flag fehlt.
http://develissimo.com/forum/post/179346/

Das war schon mal ein wichtiger Hinweis, nun ist die Frage, wie ich die 
Section mit dem Flag LOAD markiere.

Zum IAR oder CCS Assembler findet man zwar eine große Menge Ergebnisse, 
was die GCC-Toolchain angeht sieht es allerdings trübe aus.
Kann mir jemand einen Tip geben, ob es sich um einen Schalter von GCC 
handelt oder ob die Anweisung im Quelltext stehen muss?
Sonst werd ich es morgen mal mit einer anderen Suchmaschine probieren, 
der Marktführer muss ja nicht unbedingt die besten Ergebnisse liefern ;)

von Krapao (Gast)


Lesenswert?

.section .vectors, "ax"

oder ganz ausführlich

.section .vectors, "ax", @progbits

wäre mein Tipp

GNU Assembler User Manual
http://sourceware.org/binutils/docs-2.15/as/Section.html#Section

Ist aber ungetestet. Ich habe heute abend mehr Zeit als gedacht 
verbracht, um erstmal die Toolchain aufzusetzen.

von Krapao (Gast)


Lesenswert?

Neu: 
http://www.mikrocontroller.net/articles/MSPGCC#Einfaches_Assembler-Beispielprogramm

Das mit der Windows-Version von MSPDebug will ich auch noch mal 
probieren. Gestern hatte ich dort aufgehört, weil ich keinen Treiber für 
"Backchannel UART" (unbekanntes Gerät im Gerätemanager: MSP430 
Application UART) fand.

Im Moment benutze ich das MSP430 Launchpad unter LMDE (Linux Mint Debian 
Edition). mspgcc und mspdebug sind dort im Repository.

von uvok (Gast)


Lesenswert?

@Krapao
Für mspdebug unter Windows brauchst du den libusb-Treiber. Dieser 
funktioniert soweit ich weiß aber nicht für das UART-Device.
Außerdem ist es nicht möglich, CodeComposer Studio und IAR Embedded 
Workbench und mspdebug gleichzeitig auf einem PC zu benutzen, da die 
beiden IDEs eigene Treiber mitbringen.

Auf dem Rechner hier habe ich mspdebug zum Laufen gebracht, nachdem ich 
das UART-Gerät über den Gerätemanager deaktiviert habe (sonst kam eine 
Meldung, dass das Gerät nicht gefunden wurde). Vielleicht hilft dir das 
ja weiter.

von uvok C. (uvok_c)


Lesenswert?

Danke für den Tip mit den Flags im Quelltext! Ich habe es eben 
ausprobiert und mspdebug hat die .vector Section mit auf den Controller 
programmiert. Das Programm läuft auch wie erwartet.

von Krapao (Gast)


Lesenswert?

Und ich habe inzwischen den

USB CDC drivers to use the back-channel UART on the LaunchPad or on the 
eZ430 Emulator: http://processors.wiki.ti.com/images/7/71/EZ430-UART.zip

installieren können und habe jetzt gleichzeitig(!) und problemlos(!) die 
libusb Treiber zum Debuggen mit MSPDebug und die MSP430 Application UART 
Treiber für die serielle Kommunikation mit dem Launchpad unter Windows 
XP am laufen.

Die Installation selbst:

1) libUSB Treiber installieren wie in der MSPDebug FAQ beschrieben
2) EZ430-UART.zip entpacken
3) Launchpad anstöpseln und Hardwareassistent zur .INF Datei im 
EZ430-UART Ordner führen
4) Reboot

Als Terminalprogramm benutze ich noch Putty bei 2400 Baud. Hyperterminal 
zickt bei der Einstellung der Schnittstelle. Die Schnittstelle unter der 
das Launchpad erreichbar ist, sieht man im Gerätemanager unter COM/LPT 
in Klammern hinter dem Eintrag MSP430 Apllication UART. Bei mir ist es 
COM4.

Einem frohen Werkeln unter Windows oder Linux steht somit nix im Wege 
:-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.