Forum: Mikrocontroller und Digitale Elektronik FreeRTOS RS232 über DMA "Ruckler"


von Fragenhagel (Gast)


Lesenswert?

Hallo zusammen,

über UART und einem RS232 Transceiver sende ich Messdaten zur Kontrolle 
an den Rechner. Das ganze passiert mit 1KHz bei 115200 Baud und 
funktioniert soweit auch einwandfrei.

Da der µC (STM32G081KBT)einige Aufgaben paralell erledigen soll habe ich 
mich dafür entschieden FreeRTOS zu verwenden. In einem Task mit höchster 
Priorität (REALTIME 7) sendet der Controller jede Millisekunde die Daten 
raus.

Jetzt zum Problem:
Wie im Titel zu lesen "ruckelt" es dabei, was so viel heißen soll, dass 
die Daten im Terminal immer nur etwa sekündlich ankommen. Es kommen 
quasi sekündlich alle Daten mit einem Schwall an. Da ich einen 
RS232-USB-Transceiver verwende dachte ich erst, dass dieser vielleicht 
zwischenpuffert und nur sekündlich Daten rausschickt. Auf einem anderen 
Controller ohne FreeRTOS kommen die Daten allerdings im Terminal über 
den selben RS232-USB-Transceiver in einem kontinuierlichen Fluss an.

Hat jemand eine Vorstellung darüber woran das liegen könnte? Die 
UART-Puffer schicke ich per DMA raus und der zugehörige Task hat die 
höchste Priorität weshalb ja eigentlich nichts dafür sprechen würde, 
dass die Daten nicht kontinuierlich rausgeschickt werden können.

Vielen Dank schonmal für eure Hilfe :)

Das ganze habe ich sogar auch über einen MUX versucht für andere Tasks 
zu blockieren. Die Funktion SMP_STM32_Send(SMP_HandleTypeDef CON) 
schickt die Messdaten über eine konfigurierte Verbindung (im 
SMP_HandleTypeDef agespeichert) per UART-DMA raus.
Hier der Task:
1
void StartCON1_Task(void *argument)
2
{
3
  /* USER CODE BEGIN StartCON1_Task */
4
  /* Infinite loop */
5
  for(;;)
6
  {
7
  osMutexAcquire(DoNotDisturbMUXHandle, 1000);
8
  SMP_STM32_send(&con1);
9
  osMutexRelease(DoNotDisturbMUXHandle);
10
    osDelay(1);
11
  }
12
  /* USER CODE END StartCON1_Task */
13
}

von CK (Gast)


Lesenswert?

woher kommt osMutexAcquire
das ist keine Funktion von FreeRTOS

hat das einen Rückgabewert den man überprüfen kann, anscheinend 
übergibst du ihm einen Timeout von 1000ms

Und du willst einen Task jede Millisekunde ausführen, der Scheduler von 
FreeRTOS läuft doch selbst nur mit einem Takt von 1KHz

von Fragenhagel (Gast)


Lesenswert?

CK schrieb:
> woher kommt osMutexAcquire
> das ist keine Funktion von FreeRTOS
>
> hat das einen Rückgabewert den man überprüfen kann, anscheinend
> übergibst du ihm einen Timeout von 1000ms
>
> Und du willst einen Task jede Millisekunde ausführen, der Scheduler von
> FreeRTOS läuft doch selbst nur mit einem Takt von 1KHz

Auf den STM32 läuft die CMSIS V2 Version von FreeRTOS. osMutexAcquire() 
entspricht einem xSemaphoreTake im standart FreeRTOS.
Hier mal zum nachlesen:
https://arm-software.github.io/CMSIS_5/RTOS2/html/group__CMSIS__RTOS__MutexMgmt.html

genau der Thread wartet theoretisch bis zu 1000ms, was aber eigentlich 
nicht der Fall sein soll. Mit und ohne MUX hakt es aber sowieso, weshalb 
ich nicht denke, dass dort der Fehler liegt.

Da hast du natürlich recht, das der Sheduler nur mit 1KHz läuft. 
Eventuell muss ich den schneller laufen lassen oder ich lasse das Senden 
der Daten über einen Timer triggern.

