Forum: Mikrocontroller und Digitale Elektronik STM32 warum funktioniert printf?


von alu (Gast)


Lesenswert?

Hallo zusammen,

Ich habe ein STM32F4-Discoveryboard und nutze die summon-arm-toolchain 
unter linux. Nachdem ich mir eine UART eingerichtet habe, habe ich 
einfach mal so printf ausprobiert und war erstaunt, dass es ich es 
tatsächlich verwenden konnte.
Mittlerweile habe ich überhaupt keine anderen tx-Funktionen (kein putc 
oder Ähnliches) und ich frage mich z.B. woher printf überhaupt weiß, 
dass ich die UART2 verwende und welche Funktionen/Mechanismen zum Senden 
aufgerufen werden.
Die Definitionen sind in stdio.h sind für mich nur kryptisches 
Makro-Chinesisch...

Es wäre schön, wenn jemand hier etwas Licht ins Dunkel bringen könnte

von Ingo (Gast)


Lesenswert?

Die ARMs sind halt aus ner anderen Dimension, da brauchste nichtmal 
Code, die wissen was du willst. Musst du überhaupt noch Flaschen oder 
geht's schon per Zuruf?


SCNR ;),
Ingo

von Stefan (Gast)


Lesenswert?

>> Nachdem ich mir eine UART eingerichtet habe...

Wie hast Du das denn gemacht? Dabei hast Du bestimmt die Konsole 
eingerichtet (stdin/stdout).

von alu (Gast)


Lesenswert?

>> Wie hast Du das denn gemacht? Dabei hast Du bestimmt die Konsole eingerichtet 
(stdin/stdout).


Dies ist meine UART-Initialisierung. Weiterhin habe ich noch den 
IRQ-Handler implementiert, allerdings wird dort nur der Empfang 
bearbeitet.

1
void initUSART(uint32_t baudrate)
2
{
3
  USART_InitTypeDef   USART_InitStructure;
4
  GPIO_InitTypeDef    GPIO_InitStructure;
5
  NVIC_InitTypeDef   NVIC_InitStructure;   // nested vector interrupt controller
6
7
  // Enable clocks
8
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
9
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
10
11
  // Prepare required pins to alternative function
12
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_2 | GPIO_Pin_3;
13
  GPIO_InitStructure.GPIO_Speed   = GPIO_Speed_100MHz;
14
  GPIO_InitStructure.GPIO_Mode   = GPIO_Mode_AF;
15
  GPIO_InitStructure.GPIO_OType   = GPIO_OType_PP;
16
  GPIO_InitStructure.GPIO_PuPd   = GPIO_PuPd_UP;
17
  GPIO_Init(GPIOA, &GPIO_InitStructure);
18
19
  // Now the pins can be set to alternative function (USART)
20
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);  // GPIOA PA2: USART2_TX
21
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);  // GPIOA PA3: USART2_RX
22
23
24
  // Configuration of USART
25
  USART_InitStructure.USART_BaudRate         = baudrate;
26
  USART_InitStructure.USART_WordLength       = USART_WordLength_8b;        // standard
27
  USART_InitStructure.USART_StopBits         = USART_StopBits_1;          // standard
28
  USART_InitStructure.USART_Parity         = USART_Parity_No;          // standard
29
  USART_InitStructure.USART_HardwareFlowControl   = USART_HardwareFlowControl_None;  // standard
30
  USART_InitStructure.USART_Mode           = USART_Mode_Tx | USART_Mode_Rx;
31
  USART_Init(USART2, &USART_InitStructure);
32
33
34
  // Configure interrupt handler USART2_IRQHandler()
35
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
36
37
  NVIC_InitStructure.NVIC_IRQChannel             = USART2_IRQn;
38
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority   = 0;
39
  NVIC_InitStructure.NVIC_IRQChannelSubPriority       = 0;
40
  NVIC_InitStructure.NVIC_IRQChannelCmd           = ENABLE;
41
  NVIC_Init(&NVIC_InitStructure);
42
43
44
  // Enable UART
45
  USART_Cmd(USART2, ENABLE);
46
}

von vampire (Gast)


Lesenswert?

-echo (on)?;
-debug on?

alu schrieb:
> Weiterhin habe ich noch den
> IRQ-Handler implementiert, allerdings wird dort nur der Empfang
> bearbeitet.

??

von alu (Gast)


Lesenswert?

vampire schrieb:
> -echo (on)?;
> -debug on?

Ich weiß leider nicht was du hiermit meinst. Bin noch nicht so lange mit 
dem ARM dabei..

Meinen IRQHandler habe ich inzwischen vollkommen geleert:
1
void USART2_IRQHandler(void){}

printf funktioniert immer noch.
Ich verstehe es einfach nicht..

von Karl (Gast)


Lesenswert?

Quellcode? Automagisch geht das sicher nicht...

BTW hat die summon-arm toolchain einen recht fiesen Bug (siehe ARM).

von bösewicht (Gast)


Lesenswert?

alu schrieb:
> und ich frage mich z.B. woher printf überhaupt weiß,
> dass ich die UART2 verwende und welche Funktionen/Mechanismen zum Senden
> aufgerufen werden.

und später

alu schrieb:
> // Enable UART
>   USART_Cmd(USART2, ENABLE);
> }

Warum soll dann printf nicht fkt.?
(die summon-arm-toolchain
unter linux kenn ich allerdings nicht -- )

von Bronco (Gast)


Lesenswert?

Ich würde mal vermuten, daß printf eine Default-Konfig hat, die auf 
UART2 zeigt, und daß dort nicht per ISR, sondern per Polling gesendet 
wird.
Istaber nur eine Vermutung...

von Hui (Gast)


Lesenswert?

USART_Init(USART2, &USART_InitStructure);

Blind geschossen würde ich sagen das in der Funktion etwas drinsteckt 
nach dem Motto
Hey Printf weist du schon wo du hin musst?
Nein!
Nimm mal UART2 der wird hier gerade aktiviert.
OK!

Oder bei USART_Cmd(USART2, ENABLE);

Ohne in das Fachchinesisch schauen zu wollen würde ich an deiner Stelle 
mal alles auf USART1 ummünzen und schauen ob auf 2 immer noch was 
rauskommt.
Dann mal sehen ob das zuletzt oder zuerst initialisierte USART den 
"Zuschlag" erhält oder beide. und ob es der init befehl oder der enable 
ist.

von ♪Geist (Gast)


Lesenswert?

>Die Definitionen sind in stdio.h sind für mich nur kryptisches
>Makro-Chinesisch...
Da wird bestimmt eine custom stdio.c automatisch gelinkt. Alles andere 
wäre Wunder ;)

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.