Skip to content

FreeRTOS blink example

bdani edited this page Apr 16, 2017 · 4 revisions

Ha sikeresen feltelepítettük a fejlesztőkörnyezetet, és le tudtuk fordítani az üres projektet, akkor nekiláthatunk tartalommal megtölteni. Először egy egyszerű led-villogtató alkalmazást mutatunk be UART kommunikációval, majd kiegészítjük PMW generálással, amivel később a quadcopter motorjait tudjuk vezérleni. A projekt konfigurálása során beállítottuk, hogy a konfigurátor állítsa be nekünk a FreeRTOS-t. Ez egy ingyenes, beágyazott rendszerekben előszeretettel használt operációs rendszer. Segítségével task-okat hozhatunk létre, akár csak a tanfolyamon használt NXT-n, és ezeket az operációs rendszer felváltva, kvázi párhuzamosan futtatja, vagy a megadott időzítésekkel ütemezi. Az operációs rendszer tehát megkönnyíti a programozás menetét, illetve biztonságosabbá teszi programunkat. A FreeRTOS-nek saját függvénykönyvtára van, melyek segítségével létrehozhatunk a task-okokat, ütemezhetjük, vagy kinyírhatjuk azokat. A példák során megismerkedünk ezen függvények használatával. Ezen kívül szükségünk van az STM HAL (Hardware Abstraction Layer) ismeretére. Ez szintén egy függvénykönyvtár mellyel a mikrokontroller perifériáit (GPIO, UART, PWM, I2C, TIMER) kezelhetjük. Kezdetben bonyolultnak tűnhetnek, de ha az alapokkal megismerkedtünk később sokkal könnyebb a fejlesztés menete.

A kiindulási alapunk

A Cube legenerálta nekünk a beállításainknak megfelelő kezdeti kódot. Ez remélhetőleg mindenkinek úgy néz ki, mint itt a repo-ban. Minket most főleg az Src/main.c file fog érdekelni. Mint láthatjuk egy elég terjedelmes kódot generált le a program. Ebben főként a perifériákat inicializálja, valamint felkonfigurálja az OS-t. Minden perifériának külön inicializáló függvénye van, melyeknek az implementációja a kód végén található. Ami most számunkra érdekes, az az operációs rendszer függvényei. A kód futása a megszokott main()-ben kezdődik. Itt találhatjuk a példa task inicializáló sorait:

osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

Ez inicializál egy task-ot defaultTask néven, Normál prioritással. A task-ot egy függvény fogja megvalósítani, amit StartDefaultTask néven implementálunk (ahhoz hogy itt ne kapjunk hibát, a függvényt korábban dekraláni kell). Ezután elindítja az ütemezőt osKernelStart();, ami vált a task-ok között. Most csak egy task-unk lesz, így az ütemező valójában nem fog váltogatni, de ettől még el kell indítani, hogy működjönk a program. Ettől a ponttól fogva az ütemező dönti el, hogy mi fusson, és soha nem tér vissza a fent meghívott függvény. Már csak implementálunk kell a task-ot jelentő függvényt. Ezt már a kód végén el is kezdte nekünk a Cube. Keressük meg a következő részt:

void StartDefaultTask(void const * argument)
{

  /* USER CODE BEGIN 5 */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END 5 */ 
}

A task-oknak mindig végtelen ciklust kell tartalmazniuk, magától az ütemező nem ciklikusan hajtja végre a programot. Itt megírhatjuk a villogtató programot. Most lesz szükségünk a korábban említett HAL könyvtárra. Ennek a megfelelő elemei már include-olva vannak, ha az eddigiek alapján készítettük el a projektet. A GPIO (digitális ki/bement) kezelésére az alábbi függvényeink vannak:

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

Nekünk most a HAL_GPIO_TogglePin függvényre lesz szükségünk. A teljes dokumentációt itt találjuk. Így a villogtató ciklus így néz ki (a define-okat is a Cube hozta létre):

  for(;;)
  {
	HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
        osDelay(500);
  }
Clone this wiki locally