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
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.
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
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.
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
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.
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