Forum: Mikrocontroller und Digitale Elektronik STM32F429i-Disco FreeRTOS Task wird nur einmal ausgeführt


von W. M. (muhh)


Lesenswert?

Hey Leute,

ich wollte mich mal mit RTOS auseinandersetzen und FreeRTOS für das 
STM32F429i-disco Board verwenden.

Dafür habe ich mir ein Projekt in Eclipse eingerichtet, welches mir 
fleißig Code ausspuckt, der auch funktioniert. Allerdings habe ich wie 
im Titel beschrieben das Problem, dass mein Task nur einmal ausgeführt 
wird. Im Projekt verwende ich die neusten HAL-Treiber von der ST 
Homepage (FW1.5).

Ich poste hier erstmal nur den Code der main.c, wenn Bedarf an weiteren 
Ausschnitten besteht, einfach Bescheid sagen :)

Bin ich nur zu doof die FreeRTOS API zu benutzen oder liegt es 
vielleicht doch an etwas anderem?
1
#include "main.h"
2
#include <stdint.h>
3
#include <stddef.h>
4
#include "core_cmFunc.h"
5
6
#include "FreeRTOS.h"
7
#include "task.h"
8
9
static void SystemClock_Config(void);
10
11
/* Private functions ---------------------------------------------------------*/
12
GPIO_InitTypeDef GPIOG_13;
13
14
void vTaskCode12( void * pvParameters )
15
{
16
  while(1)
17
  {
18
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
19
20
      vTaskDelay(500);
21
  }
22
}
23
24
25
/**
26
  * @brief  Main program
27
  * @param  None
28
  * @retval None
29
  */
30
int main(void)
31
{
32
  HAL_Init();  
33
  
34
  /* Configure the system clock to 180 MHz */
35
  SystemClock_Config();
36
37
38
  /* Configure LED3 and LED4 */
39
  __GPIOG_CLK_ENABLE();
40
41
  GPIOG_13.Mode = GPIO_MODE_OUTPUT_PP;
42
  GPIOG_13.Pin = GPIO_PIN_13;
43
  GPIOG_13.Pull = GPIO_NOPULL;
44
  GPIOG_13.Speed = GPIO_SPEED_FAST;
45
46
  HAL_GPIO_Init(GPIOG, &GPIOG_13);
47
  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
48
  
49
  xTaskCreate( vTaskCode12, "LED1", 512, NULL, 1, NULL );
50
  
51
  /* Start scheduler */
52
  vTaskStartScheduler();
53
54
  /* We should never get here as control is now taken by the scheduler */
55
  while(1)
56
  {
57
    HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
58
  }
59
}
60
61
static void SystemClock_Config(void)
62
{
63
  RCC_OscInitTypeDef RCC_OscInitStruct;
64
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
65
66
    __PWR_CLK_ENABLE();
67
68
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
69
70
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
71
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
72
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
73
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
74
    RCC_OscInitStruct.PLL.PLLM = 8;
75
    RCC_OscInitStruct.PLL.PLLN = 360;
76
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
77
    RCC_OscInitStruct.PLL.PLLQ = 4;
78
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
79
80
    HAL_PWREx_ActivateOverDrive();
81
82
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
83
                                |RCC_CLOCKTYPE_PCLK2;
84
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
85
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
86
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
87
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
88
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
89
}

Dank und LG Willy

von Leo B. (luigi)


Lesenswert?

Deine Fehlerbeschreibung ist doch recht oberflächlich.
Was genau passiert denn, was nicht?
Wo "hängt" das Programm?

Um deine Frage so wie sie ist zu beantworten, würde ich sagen:
Du rufst den Task einmal auf, also wird er einmal Ausgeführt. Was willst 
du mehr?

Ich vermute aber deine LED blinkt nicht wie gewollt. Da würde ich den 
Fehler bei vTaskDelay() suchen:
http://www.freertos.org/a00127.html
vielleicht das hier?
1
INCLUDE_vTaskDelay must be defined as 1 for this function to be available.

von W. M. (muhh)


Lesenswert?

Hallo Leo,

hier eine bisschen genauere Beschreibung:

Der Task "vTaskCode12" soll in 0,5s Abständen die LED3 (GPIOG Pin 13) 
toggeln.
Nach dem Initialisieren des Pin 13 des Port G setze ich die LED auf 
HIGH, sodass sie anfängt zu leuchten. Mit dem Task wird sie nun wieder 
ausgeschaltet und bleibt dann leider aus, obwohl sie ab nun im 500ms 
Takt blinken sollte.

Daher ist meine Vermutung, dass der Task nur einmal ausgeführt wird. Ich 
hatte überlegt, ob es vielleicht an irgendwelchen Interrupts bzw. 
falschen Prioritäten des NVIC zu tun hat... Hat sich bis jetzt aber noch 
nicht rausfinden lassen.

Leo B. schrieb:
> INCLUDE_vTaskDelay must be defined as 1 for this function to be
> available.

Leider steht genau in dieser Zeile eine 1, schön wär's gewesen :)

von Jan K. (jan_k)


Lesenswert?