von 900ss (900ss)


Lesenswert?

Fragenhagel schrieb:
> genau der Thread wartet theoretisch bis zu 1000ms, was aber eigentlich
> nicht der Fall sein soll.

Was ich gelernt habe: Alles was du nicht geprüft hast, weißt du nicht :)

von Rolf M. (rmagnus)


Lesenswert?

Fragenhagel schrieb:
> genau der Thread wartet theoretisch bis zu 1000ms, was aber eigentlich
> nicht der Fall sein soll. Mit und ohne MUX hakt es aber sowieso, weshalb
> ich nicht denke, dass dort der Fehler liegt.

Aber wenn du sagst, dass die Daten nur einmal pro Sekunde gesendet 
werden und im sende-Thread zufällig mit einem Timeout von genau einer 
Sekunde gewartet wird, würde ich auf jeden Fall prüfen, ob es da nicht 
vielleicht einen Zusammenhang gibt. Sollte sich ja auch sehr leicht 
testen lassen.

> Da hast du natürlich recht, das der Sheduler nur mit 1KHz läuft.
> Eventuell muss ich den schneller laufen lassen oder ich lasse das Senden
> der Daten über einen Timer triggern.

Taskwechsel werden nicht nur im Timer-Tick durchgeführt, sondern in 
jeder Switching-ISR oder manuell mit einem Aufruf, der auf irgendwas 
wartet, so wie dein osDelay().

von Planloser (Gast)


Lesenswert?

Rolf M. schrieb:
> Taskwechsel werden nicht nur im Timer-Tick durchgeführt, sondern in
> jeder Switching-ISR oder manuell mit einem Aufruf, der auf irgendwas
> wartet, so wie dein osDelay().

Nö. Taskwechsel in FreeRTOS auf Cortex-M-MCUs werden nur im 
PendSV-Interrupt durchfeführt.
Im Systick z.B. wird der PendSV-Interrupt nur ausgelöst.

von Rolf M. (rmagnus)


Lesenswert?

Planloser schrieb:
> Rolf M. schrieb:
>> Taskwechsel werden nicht nur im Timer-Tick durchgeführt, sondern in
>> jeder Switching-ISR oder manuell mit einem Aufruf, der auf irgendwas
>> wartet, so wie dein osDelay().
>
> Nö. Taskwechsel in FreeRTOS auf Cortex-M-MCUs werden nur im
> PendSV-Interrupt durchfeführt.
> Im Systick z.B. wird der PendSV-Interrupt nur ausgelöst.

Hmm, ok, wie das dort implementiert ist, weiß ich nicht. Ich habe früher 
mal ein FreeRTOS auf einen ARM7TDMI portiert und dort alle wichtigen 
ISRs zu Switching-ISRs gemacht mit Scheduler-Aufruf. Und ist das dann 
tatsächlich so, dass eine Delay-Funktion oder ein Warten auf eine Queue 
einfach sinnlos CPU-Zeit verbrät, bis der nächste Tick kommt? Das klingt 
mir sehr ineffizient.

von Fragenhagel (Gast)


Lesenswert?

900ss D. schrieb:
> Fragenhagel schrieb:
>> genau der Thread wartet theoretisch bis zu 1000ms, was aber eigentlich
>> nicht der Fall sein soll.
>
> Was ich gelernt habe: Alles was du nicht geprüft hast, weißt du nicht :)

Ich rufe in einem anderen Programm die Sende-Funktion nun in der 
Callback-Funktion eines Timers auf (1KHz) und beobachte hier genau das 
selbe Verhalten. Eventuell ist es doch der USB Adapter...

von Fragenhagel (Gast)


Lesenswert?

Rolf M. schrieb:
> Hmm, ok, wie das dort implementiert ist, weiß ich nicht. Ich habe früher
> mal ein FreeRTOS auf einen ARM7TDMI portiert und dort alle wichtigen
> ISRs zu Switching-ISRs gemacht mit Scheduler-Aufruf. Und ist das dann
> tatsächlich so, dass eine Delay-Funktion oder ein Warten auf eine Queue
> einfach sinnlos CPU-Zeit verbrät, bis der nächste Tick kommt? Das klingt
> mir sehr ineffizient.

