Forum: Mikrocontroller und Digitale Elektronik STM32 Nucleo32 - FREERTOS mit UART-Rx


von Roman R. (reiter86)


Lesenswert?

Hallo,

Ich verwende einen STM32 Nucleo32 mit FREERTOS und gebe über einen Task 
im Sekundentakt eine Nachricht über UART auf Putty aus und möchte 
zusätzlich wenn ich ein Zeichen eingebe, dass die 
"HAL_UART_RxCpltCallback" aufgerufen wird und anschließend wieder in den 
Task gesprungen wird.

Task:
void monitoringFunction(void *argument)
{
  printf("Test\n");
  osDelay(1000);
}

Callback:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  printf("CpltCallback\n");
  HAL_UART_Receive_IT(&huart2, RxBuffer, RxBuffer_SIZE);
}

Habe vor dem osKernelInitialize() den UART2-Interrupt-Receive aktiviert
HAL_UART_Receive_IT(&huart2, RxBuffer, RxBuffer_SIZE);

Wenn ich das Programm starte tut sich mal nichts.
Wenn ich eine Taste drücke wird in die Callback gesprungen und 
"CpltCallback" ausgegeben.
Wenn ich wieder eine Taste drücke wird wieder in die Callback gesprungen 
und "CpltCallback" ausgegeben.

ABER es wird nicht in den Task gesprungen.

Wenn ich die HAL_UART_Receive_IT(&huart2, RxBuffer, RxBuffer_SIZE) in 
der Callback entferne, komme ich nur ein einziges mal in die Callback 
und der Task läuft ständig ohne Interruptfunktion.

Wenn ich den Interrupt anstatt eines Zeichens über UART mit einem 
Externen Interrupt mache funktioniert das kurzzeitige unterbrechen des 
Tasks.

Weiß wer warum das mit UART_IT nicht funktioniert?

von PittyJ (Gast)


Lesenswert?

Ich habe vor Wochen das gleiche gemacht, war nicht so leicht.
Die Sourcen sind auf der Arbeit, komme ich jetzt am WE nicht ran.

Es muss der Interrupt für UartXX aktiviert werden.
In der Interrupt-Routine, muss dann der richtige Callback-Handler 
angesprungen werden.
Die Callbacks müssen global aktiviert werden, das ist so ein #define in 
einen STM Include.
Der eigene Callback muss dann auch in dem Uart-Handle noch aktiviert 
werden.

Dann kam auch ein Zeichen in meinem Callback an.

von Harry L. (mysth)


Lesenswert?

Roman R. schrieb:
> void monitoringFunction(void *argument)
> {
>   printf("Test\n");
>   osDelay(1000);
> }

Versuchs mal so:
1
void monitoringFunction(void *argument)
2
{
3
  while(1)
4
    {
5
      printf("Test\n");
6
      osDelay(1000);
7
    }
8
}

von Roman R. (reiter86)


Lesenswert?

F..k, dass habe ich in der Angabe vergessen..... Thx für den Hinweis

von Johnny B. (johnnyb)


Lesenswert?

Roman R. schrieb:
> Callback:
> void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
> {
>   printf("CpltCallback\n");
>   HAL_UART_Receive_IT(&huart2, RxBuffer, RxBuffer_SIZE);
> }

HAL_UART_RxCpltCallback() wird von einem Interrupt aufgerufen, das 
heisst, dort drin sollte man es unbedingt vermeiden, eine zeitraubende 
printf() funktion aufzurufen, ansonsten kann es megamässige Probleme 
geben.
Am besten für das printf einen eigenen FreeRTOS Task aufsetzen und darin 
beispielsweise auf eine Semaphore warten (xSemaphoreTake), die man im 
HAL_UART_RxCpltCallback freigibt (xSemaphoreGiveFromISR).

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.