poniedziałek, 11 września 2017

[30] STM32F4 - FreeRTOS - obsługa prostych zadań, mruganie diodami

Tym razem bardzo szybki post dotyczący systemu freeRTOS. W nim chciałbym przedstawić obsługę systemu FreeROTS, a dokładniej jednej części tzn. funkcji Task.

[Źródło: http://www.st.com/en/evaluation-tools/stm32f4discovery.html]

FreeRTOS


System FreeRTOS jest to system operacyjny czasu rzeczywistego. Daje on możliwość skorzystania z pięciu mechanizmów, które umożliwią komunikację pomiędzy różnymi zadaniami. W ich skład wchodzą semafory binarne, kolejki, semafory licznikowe, muteksy oraz muteksy rekurencjyjne. 

Semafory binarne służą do sterowania wykonywanym zadaniem. Oczywiście działa to tylko wtedy gdy semafor jest włączony. Są one wykorzystywane do synchronizacji zadań lub zadania i przerwania. W drugim przypadku czynność zostaje odblokowana gdy wystąpi przerwanie.

Drugim mechanizmem są kolejki. Wykorzystuje się je do wymiany informacji między zadaniami czy przerwaniami i zadaniami. Przeważnie stosuje się je jako bufory FIFO. Kolejka ma ustaloną wcześniej ilość elementów oraz rozmiar każdego z nich. Wszystkie parametry należy określić na etapie deklarowania kolejki. Jako argument przekazywane są kopie danych głównych. Możliwe jest także zastosowanie wskaźnika na element, którego wartość przekracza tą zdefiniowaną w kolejce.

System udostępnia także możliwość by po określonej ilości taktów przejść w stan zablokowania, jeśli dane nie pojawią się w kolejce bądź gdy znajduje się w niej za dużo elementów.

Kolejnym rodzajem są semafory licznikowe czyli połączenie kolejki i semafora binarnego. Stosuje się w programach które wymagają zliczania ilości wystąpień danego zdarzenia oraz jego przetworzenia.

Teraz pora na muteksy, które mają podobne działanie co semafory licznikowe z wyjątkiem posiadania systemu priorytetów. Stosuje się głównie w miejscach gdzie należy dzielić dostępny zasób sprzętowy

Program:


Efektem działania programu będzie mruganie diodami wbudowanymi w płytkę Discovery. Każda z nich będzie działała z różnym interwałem czasowym, który został dobrany na etapie kompilacji projektu.

  1. /* Include core modules */
  2. #include "stm32f4xx.h"
  3. #include "main.h"
  4. #include "freeRTOS.h"
  5. #include "freeRTOSConfig.h"
  6. #include "task.h"
  7. #include "system_stm32f4xx.h"
  8. void vApplicationIdleHook(void)
  9. {
  10. }
  11. void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
  12. {
  13. }
  14. void vApplicationTickHook(void)
  15. {
  16. }
  17. void vApplicationMallocFailedHook(void)
  18. {
  19. }
  20. void LED_Task(void* pParams)
  21. {
  22.  while(1)
  23.  {
  24.   GPIO_SetBits(GPIOD, GPIO_Pin_14);
  25.   vTaskDelay(300);
  26.   GPIO_ResetBits(GPIOD, GPIO_Pin_14);
  27.   vTaskDelay(300);
  28.  }
  29. }
  30. void LED_Task2(void* pParams)
  31. {
  32.  while(1)
  33.  {
  34.   GPIO_SetBits(GPIOD, GPIO_Pin_12);
  35.   vTaskDelay(500);
  36.   GPIO_ResetBits(GPIOD, GPIO_Pin_12);
  37.   vTaskDelay(500);
  38.  }
  39. }
  40. void LED_Task3(void* pParams)
  41. {
  42.  while(1)
  43.  {
  44.   GPIO_SetBits(GPIOD, GPIO_Pin_13);
  45.   vTaskDelay(800);
  46.   GPIO_ResetBits(GPIOD, GPIO_Pin_13);
  47.   vTaskDelay(800);
  48.  }
  49. }
  50. void LED_Task4(void* pParams)
  51. {
  52.  while(1)
  53.  {
  54.   GPIO_SetBits(GPIOD, GPIO_Pin_15);
  55.   vTaskDelay(1050);
  56.   GPIO_ResetBits(GPIOD, GPIO_Pin_15);
  57.   vTaskDelay(1050);
  58.  }
  59. }
  60. void LED_INIT(void)
  61. {
  62.  GPIO_InitTypeDef GPIO_InitDef;321
  63.  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  64.  GPIO_InitDef.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  65.  GPIO_InitDef.GPIO_OType = GPIO_OType_PP;
  66.  GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;
  67.  GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;
  68.  GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;
  69.  GPIO_Init(GPIOD, &GPIO_InitDef);
  70. }
  71. int main()
  72. {
  73.  SystemCoreClockUpdate();
  74.  SysTick_Config(SystemCoreClock/1000);
  75.  LED_INIT();
  76.  xTaskCreate(LED_Task, "LED_BLINK", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  77.  xTaskCreate(LED_Task2, "LED_BLINK", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  78.  xTaskCreate(LED_Task3, "LED_BLINK", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  79.  xTaskCreate(LED_Task4, "LED_BLINK", configMINIMAL_STACK_SIZE, NULL, 1, NULL);
  80.  vTaskStartScheduler();
  81.  while (1)
  82.  { }
  83. }

Bibliografia


http://ep.com.pl/files/2562.pdf
http://www.scienceprog.com/freertos-on-stm32/