Kann ich mir so ehrlich gesagt auch nicht vorstellen. Das würde ja 
bedeuten, dass der MCU nur jede Millisekunde zwischen zwei Tasks 
wechseln könnte und somit quasi immer fast ausschließlich damit 
beschäftigt wäre darauf zu warten einen anderen Task ausführen zu 
können.

von 900ss (900ss)


Lesenswert?

Planloser schrieb:
> Nö. Taskwechsel in FreeRTOS auf Cortex-M-MCUs werden nur im
> PendSV-Interrupt durchfeführt.

Glaub ich auch nicht und es ist auch nicht die Regel bei RTOS. 
Wenigstens bei wartenden API-Calls wird wahrscheinlich auch die Task 
gewechselt. Und weshalb sollte das bei Cortex-M CPUs nur in dem Tick 
gemacht werden? Der Code auf Kernelebene unterscheidet sich eher nicht 
wenn eine andere Architektur im Spiel ist.

Edit: Ich hab das gerade mal recherchiert. Im Freertos-Forum wurde das 
von einem Freertos Kollegen bestätigt, der Kontext-Switch passiert auch 
in der API-Funktion.

: Bearbeitet durch User
von Planloser (Gast)


Lesenswert?

900ss D. schrieb:
> Planloser schrieb:
>> Nö. Taskwechsel in FreeRTOS auf Cortex-M-MCUs werden nur im
>> PendSV-Interrupt durchfeführt.
>
> Glaub ich auch nicht und es ist auch nicht die Regel bei RTOS.

Glauben gehört in die Kirche.

> Wenigstens bei wartenden API-Calls wird wahrscheinlich auch die Task
> gewechselt. Und weshalb sollte das bei Cortex-M CPUs nur in dem Tick
> gemacht werden?

Habe ich so gar nicht geschrieben.
Geschrieben habe ich, dass der Task-Wechsel nur im PendSV-Interrupt 
durchgeführt wird.

> Edit: Ich hab das gerade mal recherchiert. Im Freertos-Forum wurde das
> von einem Freertos Kollegen bestätigt, der Kontext-Switch passiert auch
> in der API-Funktion.

Tja, warum ist wohl OPENSOURCE so hilfreich?
Damit man nicht bei Recherchen inkompetente Kollegen fragen muss, die 
dann Blödsinn raushauen.

Daher hier für diejenigen, die - aus welchen Gründen auch immer - den 
Sourcecode nicht verstehen:
1
#define portYIELD()                               \
2
{                                        \
3
  /* Set a PendSV to request a context switch. */                \
4
  portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;                \
5
                                        \
6
  /* Barriers are normally not required but do ensure the code is completely  \
7
  within the specified behaviour for the architecture. */            \
8
  __asm volatile( "dsb" ::: "memory" );                    \
9
  __asm volatile( "isb" );                          \
10
}

portYIELD() wird von allen Funktionen wie den Queue-Funktionen, Delays, 
etc. aufgerufen, wenn ein Task-Wechsel vorgenommen werden soll. Das 
Posten der vielen Stellen spare ich mir, wer es nicht glaubt, sollte 
sich jemanden besorgen, der den C-Sourcecode lesen kann.

Also nochmal für die Unsinn-Schreiber hier:
Auf Cortex-M-MCUs findet der Taskwechsel in FreeRTOS nur im 
PendSV-Interrupt statt!

von Planloser (Gast)


Lesenswert?

Noch der Systick Interrupt:
1
void xPortSysTickHandler( void )
2
{
3
  /* The SysTick runs at the lowest interrupt priority, so when this interrupt
4
  executes all interrupts must be unmasked.  There is therefore no need to
5
  save and then restore the interrupt mask value as its value is already
6
  known. */
7
  portDISABLE_INTERRUPTS();
8
  {
9
    /* Increment the RTOS tick. */
10
    if( xTaskIncrementTick() != pdFALSE )
11
    {
12
      /* A context switch is required.  Context switching is performed in
13
      the PendSV interrupt.  Pend the PendSV interrupt. */
14
      portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
15
    }
16
  }
17
  portENABLE_INTERRUPTS();
18
}

