Forum: Mikrocontroller und Digitale Elektronik STM32, printf und fflush


von Ralph S. (jjflash)


Lesenswert?

Vorneweg: Mein "Problem" ist "neugieriger Natur", da ich in aller Regel 
in Verbindung mit Mikrocontrollern ein eigenes printf (mit 
Festkommaausgabe) anstelle eines kompletten printf aus der libc 
verwende.

Allerdings habe ich dazu dennoch eine Frage, weil es im Bekanntenkreis 
darum ging, wie man es bewerkstelligt, dennoch ein printf der libc (oder 
evtl. der libc_nano, dann ohne Gleitkomma) in Verbindung mit STM32 
verwenden kann.

Bedingungen:

- Compiler: arm-none-eabi-gcc
- Library: libopencm3
- Programm wird gegen libc gelinkt
- eigene Software zur Ausgabe eines einzelnen Zeichens über uart
- Controller: STM32F103 (allerdings logischerweise gleiches Verhalten 
bei STM32F0 und STM32F4)

Folgendes (funktionsfähiges) Testprogramm:
1
#include <libopencm3.h>
2
3
#include <stdint.h>
4
#include <string.h>
5
#include <math.h>
6
7
// zwingend fuer Verwendung von "printf" notwendig
8
#include <errno.h>
9
#include <stdio.h>
10
#include <unistd.h>
11
12
#include "sysf103_init.h"
13
#include "uart.h"
14
15
16
#define BAUDRATE 19200
17
18
int _write(int file, char *ptr, int len)
19
{
20
  int i;
21
22
  if (file == STDOUT_FILENO || file == STDERR_FILENO)
23
  {
24
    for (i = 0; i < len; i++)
25
    {
26
      uart_putchar(ptr[i]);
27
    }
28
    return i;
29
  }
30
  errno = EIO;
31
  return -1;
32
}
33
34
/* --------------------------------------------------------
35
                             main
36
   -------------------------------------------------------- */
37
int main(void)
38
{
39
  uint8_t count;
40
  double sw, wi;
41
42
  sys_init();
43
44
  uart_init(BAUDRATE);
45
46
  wi= 45.0;
47
48
  sw= sin(wi * M_PI / 180.0);
49
50
  printf("\n\r-------------------------------------\n\n\r");
51
  printf("STM32F103C8T6 / %luMHz - %dBd 8N1\n\r", rcc_ahb_frequency/1000000, BAUDRATE);
52
  printf(" Februar 2020 R. Seelig \n\n\r");
53
  printf(" APB = %lu MHz\n\r", rcc_apb1_frequency/1000000);
54
  printf(" AHB = %lu MHz\n\r", rcc_ahb_frequency/1000000);
55
  printf("\n\r-------------------------------------\n\n\r");
56
57
  printf("Sinus von %.2f= %.4f\n\r", wi, sw);
58
  wi= 341234.123 * 12432.48;
59
  printf("Egebnis einer Rechnung: %3.4f\n\n\r", wi);
60
61
  printf("Ein einfacher Integer Zaehler\n\r" );
62
  printf("-------------------------------------\n\r");
63
  count= 0;
64
  while(1)
65
  {
66
    printf("    count= %d \r",count);
67
    fflush(stdout);                      // wichtig, da printf den Stream erst mit einem \n abschickt
68
    count++;
69
    delay(1000);
70
  }
71
}

Meine Frage bezieht sich hier auf Zeile 66 und 67.

printf schreibt seine Ausgaben in einen Puffer und schickt diesen Puffer 
erst bei Eintreffen eines newline "\n" Zeichens ab. Möchte ich jetzt 
aber ganz bewußt kein newline schicken (damit bspw. eine Ausgabe immer 
in derselben Zeile erfolgt) muß ich zwingend den Puffer mit einem 
fflush(stdout) leeren.

Das finde ich (für mich) etwas unschön, denn ich hätte es gerne, dass 
genau das was printf ausgeben soll sofort ausgegeben wird und nicht erst 
dann, wenn ein "\n" Zeichen eintrifft.

Natürlich könnte ich jetzt in einem Timerinterrupt perodisch ein 
fflush(stdio) abschicken, aber das empfinde ich noch etwas unschöner.

Gibt es hier eine Lösung um auf das fflush verzichten zu können?

von Nop (Gast)


Lesenswert?

Ralph S. schrieb:

> Gibt es hier eine Lösung um auf das fflush verzichten zu können?

Du könntest das Buffering abschalten:
1
(void) setvbuf(stdout, NULL, _IONBF, 0);

von Ralph S. (jjflash)


Lesenswert?

Nop schrieb:
> Ralph S. schrieb:
>
>> Gibt es hier eine Lösung um auf das fflush verzichten zu können?
>
> Du könntest das Buffering abschalten:
>
>
1
(void) setvbuf(stdout, NULL, _IONBF, 0);

Ganz herzlichen Dank, genau das war die Lösung, nach der ich gesucht 
hatte !

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.