Forum: Mikrocontroller und Digitale Elektronik Problem mit xSemaphoreGiveFromISR()


von Moot S. (mootseeker)


Lesenswert?

Hallo Zusammen,

ich arbeitet momentan an einem STM32F446RE Projekt und verwende als 
Betriebssystem FreeRTOS. Bei FreeRTOS bin ich noch etwas neu dabei und 
möchte mir nun das Know How erarbeiten.

Mit dem Timer2 habe ich mir einen Interrupt erstellt welcher alle 10s 
kommt. Der Interrupt funktioniert soweit so gut (Getestet mit LED Pin 
toggeln).

Nun habe ich mir einen Event Task erstellt in dem das ganze 
Hauptprogramm nach dem Init der Peripherien laufen soll.
1
void event_handler_task(void *pvParameters)
2
{
3
  SemaphoreHandle_t init_synchronisation = *(SemaphoreHandle_t*) pvParameters;
4
5
  MX_TIM2_Init();                //Timer 2 init
6
  HAL_TIM_Base_Start_IT(&htim2); //Timer 2 start interrupt
7
8
  event_binary = xSemaphoreCreateBinary();
9
  configASSERT(event_binary);
10
11
  xSemaphoreGive(init_synchronisation);
12
13
  for (;;)
14
  {
15
    if (xSemaphoreTake(event_binary, portMAX_DELAY) == pdTRUE)
16
    {
17
      sprintf(debug_string, "We are in the Event Task!");
18
      debug_put_string(debug_string);
19
    }
20
21
    vTaskDelay(1000 / portTICK_RATE_MS);
22
  }
23
}

Die BinarySemaphore dazu habe ich Global im selben File erstellt:
1
static SemaphoreHandle_t event_binary = NULL;

Die Interrupt Funktion sieht so aus:
1
void TIM2_IRQHandler(void)
2
{
3
  static BaseType_t xHigherPriorityTaskWoken = pdFALSE;
4
5
  xSemaphoreGiveFromISR(event_binary, &xHigherPriorityTaskWoken);
6
7
    if( xHigherPriorityTaskWoken == pdTRUE)
8
    {
9
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken); 
10
    }
11
12
  HAL_TIM_IRQHandler(&htim2);
13
14
  HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_2);
15
}


Mein Problem ist nun, dass wenn ich das ganze Debugge bleibt der 
kontroller beim xSemaphoreGiveFromISR hängen. Der Code wird nur bis zu 
dieser Funktion ausgeführt und wenn ich den Debugger anhalte bin ich in 
folgender Funktion:
1
configASSERT( pxQueue );

Hinter dem configASSERT steckt eine Endlosschelife wenn der Wert der 
übergeben wird 0 ist.

Meine Frage nun, verwende ich die falsche Funktion oder habe ich sie 
falsch initialisiert?

von Markus F. (mfro)


Lesenswert?

Moot S. schrieb:
> Die BinarySemaphore dazu habe ich Global im selben File erstellt:
> static SemaphoreHandle_t event_binary = NULL;

Hast Du nicht.

Du hast lediglich eine Semaphore-Handle-Variable mit NULL initialisiert.

Da fehlt ein xSemaphoreCreateBinary() oder 
xSemaphoreCreateBinaryStatic()

Doku lesen! Lesen bildet ;)

von Moot S. (mootseeker)


Lesenswert?

Aber das Create habe ich im eventTask? reicht das da nicht?

Das habe ich ja nach gelesen und da steht das so als Beispiel:
1
#define LONG_TIME 0xffff
2
#define TICKS_TO_WAIT    10
3
4
SemaphoreHandle_t xSemaphore = NULL;
5
6
/* Repetitive task. */
7
void vATask( void * pvParameters )
8
{
9
    /* We are using the semaphore for synchronisation so we create a binary
10
    semaphore rather than a mutex.  We must make sure that the interrupt
11
    does not attempt to use the semaphore before it is created! */
12
    xSemaphore = xSemaphoreCreateBinary();
13
14
    for( ;; )
15
    {
16
        /* We want this task to run every 10 ticks of a timer.  The semaphore
17
        was created before this task was started.
18
19
        Block waiting for the semaphore to become available. */
20
        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
21
        {
22
            /* It is time to execute. */
23
24
            ...
25
26
            /* We have finished our task.  Return to the top of the loop where
27
            we will block on the semaphore until it is time to execute
28
            again.  Note when using the semaphore for synchronisation with an
29
            ISR in this manner there is no need to 'give' the semaphore
30
            back. */
31
        }
32
    }
33
}
34
35
/* Timer ISR */
36
void vTimerISR( void * pvParameters )
37
{
38
static unsigned char ucLocalTickCount = 0;
39
static signed BaseType_t xHigherPriorityTaskWoken;
40
41
    /* A timer tick has occurred. */
42
43
    ... Do other time functions.
44
45
    /* Is it time for vATask() to run? */
46
    xHigherPriorityTaskWoken = pdFALSE;
47
    ucLocalTickCount++;
48
    if( ucLocalTickCount >= TICKS_TO_WAIT )
49
    {
50
        /* Unblock the task by releasing the semaphore. */
51
        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
52
53
        /* Reset the count so we release the semaphore again in 10 ticks
54
        time. */
55
        ucLocalTickCount = 0;
56
    }
57
58
    /* If xHigherPriorityTaskWoken was set to true you
59
    we should yield.  The actual macro used here is
60
    port specific. */
61
    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
62
}

Und da ist das Create ja auch im Task???

von Moot S. (mootseeker)


Lesenswert?

Es funktioniert zwar nicht aber mir ist aufgefallen, dass ich die 
Semaphore erst nach dem Timer erstelle, das hat dazu geführt, dass beim 
Start des Interrupts die Semaphore noch nicht vorhanden war und er sich 
deswegen in der Endlosschleife aufgesetzt hat.

Nun habe ich noch ein Problem mit dem Take aber das sollte ich schaffen 
^^

von Max M. (maxmicr)


Lesenswert?

Markus F. schrieb:
> Hast Du nicht.

Lies doch wenigstens seinen Code zuerst...

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.