von Adam P. (adamap)


Lesenswert?

Fragenhagel schrieb:
> Eventuell ist es doch der USB Adapter...

Was für einen hast du denn?
Und mit welchen Tool schneidest die empfangen Daten mit?

von Fragenhagel (Gast)


Lesenswert?

Adam P. schrieb:
> Was für einen hast du denn?
> Und mit welchen Tool schneidest die empfangen Daten mit?

So einer ist es:
https://de.rs-online.com/web/p/serielle-konverter-und-extender/7300158/?cm_mmc=DE-PLA-DS3A-_-google-_-CSS_DE_DE_Computertechnik_und_Peripherieger%C3%A4te_Whoop-_-(DE:Whoop%21)+Serielle+Konverter+und+Extender-_-7300158&matchtype=&aud-827186183886:pla-434530197084&gclid=EAIaIQobChMImvyVoqKF7wIVkcLtCh2E2QnJEAYYAiABEgICGPD_BwE&gclsrc=aw.ds

Ich habe ausprobiert:
-hterm
-tera term
-Python Scrip (PySerial)

Planloser schrieb:
> Also nochmal für die Unsinn-Schreiber hier:
> Auf Cortex-M-MCUs findet der Taskwechsel in FreeRTOS nur im
> PendSV-Interrupt statt!

Okay, also kann der Controller mit FreeRTOS nur jede millisekunde den 
Task wechseln, was ja bei mir zu Problemen führen wird, da ich stand 
jetzt zwei Tasks habe, die jede Milisekunde laufen sollen. Den Sheduler 
Takt kann ich nicht erhöhen, da ist in CubeMX 1KHz das Maximum. Macht 
das denn überhaupt sinn oder wie kann man das am elegantesten Lösen?

Werde mir die CMSIS FreeRTOS Doku auch nochmal genauer zu Gemüte führen.

von Jonas B. (jibi)


Lesenswert?

>Das ganze passiert mit 1KHz bei 115200 Baud und
>funktioniert soweit auch einwandfrei.

Sendest du mehr als 10 Byte am Stück?

von Johannes S. (Gast)


Lesenswert?

Fragenhagel schrieb:
> Okay, also kann der Controller mit FreeRTOS nur jede millisekunde den
> Task wechseln,

Nein, das schrieb Planloser nicht, sondern die Tasks wechseln im PendSV 
Int. Wichtig ist in den Tasks portYield oder Funktionen aufzurufen die 
Zeit abgegeben um anderen eine Chance zu geben.

von John Doe (Gast)


Lesenswert?

Fragenhagel schrieb:
> Okay, also kann der Controller mit FreeRTOS nur jede millisekunde den
> Task wechseln, was ja bei mir zu Problemen führen wird, da ich stand
> jetzt zwei Tasks habe, die jede Milisekunde laufen sollen. Den Sheduler
> Takt kann ich nicht erhöhen, da ist in CubeMX 1KHz das Maximum. Macht
> das denn überhaupt sinn oder wie kann man das am elegantesten Lösen?


Nein, in FreeRTOS wird halt nur der reine Taskwechsel ausschliesslich im 
PendSV-IRQ durchgeführt, also das "klassische" Sichern des TCB und 
Aktivieren des Neuen.
Den PendSV-IRQ triggern tut dann nicht nur der Systick, sondern jede 
API-Funktion, die das braucht. Also zum Beispiel, wenn man etwas aus 
einer Queue auslesen möchte und die noch leer ist, dann wird ein 
PendSV-IRQ über den Aufruf von taskYield() in der entsprechenden 
API-Funktion getriggert.
Ein vTaskDelay() triggert ebenso den PendSV-IRQ.
taskYield() selber braucht man übrigens nicht aufrufen. Es gibt übrigens 
gleich eine Reihe von taskYield-Funktionen (je nach Kontext ruft 
FreeRTOS eine andere auf).

Ich kann übrigens aus eigener Erfahrung jedem, der mehr mit FreeRTOS 
macht, raten, sich die Sources mal anzusehen. Bringt viel fürs 
Verständnis.
Am besten mit port.c anfangen, dann tasks.c. Den Rest dann nach Bedarf.
FreeRTOS ist wirklich überschaubar.

