Forum: Mikrocontroller und Digitale Elektronik Liest hier jemand von SEGGER mit? Ich hab da mal ne Frage Emulation fehlerhaft?


von Bernd K. (prof7bit)


Lesenswert?

Nachdem ich durch Aufspielen der Segger-Firmware auf das FRDM-KL05z 
Board und Verwenden des J-Link Debugservers anstelle von OpenOCD & 
CMSIS-DAP-Firmware einen Geschwindigkeitszuwachs beim Debuggen von

** außerirdischen **

Ausmaßen beobachtet habe gehe ich davon aus das es tatsächlich so ist 
daß der Debugserver von SEGGER die Instruktionen emuliert anstatt sie 
auf der MCU ausführen zu lassen.

Aber: Meine LED blinkt nun nicht mehr. Zumindest nicht im Einzelschritt.

Die KLxx Prozessoren von Freescale haben eine BME und spezielle 
zusätzliche Register an separaten Adressen, die wenn sie beschrieben 
werden den soeben geschriebenen Wert nehmen und damit eine atomare 
lesen/ändern/schreiben Operation am eigentlichen Zielregister ausführen.

Da ist zum Beispiel für jedes GPIO-Register folgendes definiert:
1
/** GPIO - Register Layout Typedef */
2
typedef struct {
3
__IO uint32_t PDOR; /**< Port Data Output Register, offset: 0x0 */
4
__O uint32_t PSOR; /**< Port Set Output Register, offset: 0x4 */
5
__O uint32_t PCOR; /**< Port Clear Output Register, offset: 0x8 */
6
__O uint32_t PTOR; /**< Port Toggle Output Register, offset: 0xC */
7
__I uint32_t PDIR; /**< Port Data Input Register, offset: 0x10 */
8
__IO uint32_t PDDR; /**< Port Data Direction Register, offset: 0x14 */
9
} GPIO_Type;

Dann kann man also zum Beispiel sagen:
1
PTB->PCOR = (1 << 4) | (1 << 5);

Und die Bits für Pins 4 und 5 werden gelöscht, in einer einzigen 
Schreiboperation.

Es scheint nun aber so daß die PCOR Register nicht korrekt emuliert 
werden vom jlink. PSOR scheint zu gehen, die anderen hab ich noch nicht 
getestet. Die LED geht aus aber nie wieder an, es sei denn ich verlasse 
den Einzelschrittmodus und lass es wieder normal laufen, dann gehts 
wieder.

Ist das ein bekannter Bug?

Hab ich jetzt einen J-Link gewonnen? Code kann ich am Montag 
nachreichen, ich hab das ganze Zeug in der Firma liegen gelassen.

Bernd

von Jim M. (turboj)


Lesenswert?

Bernd K. schrieb:
> Verwenden des J-Link Debugservers anstelle von OpenOCD &
> CMSIS-DAP-Firmware einen Geschwindigkeitszuwachs beim Debuggen

CMSIS-DAP verwendet USB HID IIRC, da wundern mich 
Geschwindigkeitsprobleme nicht wirklich. IMO gibt oder gab es da Patches 
für, aber eventuell nur in OpenOCD Gerrit.

OpenOCD kann JTAG (SWD mit neurem Git Master) auch mit einem JLINK 
Adapter - man muss aber den LibUSB-Win32 Filtertreiber installieren 
(z.B. mit Zadig).

Bernd K. schrieb:
> davon aus das es tatsächlich so ist
> daß der Debugserver von SEGGER die Instruktionen emuliert anstatt sie
> auf der MCU ausführen zu lassen.

Nö, nur die USB Kommunikation hat weniger Latenzen. Die Instruktionen 
werden von der MCU ausgeführt.

Bernd K. schrieb:
> Aber: Meine LED blinkt nun nicht mehr.

Zeig Deinen Code. Der obige Schnipsel schaltet aus, aber nicht ein.

von Bernd K. (prof7bit)


Lesenswert?

Jim Meba schrieb:
> Nö, nur die USB Kommunikation hat weniger Latenzen. Die Instruktionen
> werden von der MCU ausgeführt.

Da hab ich aber was anderes gelesen. Und das Symptom (extremer geradezu 
unwirklichrer Performancegewinn, manche Instruktionen werden nicht mehr 
korrekt ausgeführt) passt dazu. Oder hast Du eine andere Erklärung?

von Jim M. (turboj)


Lesenswert?

Bernd K. schrieb:
> Da hab ich aber was anderes gelesen.

Wo genau hast du das gelesen?