Toggle pin funktioniert?
Wie wäre es mal mit einem break point in der task?
Der Inhalt in deiner main while Schleife wird nie ausgeführt.

von Matthias N. (matt90)


Lesenswert?

Hallo,

wenn du die "neue" STM HAL nimmst solltest du auch die hierfür 
bereitgestellten Befehle verwenden.

Definition und erstellen des tasks über STM HAL:
1
    osThreadDef(User_thread, StartThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
2
    osThreadDef(CheckButton_thread, CheckButtonThread, osPriorityNormal, 0, configMINIMAL_STACK_SIZE);
3
    osThreadCreate(osThread(User_thread), NULL);
4
    osThreadCreate(osThread(CheckButton_thread), NULL);
5
    osKernelStart(NULL, NULL);

Beispiel hierfür Wäre:
https://github.com/dobromyslov/stm32f0-cmsis-cube-hal-freertos-template/blob/master/src/main.c

Grüße

MaTT

von Fritz (Gast)


Lesenswert?

W. M. schrieb:
> /* We should never get here as control is now taken by the scheduler
> */
>   while(1)
>   {
>     HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
>   }

Steht zwar wahrscheinlich so im Template, aber wer weiss obs auch 
stimmt. Da würde der Pin immer gesetzt und nur einige Bruchteile von us 
von der Task getoggelt!

kommentiere HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET); aus und 
versuche es nochmals.

von Jupp (Gast)


Lesenswert?

Un ich finde es immer spannend, wenn so ein Thread mitten drinn beendet 
wird. Jetzt hat "Jeder" der mal recherchiert, gar nichts davon.
Zum anderen wird nur eingeschaltet uns sonst nix.
Mit einem JTAG/SWD kann man schon bei nutzung von FreeRTOS die laufenden 
Threads und deren Status anzeigen lassen. In emBits und Keil's µVision 
geht sowas sehr gut. In anderen IDE's gibt es sowas auch. Da muss man 
also nicht raten oder vermuten sondern prüfen und tracen.

von Frank (Gast)


Lesenswert?

Um das Thema mal abzuschließen:
Ich stand gerade vor dem selben Problem. Leider sieht man vor lauter 
Wrappern/StdLib/HAL/Präsidentenwahl/etc.pp. gar nicht mehr durch.
Gerade die cmsis_os.h finde ich nicht hilfreich, wenn man FreeRTOS 
lernen bzw. nutzen möchte.

Lange Rede, kurzer Sinn: vTaskDelay funktioniert nur, wenn 
xPortSysTickHandler aufgerufen wird.
Das wiederum passiert im SysTick_Handler, aber nur, wenn dort 
USE_RTOS_SYSTICK definiert ist.

Diese Symbol kann man in Eclipse (4.6.1) unter Project -> Properties -> 
C/C++ General -> Paths and Symbols -> Symbols -> Add... -> Name: 
USE_RTOS_SYSTICK
definieren.

Hier ist ein Minimalbeispiel, getestet mit Eclipse, dem openSTM32-Plugin 
und einem Nucleo-F446ZE:
1
#include "stm32f4xx.h"
2
#include "stm32f4xx_nucleo_144.h"
3
4
// don't forget to define USE_RTOS_SYSTICK globally!
5
// Wichitg! USE_RTOS_SYSTICK muss global definiert werden!
6
// (damit wird über osSystickHandler -> xPortSysTickHandler von freeRTOS aufgerufen)
7
8
// Wrapper von ARM/CMSIS einbinden (bindet wiederum freertos.h ein)
9
#include <cmsis_os.h>
10
11
12
// user defines
13
// Nutzerdefinitionen
14
#define LED_PIN        GPIO_PIN_0
15
#define LED_PORT       GPIOB
16
17
18
void blinky_task( void* pvParameters)
19
{
20
  for(;;)
21
  {
22
    vTaskDelay( 1000 / portTICK_PERIOD_MS);
23
    HAL_GPIO_WritePin( LED_PORT, LED_PIN, GPIO_PIN_SET);
24
25
    vTaskDelay( 200  / portTICK_PERIOD_MS);
26
    HAL_GPIO_WritePin( LED_PORT, LED_PIN, GPIO_PIN_RESET);
27
  }
28
}
29
30
31
int main(void)
32
{
33
  //
34
  // STM32-HAL-spezifisch
35
  //
36
  // Takt einstellen, SysTick aktivieren
37
  HAL_Init();
38
39
  // GPIO mit Takt versorgen
40
  __HAL_RCC_GPIOB_CLK_ENABLE();
41
42
  // IO-Port für LED konfigurieren
43
  GPIO_InitTypeDef GPIO_InitStructure;
44
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
45
  GPIO_InitStructure.Pin  = LED_PIN;
46
  HAL_GPIO_Init( LED_PORT, &GPIO_InitStructure);
47
48
49
  //
50
  // freeRTOS-spezifisch
51
  //
52
  // Task erzeugen
53
  xTaskCreate( blinky_task, (char*) "blinky", configMINIMAL_STACK_SIZE, 0, 1, 0);
54
  // Scheduler ausführen
55
  vTaskStartScheduler();
56
}

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.