von Rolf M. (rmagnus)


Lesenswert?

Planloser schrieb:
> portYIELD() wird von allen Funktionen wie den Queue-Funktionen, Delays,
> etc. aufgerufen, wenn ein Task-Wechsel vorgenommen werden soll. Das
> Posten der vielen Stellen spare ich mir, wer es nicht glaubt, sollte
> sich jemanden besorgen, der den C-Sourcecode lesen kann.
>
> Also nochmal für die Unsinn-Schreiber hier:
> Auf Cortex-M-MCUs findet der Taskwechsel in FreeRTOS nur im
> PendSV-Interrupt statt!

Ach dir ging es nur um Wortklauberrei. Ob das jetzt über einen 
PendSV-Interrupt geht oder nicht, ist doch wurscht. Es ging darum, dass 
man das von verschiedenen Stellen aus antriggern kann und es nicht nur 
hart einmal alle Millisekunde einen Taskwechsel gibt, als Antwort auf 
diese Aussage:

Fragenhagel schrieb:
> Da hast du natürlich recht, das der Sheduler nur mit 1KHz läuft.
> Eventuell muss ich den schneller laufen lassen oder ich lasse das Senden
> der Daten über einen Timer triggern.

Oben nennst du dann genau die Sachen, die ich auch schon genannt hatte.

von 900ss (900ss)


Lesenswert?

Planloser schrieb:
> Also nochmal für die Unsinn-Schreiber hier

Ich weiß nicht weshalb du so aggressiv wirst, ich habe dich einfach 
falsch verstanden.

Deine Angabe oben ließ vermuten, daß der PendSV Interrupt nur vom 
Systick getriggert wird. Dass der auch von den API-Funktionen angestoßen 
wird, wußte ich nicht und hast du auch nicht geschrieben. Andere 
scheinen deine Aussage auch falsch verstanden zu haben.

Also stimmt die Aussage der Kollegen auch, API-Calls in den Kernel lösen 
gegebenenfalls Taskwechsel aus (über den PendSV IRQ).

So und jetzt beruhige dich wieder.
Ende OT..

von Jonas B. (jibi)


Lesenswert?

>In einem Task mit höchster
>Priorität (REALTIME 7) sendet der Controller jede Millisekunde die Daten
>raus.

Nochmal, wieviele Daten sind das??

von Fragenhagel (Gast)


Lesenswert?

Jonas B. schrieb:
>>In einem Task mit höchster
>>Priorität (REALTIME 7) sendet der Controller jede Millisekunde die Daten
>>raus.
>
> Nochmal, wieviele Daten sind das??

Jonas B. schrieb:
> Sendest du mehr als 10 Byte am Stück?

Es sind exakt 10 Bytes zwei 16Bit Variablen auf je 3Byte mit 
Byte-Kennung aufgeteilt und einem Delimitter zur Kennung eines Pakets 
(War hauptsächlich für die Python Implementation gedacht weil so bis zum 
Delimiter gelesen werden kann).

10Bytes sollten ja zeittechnisch kein Thema sein. Auf einem STM32F407 
läuft das Programm auch über FreeRTOS problemlos und sendet 
kontinuierlich, jedoch über den VCOM des ST-Links, da es sich dabei um 
ein DEV Board handelt.

von Fragenhagel (Gast)


Lesenswert?

John Doe schrieb:
> Nein, in FreeRTOS wird halt nur der reine Taskwechsel ausschliesslich im
> PendSV-IRQ durchgeführt, also das "klassische" Sichern des TCB und
> Aktivieren des Neuen.
> Den PendSV-IRQ triggern tut dann nicht nur der Systick, sondern jede
> API-Funktion, die das braucht. Also zum Beispiel, wenn man etwas aus
> einer Queue auslesen möchte und die noch leer ist, dann wird ein
> PendSV-IRQ über den Aufruf von taskYield() in der entsprechenden
> API-Funktion getriggert.
> Ein vTaskDelay() triggert ebenso den PendSV-IRQ.
> taskYield() selber braucht man übrigens nicht aufrufen. Es gibt übrigens
> gleich eine Reihe von taskYield-Funktionen (je nach Kontext ruft
> FreeRTOS eine andere auf).
>
> Ich kann übrigens aus eigener Erfahrung jedem, der mehr mit FreeRTOS
> macht, raten, sich die Sources mal anzusehen. Bringt viel fürs
> Verständnis.
> Am besten mit port.c anfangen, dann tasks.c. Den Rest dann nach Bedarf.
> FreeRTOS ist wirklich überschaubar.