> Und das Symptom (extremer geradezu
> unwirklichrer Performancegewinn, manche Instruktionen werden nicht mehr
> korrekt ausgeführt) passt dazu. Oder hast Du eine andere Erklärung?

Das Segger zeugs ist bei mir u.a. bei Flashen auch schneller als FTDI 
(Jtagkey2) + OpenOCD.

Bei CMSIS-DAP ist noch ein Patch für OpenOCD offen, der die 
Geschwindigkeit stark steigern soll:
http://openocd.zylin.com/#/c/2356/

Es wird normalwerweise alles auf dem MCU ausgeführt, deshalb haben die 
Cortex M ja die schicke Debug-Schnittstelle von ARM spendiert bekommen.

von Bernd K. (prof7bit)


Lesenswert?

Jim Meba schrieb:
> Bernd K. schrieb:
>> Da hab ich aber was anderes gelesen.
>
> Wo genau hast du das gelesen?

Hier bin ich drüber gestolpert und anschließendes Googeln hat auch noch 
vereinzelte Hinweise darauf ergeben, leider hab ich kein Dokument 
gefunden das präzise erläutert was denn nun tatsächlich genau abläuft 
beim single-stepping:
https://www.segger.com/admin/uploads/userfiles/file/PressReleases/091016_Flash_breakpoints_IQ_magazine.pdf

> Bei CMSIS-DAP ist noch ein Patch für OpenOCD offen, der die
> Geschwindigkeit stark steigern soll:
> http://openocd.zylin.com/#/c/2356/
>
> Es wird normalwerweise alles auf dem MCU ausgeführt, deshalb haben die
> Cortex M ja die schicke Debug-Schnittstelle von ARM spendiert bekommen.

OpenOCD verwende ich momentan 0.9.0-dev weil 0.8.0 es geschafft hat das 
FRDM-KL05z-Board zu "bricken". Der Befehl "program foo.elf" scheitert 
mit einem write error und anschließend ist das Board tot. "flash 
write_image foo.elf" hingegen funktioniert einwandfrei. Das passiert 
zwar mit der 0.9.0 immer noch (wenn man vergisst die neue target/klx.cfg 
aus dem master-branch zu verwenden) aber zumindest kann man es mit 
0.9.0-dev wiederbeleben ohne vorher wieder die orginal openSDA-Firmware 
auf den onboard debug-Adapter auspielen zu müssen.

Die Geschwindigkeit beim Debugging mit openocd war jetzt nicht unbedingt 
unerträglich langsam, es war in etwa vergleichbar mit dem was ich zuvor 
auch bei openocd/st-link auf einem stm32f4 beobachtet habe, halt eben 
eine spürbare Latenz aber noch nicht wirklich störend.

Am Freitag hab ich dann in Feierabendlaune nur mal spaßeshalber die von 
Segger bereitgestellte jlink-Firmware auf den onboard-Adapter des 
FRDM-Boards gespielt und in Eclipse den jlink-gdbserver anstelle von 
openocd verwendet und der sodann folgende Geschwindigkeitsrausch war 
jenseits von nur "ein bisschen schneller", es war ungefähr so als würde 
ich eine lokale Anwendung direkt auf dem PC debuggen, es war überhaupt 
keine Latenz beim Einzelschritt mehr spürbar. Das Erlebnis war 
überwältigend.

Nur das Nicht-Funktionieren des PCOR Registers beim single-step.

Die Ursache dafür würd ich gerne verstehen. Ansonsten macht das J-Link 
Zeugs einen stabilen Eindruck und auch die explizite J-Link 
Unterstützung im Eclipse-GNUARM-Plugin gefällt mir sehr gut und ein 
stand-alone JTAG-Adapter muss ohnehin angeschafft werden. Nur dieser 
eine Wermutstropfen trübt momentan noch die Stimmung.

Die Kombination j-link Firmware auf dem Adapter und openOCD als 
Debugserver hab ich noch nicht getestet, das mach ich am Montag.

PS:
Der Code auf dem ich aufbaue beruht darauf: 
https://github.com/0xc0170/kinetis_klxx_gcc/blob/master/gpio_demo_frdmkl05z/main.c

In der main() habe ich bisher lediglich das Toggeln mit PTOR durch ein 
abwechselndes PSOR und PCOR aller drei Farben ersetzt, das läuft auch 
wunderbar, auch mit openOCD im Einzelschritt, nur mit jlink gehen die 
LED aus (PSOR denn die RGB-LED hat gemeinsame Anode) aber nicht mehr an 
(PCOR).

von Bernd K. (prof7bit)


Lesenswert?

Er überspringt ganze Programmblöcke!

