Forum: Mikrocontroller und Digitale Elektronik CMSIS/FreeRTOS, Resume Task from ISR, CMSIS osThreadResume verwendet die xTaskResumeFromISR nicht, w


von seppel (Gast)


Lesenswert?

Hallo,

ich werdende einen STM32 mit der STM32CubeIDE und das darin 
konfigurierbare FreeRTOS. Um Daten aufzunehmen verwende ich einen 
I2CRead mit DMA-transfer und einen Interrupt um eine Mittelwertbildung 
zu machen.

HAL_TIM_PeriodElapsedCallback -> HAL_I2C_Mem_Read_DMA
HAL_I2C_MemRxCpltCallback -> "Avg-Function"/Lowpassfilter
"AvgCnt ==16" -> "Schedule a Task"

Nach 16 Mittelwerten möchte ich einen Task aktivieren(resume a suspended 
task)um Berechnungen zu machen. Das kann man bei FreeRTOS eigentlich mit 
xTaskResumeFromISR gemacht werden, aber das wird in der CMSIS 
Abstraktion osThreadResume nicht verwendet , man bekommt einen Fehler.
1.  osStatus_t osThreadResume (osThreadId_t thread_id) {
2.  TaskHandle_t hTask = (TaskHandle_t)thread_id;
3.  osStatus_t stat;
4.
5.  if (IS_IRQ()) {
6.  stat = osErrorISR;
7.  }
8.  else if (hTask == NULL) {
9.  stat = osErrorParameter;
10.  }
11.  else {
12.  stat = osOK;
13.  vTaskResume (hTask);
14.  }
15.
16.  return (stat);
17.  }
18.  #endif /* (configUSE_OS2_THREAD_SUSPEND_RESUME == 1) */

Warum ist das nicht in der CMSIS Implementierung so gelöst, bzw. was 
wäre die Empfehlung, es gibt sicher gute Gründe warum xTaskResumeFromISR 
in osThreadResume nicht verwendet wird ? Oder habe ich eine Funktion in 
CMSIS übersehen?

Vielen Dank.

Grüße, Seppel

von Johannes S. (Gast)


Lesenswert?

Das ist auch in der cmsis so dokumentiert, den Grund kenne ich aber auch 
nicht.
Für diese Aufgabe würde ich aber eher eine Queue oder Semaphore 
verwenden, das könnte billiger sein als suspend/resume.

von seppel (Gast)


Lesenswert?

Hallo,

eine queue verwende ich, aber der Task soll nicht permanent laufen bzw. 
die queue pollen. Gibt es eine Möglichkeit dass der Task auf die Queue 
wartet und aktiviert wird sobald Werte darin sind? Ansonsten fällt mir 
nur "Task-Delay", also zyklisches pollen auf, schlecht für die Echteit 
und auch wenig effizient.

xTaskResumeFromISR wurde in der CMSIS V2 entfernt, in den V1 war das 
implementiert.

Grüße, Seppel

von seppel (Gast)


Lesenswert?


von seppel (Gast)


Lesenswert?

P.S.2: Wozu man "portYield" oer "TaskYield" benötigt habe ich nicht 
verstanden. Wenn mir das jemand erklärt wäre ich sehr dankbar, die RTOSe 
die ich vorher kennengelernt habe hatten das nicht.

von MaNi (Gast)


Lesenswert?

Vorab, ich habe selbst noch nicht mit FreeRTOS gearbeitet.

seppel schrieb:
> Wozu man "portYield" oer "TaskYield" benötigt habe ich nicht verstanden.

Kommt auf deine Konfiguration an ob/was es macht:
https://www.freertos.org/a00020.html#taskYIELD

seppel schrieb:
> aber der Task soll nicht permanent laufen

Wenn ich das richtig verstehe könntest du deine Berechnungstask doch mit 
xTaskNotifyWait o.ä. schlafen legen:
https://www.freertos.org/xTaskNotifyWait.html

Sobald alle Werte vorhanden sind wirfst du sie wieder über ein Event 
(xTaskNotify / FromISR) an:
https://www.freertos.org/xTaskNotify.html
https://www.freertos.org/xTaskNotifyFromISR.html

von gfdgd (Gast)


Lesenswert?

seppel schrieb:
> eine queue verwende ich, aber der Task soll nicht permanent laufen bzw.
> die queue pollen. Gibt es eine Möglichkeit dass der Task auf die Queue
> wartet und aktiviert wird sobald Werte darin sind? Ansonsten fällt mir
> nur "Task-Delay", also zyklisches pollen auf, schlecht für die Echteit
> und auch wenig effizient.

geht

TaskNotification
if( ulTaskNotifyTake( pdFALSE, portMAX_DELAY  )==pdTRUE){
}


oder per Queue
if ( pdTRUE == xQueueReceive(Event_mbox,  event, portMAX_DELAY   ) )
{
}


Der Task steht solange nichts in der queue liegt oder ein notify kommt

von Johannes S. (Gast)


Lesenswert?

in der portablen CMSIS Version wären das dann die osMessageQueue 
Funktionen,
https://www.keil.com/pack/doc/CMSIS/RTOS2/html/group__CMSIS__RTOS__Message.html
Messwerte oder Messwerttupel wie Zeitstempel+Messwert kann man direkt in 
eine Queue werfen.
Bei größeren Strukturen würde viel kopiert, da kann man mit zwei Queues 
arbeiten. Eine wird zuerst mit Zeigern auf freie Blöcke gefüllt. Der 
Sender (ISR) holt dann aus dieser Q einen Zeiger, füllt den Block mit 
Daten und wirft den Zeiger dann in die andere Q. Der Empfänger blockiert 
an dieser bis Daten da sind, verarbeitet die und wirft den Zeiger dann 
wieder in die Q der freien Blöcke.

von seppel (Gast)


Lesenswert?

Hallo,

@MaNi: "Kommt auf deine Konfiguration an ob/was es macht: 
https://www.freertos.org/a00020.html#taskYIELD"; . Warum sollte man das 
RTOS nicht preemtive betreiben? Wenn es nicht preemtive betrieben wird, 
dann würde ich trotzdem immer erwarten dass die ISR abgearbeitet wird 
und nach dem Verlassen die lauffähigen Taks gescheduled werden, nicht 
von der ISR aus, denn darin werden in der Regel andere Interrupts 
blockiert, läuft mit hoher Prio,... und dann in einen niederprioren 
Task? Kommt mir merkwürdig vor.

@gfdgd: Schöner Vorschlag, wartet der Task mit "portMAX_DELAY" unendlich 
lange? Was bedeutet "port" bei "portMAX_DELAY", ich bin etwas irritiert 
was das bedeutet.

Vielen Dank für eure Hilfe.

Viele Grüße, Seppel

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.