Ich werde mir den Source-Code bei Zeiten mal (nach der Klausurenphase 
;)) genauer anschauen. Danke auf jeden Fall aber schonmal für die 
Erklärungen.

Gruß

von Fragenhagel (Gast)


Lesenswert?

Jonas B. schrieb:
> Nochmal, wieviele Daten sind das??

Mit einem anderen µC (STM32G031) hatte ich auch schon über UART/RS232 
auf die selbe Art und Weise Daten geschickt hatte. Da allerdings nur 
eine Variable, sprich 4Bytes mit 1KHz. Das kam auch kontinuierlich im 
Terminal über den USB-RS232-Adapter an.

Fragenhagel schrieb:
> Es sind exakt 10 Bytes

Mit dem Kopfrechnen klappts auch nicht mehr so gut. 2*3Bytes + 1Byte 
ergeben natürlich 7Byte...

von Rolf M. (rmagnus)


Lesenswert?

Fragenhagel schrieb:
> 10Bytes sollten ja zeittechnisch kein Thema sein.

Kein Thema ist übertrieben. Bei 115200 Baud liegt das Maximum bei 11 
Bytes.

von Fragenhagel (Gast)


Lesenswert?

Rolf M. schrieb:
> Kein Thema ist übertrieben. Bei 115200 Baud liegt das Maximum bei 11
> Bytes.

Ja gut, das stimmt natürlich wenn man davon ausgeht, dass ein Parity-Bit 
und 2 Stop-Bits mitgesendet werden. Mit der Baudrate könnte ich 
theoretisch aber auch mal versuchsweise hochgehen. Der USB-RS232 Wandler 
kann theoretisch bis 1MBaud. Ich weiß garnicht wo da die Grenze vom PC 
liegt aber 256000Baud sollten ja noch drin sein.

von Rolf M. (rmagnus)


Lesenswert?

Fragenhagel schrieb:
> Rolf M. schrieb:
>> Kein Thema ist übertrieben. Bei 115200 Baud liegt das Maximum bei 11
>> Bytes.
>
> Ja gut, das stimmt natürlich wenn man davon ausgeht, dass ein Parity-Bit
> und 2 Stop-Bits mitgesendet werden.

Nö. Damit bekommst du nur noch 9 Bytes drüber.
1 Startbit, 8 Datenbits, 1 Stopbit, macht 10 Bits pro Byte. Also 11.520 
Bytes pro Sekunde bzw. 11,52 Bytes pro Millisekunde.

von Jonas B. (jibi)


Lesenswert?

>Kein Thema ist übertrieben. Bei 115200 Baud liegt das Maximum bei 11
>Bytes.

Eben und das auch nur wenn sonst nichts anderes gemacht wird, du hast ja 
noch den Overhead from freertos.

>Mit der Baudrate könnte ich
>theoretisch aber auch mal versuchsweise hochgehen.

Das oder eben weniger senden, einfach mal zum Testen um den Fehler 
einzukreisen...

Gruß J

von Fragenhagel (Gast)


Lesenswert?

Jonas B. schrieb:
> Eben und das auch nur wenn sonst nichts anderes gemacht wird, du hast ja
> noch den Overhead from freertos.
>
>>Mit der Baudrate könnte ich
>>theoretisch aber auch mal versuchsweise hochgehen.
>
> Das oder eben weniger senden, einfach mal zum Testen um den Fehler
> einzukreisen...

Werde ich machen wenn ich wieder im Labor bin. Das wird leider erst 
nächste Woche wieder der Fall sein. Der F4 packt es ja problemlos aber 
klar der Taktet auch mehr als doppelt so schnell (64MHz -> 168MHz).

