Problem mit sprintf aus gcctest9

Gast #74569
Lesenswert?

Hallo!

Ich verwende den Code aus gcctest9 mit einem at90s8515.

Codeauszug:

SIGNAL(SIG_INTERRUPT0)     /* signal handler for external interrupt
int0 */
{
  u08 pos;
  pos=240;
  send();
  sprintf(out, "    Position: %u \r\n", pos);
        uart_putstr(out);       /* print via UART */
        uart_putstr("Position gesendet. \r\n");

}



int sprintf(u08 *buf, const u08 *format, ...)
/* simplified sprintf */
{
  u08 scratch[SCRATCH];
  u08 format_flag;
  u16 u_val=0, base;
  u08 *ptr;
  va_list ap;

  va_start (ap, format);
  for (;;){
    while ((format_flag = *format++) != '%'){      /* Until '%' or
'\0' */
      if (!format_flag){va_end (ap); return (0);}
      *buf = format_flag; buf++; *buf=0;
    }

    switch (format_flag = *format++){

    case 'c':
      format_flag = va_arg(ap,int);
    default:
      *buf = format_flag; buf++; *buf=0;
      continue;
    case 'S':
    case 's':
      ptr = va_arg(ap,char *);
      strcat(buf, ptr);
      continue;
    case 'o':
      base = 8;
      *buf = '0'; buf++; *buf=0;
      goto CONVERSION_LOOP;
    case 'i':
      if (((int)u_val) < 0){
        u_val = - u_val;
        *buf = '-'; buf++; *buf=0;
      }
      /* no break -> run into next case */
    case 'u':
      base = 10;
      goto CONVERSION_LOOP;
    case 'x':
      base = 16;

    CONVERSION_LOOP:
      u_val = va_arg(ap,int);
      ptr = scratch + SCRATCH;
      *--ptr = 0;
      do {
        char ch = u_val % base + '0';
        if (ch > '9')
          ch += 'a' - '9' - 1;
        *--ptr = ch;
        u_val /= base;
      } while (u_val);
      strcat(buf, ptr);
      buf += strlen(ptr);
    }
  }
}

Bei INT0 wird:

00000001
 Position gesendet.

ausgegeben. (00000001 wird von send(); erzeugt)

Wird die Variable pos nicht gewandelt und in out abgelegt?
Oder wird out nur nicht ausgegeben?
Welche Fehler von sprintf sind bekannt.

Danke für eure Hilfe.
Tino
Gast #74570
Lesenswert?

Nur als Hinweis: die gcctest-Programme sind veraltet.

Die aktuelle avr-libc Version enthält eine offizielle Version der
printf()-Familie, einschließlich sprintf().  Allerdings ist printf
naturgemäß nicht klein, beachte auch die dokumentierten drei
Varianten,
die sich vorrangig hinsichtlich der implementierten Features und der
daraus resultierenden Codegröße unterscheiden (standard, minimal,
maximal -- alles einschließlich Gleitkomma).
Gast #74571
Lesenswert?

Danke Für den Hinweis.
Ich habe mir bereits selbst eine derartige Funktion geschrieben, da ich
eine sehr minimalistische Version benötige.
Mein Code ist bereits sehr groß und ich kann die libc-Funktion nicht
verwenden.

Bye Tino
Gast #74572
Lesenswert?

Nun, Deine eigenen Funktionen können wir Dir schlecht supporten. ;-)

Generell halte ich es übrigens für eine schlechte Idee, potentiell
langwierige Operationen aus einer Interruptroutine heraus
auszuführen.  Falls Deine UART-Routinen nicht gerade so viel Puffer
benutzen, daß die kompletten Strings da alle reinpassen, dann ist das
Senden über die UART aber potentiell langwierig.

Falls sie gepuffert sind, könntest Du eventuell auch dort ein Problem
mit dem `rollover' des Puffers haben.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren