Forum: Mikrocontroller und Digitale Elektronik sprintf ersatz? ( c code )


von c schüler (Gast)


Lesenswert?

hi

gibt es einen vernünftigen sprintf ersatz für einen einzelnen parameter 
als unsigned long ?

- ohne malloc
- ohne stdarg.h

wie macht ihr das im embedded design?


da war ich schon:
1
int v = -10093;    //Integer value to convert to string
2
3
  char buffer[64];
4
  int nI = 0;
5
6
  if(v < 0)
7
  {
8
    buffer[nI++] = '-';
9
    v = -v;
10
  }
11
12
  if(v)
13
  {
14
    BOOL bNoLeadingZeros = TRUE;
15
    static int pMods[] = {1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
16
    for(int i = 0; i < sizeof(pMods) / sizeof(pMods[0]); i++)
17
    {
18
      int d = v / pMods[i];
19
      if(d || !bNoLeadingZeros)
20
      {
21
        bNoLeadingZeros = FALSE;
22
        buffer[nI++] = '0' + d;
23
        v &#37;= pMods[i];
24
      }
25
    }
26
  }
27
  else
28
    buffer[nI++] = '0';
29
30
  buffer[nI] = 0;
31
32
  //'buffer' now contains the string version of 'v'


auch da:
braucht die libgcc
das ist schlecht

1
char *itoa(int num)
2
3
{
4
static char buff[20] = {};
5
int i = 0, temp_num = num, length = 0;
6
char *string = buff;
7
if(num >= 0) {
8
// count how many characters in the number
9
while(temp_num) {
10
temp_num /= 10;
11
length++;
12
}
13
// assign the number to the buffer starting at the end of the 
14
// number and going to the begining since we are doing the
15
// integer to character conversion on the last number in the
16
// sequence
17
for(i = 0; i < length; i++) {
18
buff[(length-1)-i] = '0' + (num % 10);
19
num /= 10;
20
}
21
buff[i] = '\0'; // can't forget the null byte to properly end our string
22
}
23
else
24
return "Unsupported Number";
25
return string;
26
}


und auch da

https://github.com/mludvig/mini-printf
Fehler: "signal caught in writing whirl file"

und chan werde ich noch ansehen:

http://elm-chan.org/fsw/strf/xprintf.html

von Tse (Gast)


Lesenswert?

c schüler schrieb:
> wie macht ihr das im embedded design?
ultoa

von Jim M. (turboj)


Lesenswert?

Welche Architektur ist das (int scheint 32 bittig, also kein AVR), warum 
ist LibGCC schlecht?

Wenn LibGCC "schlecht" ist, dann sollte man einen anderen Compiler als 
GCC benutzen oder direkt in Assembler programmieren.

von Amateur (Gast)


Lesenswert?

sprint und Konsorten brauchen nur deshalb so viel Platz, weil es 
sogenannte eierlegende Wollmilchsäue sind.
Geschrieben unter der Maxime: "Darf‘s noch ein bissel mehr sein"?
Würde mich, beim Betrachten der Optionen, nicht wundern, wenn die auch 
kochen und backen können.

Allerdings gibt es auch oft Leute die keinen Einheitsbrei auszugeben 
haben, was in Umkehr der obigen Aussage ein Vorteil wäre.

Also des einen Freud...

In diesem Konflikt würde ich Dir empfehlen: Sag doch mal was Du 
(ausgeben)willst!

von Der Pfnott (Gast)


Lesenswert?

Sprintf sollte man sofort vergessen. Viel zu klotzig. Was man 
standardmaessig braucht sind integer fuer die Benutzung und Hex zum 
debuggen.

von PittyJ (Gast)


Lesenswert?

>>Sprintf sollte man sofort vergessen. Viel zu klotzig.

Warum? Wenn genug Platz das ist, kann man es doch auch benutzen.
Und man muss sich verdammt anstrengen, den Speicher der modernen 
Prozessoren komplett zu belegen.

Ich würde sprintf benutzen, um mich lieber den wichtigen Problemen 
widmen.

von Axel S. (a-za-z0-9)


Lesenswert?

c schüler schrieb:
> auch da:
> braucht die libgcc

Verstehe ich jetzt nicht. Wozu sollte diese itoa Implementierung 
libgcc benötigen? Ich sehe da nur Standard-C in Verwendung.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

c schüler schrieb:
> int d = v / pMods[i];
>
> braucht die libgcc

Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer 
Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.

Evtl. reisst da -O3 -funroll-loops -funroll-all-loops was aus, aber auf 
deep embedded ist das auch nicht wirklich prickelnd.  Dann doch lieber 
so (C99):
1
#include <stdint.h>
2
#include <stdbool.h>
3
4
#if defined (__GNUC__) && defined (__AVR__) && defined (__FLASH)
5
#define flash __flash
6
#else
7
#define flash // empty
8
#endif // avr-gcc has __flash
9
10
// Wandelt N in eine ASCII-Dezimalzahl um. Die Darstellung wird
11
// mit abschliessender '\0' als Stringende nach *STR geschrieben.
12
// Return: Adresse der abschliessenden '\0'.
13
14
char* u32_to_string (char *str, uint32_t n)
15
{
16
    static const flash uint32_t pows10[] = 
17
    {
18
        1e8, 1e7, 1e6, 1e5, 1e4, 1e3, 1e2, 1e1
19
    };
20
21
    const flash uint32_t *p = pows10;
22
23
#if defined (__OPTIMIZE__) && !defined (__OPTIMIZE_SIZE__)
24
    if (n < 100000)
25
        p += 4; // skip 10^8 ... 10^5
26
#endif
27
28
    uint32_t pow10;
29
    bool nonzero = false;
30
31
    do
32
    {
33
        pow10 = *p++;
34
35
        char c = '0';
36
        
37
        while (n >= pow10)
38
        {
39
            n -= pow10;
40
            nonzero = true;
41
            c++;
42
        }
43
            
44
        if (nonzero)
45
            *str++ = c;
46
            
47
    } while (! (pow10 & 2)); // pow10 != 10
48
    
49
    // Einer
50
    *str++ = n + '0';
51
    *str = '\0';
52
    
53
    return str;
54
}

von Daniel B. (dbuergin)


Lesenswert?

verwende seit längerem die xprintf Version von Chan mit Erfolg, 
respektive ohne Probleme.

von c schüler (Gast)


Lesenswert?

danke an alle!
ich habe xprintf mal mehr oder weniger jetzt auch hier in dem fall 
probiert und es läuft damit mal vorerst. der ansatz von Johann werde ich 
mal näher ansehen, danke!

@PittyJ
ich widme mich gerade dem problem "sprintf" :)

