STM32 - CodeBench Lite - 64-bit Division

OP Persönliche Seite #2814585
Lesenswert?
• ▲
▼
Folgendes mir unerklärliche Verhalten:

Cross-Compiler: 2011.03 / 2011.09 und 2012.03 Versionen von Sourcery 
Codebench Lite.
Library: Newlib C Library (1.18.0-sg++) (stdlib.h) aus der Suite 
Sourcery CodeBench Lite.

Verhalten: sobald die Funktion "strtoull" im Programmcode eingebaut wird 
ist die Baudrate von USART1 vervierfacht. Keine Fehlermeldungen, keine 
Warnmeldungen beim compilieren, Programm läuft, Debugger läuft, evtl. 
geht das Programm manchmal in den HardFault_Handler interrupt.
Das selbe Verhalten tritt auf sobald folgendes irgendwo in das Programm 
eingebaut wird (also unabhängig davon ob dies auch ausgeführt wird):
1
long long test1 = 10, test2 = 4, test3;
2
test3 = test1 / test2;

Vermute, dass "strtoull" ebenfalls eine 64-bit Division enthält. Die 
64-Bit Division führt in jedem Falle zu dem Fehlverhalten.
Erhebliche Vergrößerung des Stacks erbringt keinerlei Veränderung des 
Verhaltens, selbst das Ergebnis der Division scheint korrekt (keine 
ausgiebigen Versuche, da eine Division dieser Art nicht benötigt wird).

Manual "Using the GNU Compiler Collection, chapter 6.9" sagt aus, dass: 
"(long long) divisions are open coded and are available only on machines
providing special support."

Die Frage ist:
Was passiert da? Schließlich ist die Baudrate unabhängig vom erzeugten 
Code und lediglich ein Wert in einem CPU-Register.
Erklärungen?
#2819316
Lesenswert?
• ▲
▼
>  Was passiert da? Schließlich ist die Baudrate unabhängig vom erzeugten
> Code und lediglich ein Wert in einem CPU-Register.

Die meisten Cortex_M3 Libs die ich kenne erzeugen den Wert für die 
Baudrate dynamisch aus der aktuellen CPU Frequenz. Und weil da relevante 
Nachkommastellen auftreten könnnen wird mit 64 Bits gerechnet.

Abhilfe: Bei bekanntem CPU Takt die entsprechenden Werte von Hand - oder 
vom Compiler - ausrechnen (lassen) und in die Register eintragen.

Es könnte sein dass die Funtion nicht reentrant ist - dann darf man 
diese Berechnung der Baudrate nicht im Interrupt ausführen.
Moderator Persönliche Seite #2820383
Lesenswert?
• ▲
▼
Ja, 64bit-Division ist augenscheinlich in strtoll. Quellcodeteil der 
newlib sieht aber wenig dramatisch aus: 
http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/stdlib/strtoll_r.c?rev=1.3&content-type=text/x-cvsweb-markup&cvsroot=src 
. Unter bestimmten Bedingungen wird jedoch ein Fehlercode gesetzt, dabei 
wird in einen Struktur vorm Type __reent geschrieben. Beim Aufruf der 
"normalen" Funktion (nicht der _r-Variante) wird dann in 
impure_data.errno geschrieben. _impure_ptr zeigt auf diese globale 
Stuktur impure_data. Man kann also evtl. hier per Debugger nachverfolgen 
- erscheint aber wenig erfolgversprechend.

Problem könnte auch im Zusammenhang mit der Fehlerüberprüfung einer 
Divisiononsroutine in der libgcc liegen. Gibt es im Linkerscript 
Einträge für ARM.extab und ARM.exidx? Einige Versionen der libgcc haben 
Abhängigkeiten zur C++-Ausnahmeverarbeitung mitgezogen, selbst wenn man 
"reines" C nutzt. Im Zweifel und falls nicht schon drin, die die beiden 
Sections in das Linkerscript eintragen (siehe Beispiele in CS 
Installationsverzeichnis) und anhand des Map-Files prüfen, ob dort etwas 
von libgcc (und/oder libc) abgelegt wird (siehe vor allem nach 
libgcc/_udivdi3 und libgcc/_divdi3 jeweils einträge in extab und exidx, 
in exidx zusätzlich noch für libgcc/bpabi).
#2820453
Lesenswert?
• ▲
▼
Jim Meba schrieb:
> Die meisten Cortex_M3 Libs die ich kenne erzeugen den Wert für die
> Baudrate dynamisch aus der aktuellen CPU Frequenz. Und weil da relevante
> Nachkommastellen auftreten könnnen wird mit 64 Bits gerechnet.

Sieht bei mir eher schlicht aus, STM32F1xx:
    unsigned apbclk = (info->dev == USART1) ? F_APB2 : F_APB1;
    info->dev->BRR = apbclk / baud;
Die 4 Nachkommstellen stehen im Baudratenregister. Ok, man könnte hier 
noch ein halbes Bit runden, aber ob das so wichtig ist? Weshalb man da 
64 Bits braucht erschliesst sich mir nicht.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.