Rolf M. schrieb:
> Nö. Damit bekommst du nur noch 9 Bytes drüber.
> 1 Startbit, 8 Datenbits, 1 Stopbit, macht 10 Bits pro Byte. Also 11.520
> Bytes pro Sekunde bzw. 11,52 Bytes pro Millisekunde.

Da hast du natürlich recht. Keine Ahnung was da rechentechnisch in 
meinem Kopf gestern los war.

von 900ss (900ss)


Lesenswert?

Du könntest evtl. in den relevanten Funktionen ein Portpin wackeln und 
mit dem Scope ansehen. Dann siehst du das Timing und erkennst ob es 
eingehalten wird.

von Fragenhagel (Gast)


Lesenswert?

So ich habe es nun endlich wieder geschafft mich dem Problem zu widmen.

Ich habe die Baudrate mal auf 500.000 erhöht -> keine Änderung.

Jetzt wollte ich das ganze mal ohne FreeRTOS umsetzen und stoße dabei 
auf weitere Probleme. So wie es aussieht hat der SysTick einen weg. 
Lasse ich einfach nur ein leere Programm laufen in dem ich in der 
while-loop mittels HAL_Delay() und HAL_GPIO_TogglePin() jede Sekunde 
eine LED togglen möchte passiert nichts. Ohne Delay im Debugger lief das 
Programm Schritt für Schritt durch weshalb ich darauf geschlossen hatte 
das etwas mit dem SysTick nicht stimmt. Und tatsächlich, sobald ich TIM1 
als SysCLK Konfiguriere funktioniert das Programm und es wird anständig 
eine Sekunde gewartet. Leider schickt die UART immernoch "schwallartig" 
raus.

Den Chip hatte ich letze Woche noch gewechselt also kann es eigentlich 
kein defekter Chip sein. Oder beim Einlöten ist der selbe Fehler 
aufgetreten. Es ist kein externer Tacktgeber angeschlossen.

von Christian K. (the_kirsch)


Lesenswert?

Ich nutze weder CubeMX mit generierten Code noch HAL

Ich konfiguriere die Clock nach Datenblatt manuell.

Rufe dann die SystemCoreClockUpdate() aus der CMSIS auf
welches die SystemCoreClock-Variable setzt.

Dann setze ich den SysTick Interrupt z.b. auf 1ms
SysTick_Config(SystemCoreClock / 1000)
Das ist ebenfalls eine Funktion aus der CMSIS.


Alle Cortex-M CPUs haben einen extra Timer für den SysTick, sodass man 
keinen General-Purpose-Timer dafür opfern muss.

: Bearbeitet durch User
von Fragenhagel (Gast)


Lesenswert?

Christian K. schrieb:
> Alle Cortex-M CPUs haben einen extra Timer für den SysTick, sodass man
> keinen General-Purpose-Timer dafür opfern muss.

Das ist mir natürlich bewusst. Aus welchem Grund aber auch immer scheint 
dieser nicht richtig zu funktionieren. Bei der Konfiguration in CubeMX 
kann man eigentlich nichts falsch machen und ein Fehler ist mir bisher 
auch nicht aufgefallen.


Zum eigentlichen Thema:
Ich habe im Datenblatt des USB-RS232 Adapter herausgefunden, dass dieser 
tatsächlich default 4kB zwischen puffert. Er wenn dieser Puffer gefüllt 
oder ein Timeout erreicht ist, werden die Daten an den PC 
weitergeleitet. Das würde erklären warum "schwallartig" Daten 
reinkommen.
Leider konnte ich bisher noch nicht herausfinden wie man die Packetgröße 
ändert.
Irgendwie lässt sich das ganze wohl konfigurieren.

von Fragenhagel (Gast)


Lesenswert?

Das Problem ist gelöst.

Die Empfangs- und Sendebuffer lassen sich direkt im Windowstreiber 
konfigurieren.  Jetzt läuft alles butterweich :)

von 900ss (900ss)


Lesenswert?

Fragenhagel schrieb:
> Die Empfangs- und Sendebuffer lassen sich direkt im Windowstreiber
> konfigurieren

Immer das gleiche mit USB-Seriell Wandler. Die machen so oft Ärger.....

Aber schön dass du es gefunden hast.

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.