Ich hab mal mit Sternchen kenntlich gemacht wo er im Einzelschritt 
langläuft. Die erset Spalte ist mit r4=5, da ist alles noch ok, unten 
wird r4 dann weitergezählt und ist wieder auf 0 (oben gehts dann mit den 
Sternchen in der zweiten Spalte weiter), dann müsste das erste if() 
zutreffen (tuts auch) und dann plötzlich bei 7ec anstatt nach 800 zu 
springen bin ich urplötzlich in 688.

Wenn ich in den Eclipse J-Link Einstellungen "enable semihosting" 
deaktiviere dann passiert das nicht.

Strange... :-/

Wer könnte schuld sein? GDB oder JLinkGDBServerCL oder Eclipse?
1
void delay(void) {
2
    uint16_t i,j;
3
    for (i = 0; i < 10000; i++) {
4
        for (j = 0; j < 100; j++) {
5
            __asm__("nop");
6
        }
7
    }
8
}
9
 
10
 
11
 
12
int main(void) {
13
14
    [...]
15
 
16
    while (1) {
17
        if      (phase == 0) {
18
            PTB->PCOR = LED_RED;
19
        }
20
        else if (phase == 1) {
21
            PTB->PSOR = LED_RED;
22
        }
23
        else if (phase == 2) {
24
            PTB->PCOR = LED_GREEN;
25
        }
26
        else if (phase == 3) {
27
            PTB->PSOR = LED_GREEN;
28
        }
29
        else if (phase == 4) {
30
            PTB->PCOR = LED_BLUE;
31
        }
32
        else if (phase == 5) {
33
            PTB->PSOR = LED_BLUE;
34
        }
35
36
        if (++phase == 6) {
37
            phase = 0;
38
        }
39
40
        delay();
41
    }

wird von gcc übersetzt mit -Os zu:
1
           delay:
2
0000067c:   ldr r2, [pc, #20]       ; (0x694 <delay+24>)
3
0000067e:   movs r3, #100   ; 0x64
4
 19                   __asm__("nop");
5
00000680:   nop ; (mov r8, r8)
6
00000682:   subs r3, #1
7
00000684:   uxth r3, r3
8
 18               for (j = 0; j < 100; j++) {
9
00000686:   cmp r3, #0
10
00000688:   bne.n 0x680 <delay+4>                                           * <- ... und zwar genau hier :-/
11
0000068a:   subs r2, #1
12
0000068c:   uxth r2, r2
13
 17           for (i = 0; i < 10000; i++) {
14
0000068e:   cmp r2, #0
15
00000690:   bne.n 0x67e <delay+2>
16
 22       }
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
                                                                    r4=5    r4=0
25
117       if      (phase == 0) {
26
000007e4:   cmp r4, #0                                              *       *
27
000007e6:   bne.n 0x7ee <main+38>                                   *       *
28
118                   PTB->PCOR = LED_RED;
29
000007e8:   movs r3, #128   ; 0x80                                          *
30
000007ea:   lsls r3, r3, #1                                                 *
31
000007ec:   b.n 0x800 <main+56>                                             *  -> und im naechsten Schritt bin ich in der delay loop...
32
120               else if (phase == 1) {
33
000007ee:   cmp r4, #1                                              *
34
000007f0:   bne.n 0x7f8 <main+48>                                   *
35
121                   PTB->PSOR = LED_RED;
36
000007f2:   movs r3, #128   ; 0x80
37
000007f4:   lsls r3, r3, #1
38
000007f6:   b.n 0x820 <main+88>
39
123               else if (phase == 2) {
40
000007f8:   cmp r4, #2                                              *
41
000007fa:   bne.n 0x804 <main+60>                                   *
42
124                   PTB->PCOR = LED_GREEN;
43
000007fc:   movs r3, #128   ; 0x80
44
000007fe:   lsls r3, r3, #2
45
00000800:   str r3, [r5, #8]
46
00000802:   b.n 0x822 <main+90>
47
126               else if (phase == 3) {
48
00000804:   cmp r4, #3                                              *
49
00000806:   bne.n 0x80e <main+70>                                   *
50
127                   PTB->PSOR = LED_GREEN;
51
00000808:   movs r3, #128   ; 0x80
52
0000080a:   lsls r3, r3, #2
53
0000080c:   b.n 0x820 <main+88>
54
129               else if (phase == 4) {
55
0000080e:   cmp r4, #4                                              *
56
00000810:   bne.n 0x818 <main+80>                                   *
57
130                   PTB->PCOR = LED_BLUE;
58
00000812:   movs r3, #128   ; 0x80
59
00000814:   lsls r3, r3, #3
60
00000816:   b.n 0x800 <main+56>
61
132               else if (phase == 5) {
62
00000818:   cmp r4, #5                                              *
63
0000081a:   bne.n 0x822 <main+90>                                   *
64
133                   PTB->PSOR = LED_BLUE;
65
0000081c:   movs r3, #128   ; 0x80                                  *
66
0000081e:   lsls r3, r3, #3                                         *
67
00000820:   str r3, [r5, #4]                                        *
68
136               if (++phase == 6) {
69
00000822:   adds r4, #1                                             *
70
00000824:   uxtb r4, r4                                             *
71
137                   phase = 0;
72
00000826:   subs r3, r4, #6                                         *
73
00000828:   subs r2, r3, #1                                         *
74
0000082a:   sbcs r3, r2                                             *
75
0000082c:   negs r3, r3                                             *
76
0000082e:   ands r4, r3                                             *
77
140               delay();
78
00000830:   bl 0x67c <delay>                                        *
79
141           }
80
00000834:   b.n 0x7e4 <main+28>                                     *

von John-eric K. (mockup)


Lesenswert?

Wie wäre es, dass du denen einfach mal schreibst.
info@segger.com

Die waren sehr freundlich. Ich hatte so auch schon Fragen und Bugs 
geklärt.

von Bernd K. (prof7bit)


Lesenswert?

John-eric K. schrieb:
> Wie wäre es, dass du denen einfach mal schreibst.
> info@segger.com

Hab ich jetzt mal gemacht. Leider kann man auch nicht einfach in deren 
Forum posten, nicht mal nach erfolgter Anmeldung dort, also der einzige 
Weg scheint wirklich E-Mail zu sein.

Wenn man in alten Threads hier auf µC.net herumstöbert stolpert man über 
vereinzelte Postings von SEGGER-Leuten die hier sogar in offizieller 
Eigenschaft unterwegs waren und Hilfe leisteten, aber scheinbar haben 
die sich mittlerweile verzogen oder wurden vergrault.

von SEGGER - Johannes (Gast)


Lesenswert?

Hallo,

wir (SEGGER) besuchen mikrocontroller.net in der Regel nur, wenn wir 
entsprechende Supportanfragen erhalten.
Bei Problemen mit dem J-Link oder anderen SEGGER-Produkten empfehlen wir 
folgende Kontaktmöglichkeiten:
 - Für Produkte die noch im Support sind (z.B. 1 Jahr für J-Link 
Base/PLUS, 2 Jahre für J-Link ULTRA+/PRO) per e-Mail an 
support@segger.com
 - Für Produkte ohne Support (z.B. J-Link EDU/OB/LITE) über unser Forum 
(http://forum.segger.com)

Die Freischaltung im Forum erfolgt manuell und kann daher bis zu 24 
Stunden dauern.

Wegen des oben geschilderten Problems sind wir bereits per e-Mail in 
Kontakt und werden eine Lösung finden.


Johannes - J-Link Develpment / Support

von Bernd K. (prof7bit)


Lesenswert?

Ich lese gerade in meiner Inbox daß das Problem reproduziert und auch 
bereits behoben werden konnte und ein dementsprechendes baldiges (diese 
Woche) Bugfix-Release schon in Vorbereitung ist.

Das hört sich doch schon mal gut an :-)

von Johannes L. (Firma: SEGGER) (segger_johannes)


Lesenswert?

Wir konnten das Problem reproduzieren und beheben.
Bei dem Step auf 0x800 wurde diese Instruktion fälschlicherweise als 
Semihostingfunktion interpretiert, was dazu führte, dass sie 
übersprungen (PTB->PCOR wurde nicht beschrieben) und das Target 
anschließend laufen gelassen wurde.

Der Fix ist bereits im aktuellen Beta enthalten (V4.97f, 
https://www.segger.com/jlink-software-beta-version.html) und wird heute 
auch im neuen Release (V4.96g, 
https://www.segger.com/jlink-software.html) enthalten sein.

Zur Geschwindigkeit sei folgendes zu sagen:
Der J-Link kann durch verschiedene Optimierungen eine sehr hohe 
Performance erreichen, dazu gehören unter anderem das Simulieren von 
Instruktionen bei Instructionsteps sowie der integrierte Flashdownload 
für die meisten Devices.
Für die beste Performance empfehlen wir den J-Link mit der J-Link 
Software (J-Link GDB Server) an Stelle des OpenOCD zu verwenden um von 
allen Optimierungen gebrauch machen zu können.


Johannes - J-Link Development / Support

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.