der thread gab mir auch sehr viel hintergrund hilfe:
Beitrag "sprintf am STM32F072"

um auf bestimmte compiler flaggs zu kommen.
ich brauche kein float, nur max unsigned long.

solved!

lg
;-)

@Daniel:
ich hatte xprintf noch gar nicht bemerkt im sd einsatz,
nur immer schön altbacken sprintf / printf.

von c schüler (Gast)


Lesenswert?

Johann L. schrieb:
> c schüler schrieb:

>> int d = v / pMods[i];
>>
>> braucht die libgcc
>
> Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer
> Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.

wenn ich jemals nur 50 prozent wissen erreiche um eine derartig - mitten 
ins schwarze - treffende aussage machen zu können, wäre ich zufrieden.
1+

es wurde alles gestrippt was es zu strippen gilt(gibt).
jetzt wird langsam aufgebaut, was wirklich nur gebraucht wird und
auf was verzichtet werden kann.


nicht böse sein Axel:

Axel S. schrieb:
> c schüler schrieb:
>> auch da:
>> braucht die libgcc
>
> Verstehe ich jetzt nicht. Wozu sollte diese itoa Implementierung
> libgcc benötigen? Ich sehe da nur Standard-C in Verwendung.


da sind welten dazwischen :)

danke Johann!

;-)

von Axel S. (a-za-z0-9)


Lesenswert?

c schüler schrieb:
> Johann L. schrieb:

>> Das wundert duch jetzt nicht wirklich...?  Du dividiert auf einer
>> Hardware, die kein DIV-Befehl hat, durch einen unbekannten Divisor.
>
> wenn ich jemals nur 50 prozent wissen erreiche um eine derartig - mitten
> ins schwarze - treffende aussage machen zu können, wäre ich zufrieden.

Naja, das war einfach gut geraten. Zumal du ja deine Zielarchitektur gar 
nicht genannt hattest.

> nicht böse sein Axel:
>
> Axel S. schrieb:
>> Verstehe ich jetzt nicht. Wozu sollte diese itoa Implementierung
>> libgcc benötigen? Ich sehe da nur Standard-C in Verwendung.
>
> da sind welten dazwischen :)

Du hättest ja auch ein bisschen mehr Input liefern können. Zum Beispiel 
was aus der libgcc da zu deinem Programm gelinkt wird. Und du hast 
auch immer noch nicht gesagt, warum das schlecht sein soll. Jedes 
C-Programm braucht Funktionen aus der C-Runtime. Das eine mehr, das 
andere weniger. Und wenn du eine arithmetische Operation verwendest, die 
auf der Zielarchitektur nicht inline erzeugt werden kann, dann 
bekommst du halt die entsprechende Funktion aus der Runtime dazugelinkt. 
Was denn sonst?

von W.S. (Gast)


Lesenswert?

c schüler schrieb:
> gibt es einen vernünftigen sprintf ersatz für einen einzelnen parameter
> als unsigned long ?

Lade dir die Lernbetty hier aus dem Forun herunter und benutze davon 
conv.c - da hast du eigentlich alles, was du brauchst.

Und "JA" das hat hier auch schon jemand mit nem AVR benutzt, dieses 
Stückchen Quelle geht nicht nur für ARM.

Und noch ein Wort zu sprintf und Konsorten: Auf einem µC ist mir sowas 
auch viel zu klobig.

W.S.

von Bernd K. (prof7bit)


Lesenswert?

PittyJ schrieb:
> Und man muss sich verdammt anstrengen, den Speicher der modernen
> Prozessoren komplett zu belegen.

Was? 8 kB hab ich ruckzuck voll.

Ach so, keine verallgemeinerungen von "mein Controller" auf "jeder 
Controller", dann streich obigen Satz wieder.

Und streich dann aber Deinen bitte ebenfalls.

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.