Bin dabei, unter FreeRTOS auf einem STM32F103C8T6 (blue pill) eine Anwendung zu schreiben, die neben einigen Analogeeinlesefunktionen auch zwei UARTs betreiben soll. Habe dazu eine Verständnisfrage zum UART global Interrupt. Versuche gerade, erst mal ein einfaches echo-Programm zum Laufen zu kriegen, was Zeichen vom UART Rx über eine ISR einliest und in einen Ringpuffer schreibt. Eine FreeRTOS Task schaut nach, ob im Input-Ringbuffer etwas drin ist. Wenn ja, schreibt sie das Zeichen in einen Output-Ringbuffer. Und eine zweite Task schaut nach, ob im Outputringbuffer etwas steht, was dann rausgeschrieben werden soll. Auch Interrupt gesteuert.
Jetzt gibt es ja den UART Global Interrupt, den man einschalten kann in der MX-Konfiguration.
Nun meine Frage zum Verständnis: ist es so, daß sich Rx und Tx den Interrupt teilen und man nachgucken muß, wer den Interrupt verursacht hat?
Die Interrupts haben erstmal nicht viel mit FreeRTOS zu tun, solange du die nicht zu hoch priorisierst.
Mein Demo (mit Echo wie gewünscht) startest du einfach am Anfang deines default-Task.
"huart2" musst du natürlich durch das Handle deines genutzten Uart ersetzen.
// End of Line Char (valid in string- and data-mode
10
11
// in raw-mode the callback is fired after any received byte.
Du hast die Bindestrich-Krankheit. In der englischen Sprache wird
der Bindestrich nur in (sehr) besonderen Fällen verwendet.
Beispiel: state-of-the-art programming
Da du englischsprachige Texte schreibst nehme ich an dass du dich
an englischsprachiche User wenden möchtest. Dann bitte keine
Deppen-Bindestriche.
Kommt es dir nicht in den Sinn, daß das Problem an ganz anderer Stelle
liegen könnte?
Mehr Details an Zusammenhängen wurden vom TO nicht bekannt
gegeben. Wenn du die Lösung des Problems kennst dann scheue
dich nicht davor zurück sie uns mitzuteilen.
Danke an Harry für den Verweis auf seine Routinen. Bevor ich das Faß aufmache, würde ich lieber die selbst produzierten Phänomene verstehen.
Ich habe jetzt wieder den Zusatnd mit einer FreeRTOS Task, in der ich nur gucke, ob ein Zeichen in der input Queue abgelegt wurde.
Außerdem habe ich noch mal einen vollen Build gemacht. Und da geht es plötzlich reproduzierbar, mehrmals hintereinander, daß ich den receive interrupt abfangen kann. Möglicherweise komme ich jetzt weiter.
Warum glaubst du, die LL-Funktionen zu benötigen?
Die brauchst du nur, wenn du ein paar Byte Flash sparen musst, oder Funktionalitäten abbilden musst, die mit der HAL sonst nicht erreichbar wären.
Normale UART-Funktionalität geht mit HAL genauso gut und ohne Performance-Einbussen.
Schnell noch nachgeschoben, die Frage: wo finde ich eine vollständige
Beschreibung der LL-Funktionen? Z.B.:
...
Google (Bsp. für F4xx):
HAL STM32F4xx Usermanual
HAL Manual habe ich.
Erstes Ergebnis.
Warum glaubst du, die LL-Funktionen zu benötigen?
Die brauchst du nur, wenn du ein paar Byte Flash sparen musst, oder
Funktionalitäten abbilden musst, die mit der HAL sonst nicht erreichbar
wären.
HAL hatte mich zuletzt genervt. Jemand schreibt auch im Rtos Forum, HAL und FreeRTOS zusammen sei keine gute Idee.
Darf man das als Beratungsresistenz einstufen dass du das immer
noch benutzt?
[/c]
Den Code habe ich mir nicht selber ausgedacht. Der wurde vom MX generiert. Hielt ich jetzt erst mal nicht für so vorrangig wichtig, den wegzulassen,
da ich ja zunächst das Problem mit dem garnicht abfangbaren IR hatte.
Letztlich bin ich noch nicht viel weiter in meiner Erkenntnis, daß ich nämlich den Einstieg in den USART1_IRQHandler mit einem in STM32CubeIDE gesetzten Breakpoint nicht abfangen kann (wenn FreeRTOS im Spiel ist).
Setze ich dort einen festverdrahteten BKPT ( __asm("bkpt"); ), so wird dieser getroffen.
Es könnte ja etwas mit BMP und GDB zu tun haben. Ob ich es mal mit einem echten STLINK-V2 versuchen sollte?
EDIT: bis auf weiteres hilft momentan, LL_USART_EnableIT_RXNE(USART1); in den Anfang der Task1 zu verlegen.
Letztlich bin ich noch nicht viel weiter in meiner Erkenntnis, daß ich
nämlich den Einstieg in den USART1_IRQHandler mit einem in STM32CubeIDE
gesetzten Breakpoint nicht abfangen kann
Für mich ergibt sich daraus einfach folgende Logik: Wenn man im
(von CubeMX generierten) IRQ Handler einen IRQ nicht abfangen kann
dann tritt der IRQ schlichtweg nicht auf. Das kann zwei Gründe haben:
Der IRQ wurde gar nicht aktiviert.
Der IRQ tritt nicht auf da das passende Ereignis nicht eingetreten ist
Der Dritte Grund ist nach wie vor (ich hatte das früher schon
erwähnt) dass der Code-Bereich vom Compiler so optimiert worden
ist dass ein Break dort nicht möglich ist.
Etwas ganz perverses ist mir noch eingefallen. Es könnte sein
dass irgendeine Instanz den Vektor auf den IRQ Handler umbiegt
und auf seine eigene Handler-Funktion zeigen lässt. Dies liesse
sich herausfinden indem man die IRQ-Tabelle im Falle des
Nicht-Abfangen-Könnens anschaut, dort muss man sehen können wo
der RXNE-Handler angesprungen wird.