Sterowanie zadaniami w freeRTOS na ESP32

Pozostałe układy mikrokontrolerów, układy peryferyjne i inne, nie mieszczące się w powyższych kategoriach.
Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Szybkie pytanie freeRTOS

Postautor: dambo » wtorek 14 mar 2017, 18:00

Może softwarowym timerem z FreeRTOSa? http://www.freertos.org/RTOS-software-timer.html
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: Szybkie pytanie freeRTOS

Postautor: inż.wielki » wtorek 14 mar 2017, 19:00

Jeżeli chcesz żeby to było wywoływane cyklicznie, nie musisz do tego angażować task'u, możesz zrobić to w software'owego timer'a. Jeżeli zaś chcesz faktycznie używać task'u, to zrób w nim pętlę nieskończoną oraz użyj

Kod: Zaznacz cały

vTaskDelay(x);


wtedy możesz zrobić tak

Kod: Zaznacz cały

while(1)
{
   if(cnt % 10) //co 10ms
   {
      //do something;
   }
   cnt++;
   vTaskDelay(1);
   
}

To jest taki sposób lekko chałupniczny ale jak najbardziej działa i zdradzę że sam często go wykorzystuje. Do tego jeżeli masz dobrze ustawiony timer to możesz dosyć dokładnie ustawić czas w jakim ma się wykonywać.

Pozdrawiam

Edit:

Nie używaj na końcu task'u

Kod: Zaznacz cały

   vTaskDelete(NULL);

to zabije Ci task i musisz go ponownie uruchamiać :)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: dambo » wtorek 14 mar 2017, 19:23

jeszcze inna opcja podobna do powyższej - używasz semafora. Odpalasz go co określony czas, czy to w przerwaniu, czy to w softtimerze.
Też mi się wydaje, ze lepiej nie używać vTaskDelete, tylko je blokować. chociaż wszystko zależy od potrzeby
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: inż.wielki » wtorek 14 mar 2017, 19:28

Przerobiony kod, ja zamiennie używam jednego albo drugiego i nie widzę żadnych problemów. Jedno i drugie jest zgodne "ze sztuką" pisania z wykorzystaniem RTOS'a

Kod: Zaznacz cały

#include <driver/gpio.h>
#include <driver/spi_master.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdio.h>
#include <string.h>
#include <u8g2.h>

#include "sdkconfig.h"
#include "u8g2_esp32_hal.h"

// CLK - GPIO14
//#define PIN_CLK 14

// MOSI - GPIO 13
//#define PIN_MOSI 13

// RESET - GPIO 26
//#define PIN_RESET 26

// DC - GPIO 27
//#define PIN_DC 27

// CS - GPIO 15
//#define PIN_CS 15

#define PIN_SDA 21
#define PIN_SCL 22


static const char *TAG = "ssd1306";
uint8_t i=0;
static TimerHandle_t esp32_timer_handle = NULL;

void error()
{
   while(1);
}

void esp32_code( TimerHandle_t xTimer )

   u8g2_esp32_hal_t u8g2_esp32_hal = U8G2_ESP32_HAL_DEFAULT;
   u8g2_esp32_hal.sda   = PIN_SDA;
   u8g2_esp32_hal.scl  = PIN_SCL;
   u8g2_esp32_hal_init(u8g2_esp32_hal);
   int cnt = 0;
   

   u8g2_t u8g2; // a structure which will contain all the data for one display
   u8g2_Setup_ssd1306_128x32_univision_f(
      &u8g2,
      U8G2_R0,
      //u8x8_byte_sw_i2c,
      u8g2_esp32_msg_i2c_cb,
      u8g2_esp32_msg_i2c_and_delay_cb);  // init u8g2 structure
   u8x8_SetI2CAddress(&u8g2.u8x8,0x78);

   ESP_LOGI(TAG, "u8g2_InitDisplay");
   u8g2_InitDisplay(&u8g2); // send init sequence to the display, display is in sleep mode after this,

   ESP_LOGI(TAG, "u8g2_SetPowerSave");
   u8g2_SetPowerSave(&u8g2, 0); // wake up display
   ESP_LOGI(TAG, "u8g2_ClearBuffer");
   u8g2_ClearBuffer(&u8g2);
   ESP_LOGI(TAG, "u8g2_DrawBox");

   u8g2_DrawBox(&u8g2, 0, 26, i,6);
   u8g2_DrawFrame(&u8g2, 0,26,100,6);
   i++;
   if(i==100)i=0;

   ESP_LOGI(TAG, "u8g2_SetFont");
    u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr);
   ESP_LOGI(TAG, "u8g2_DrawStr");
    u8g2_DrawStr(&u8g2, 2,17,"Siema Rez!");
   ESP_LOGI(TAG, "u8g2_SendBuffer");
   u8g2_SendBuffer(&u8g2);

   ESP_LOGI(TAG, "All done!");
   
}

void task_test_SSD1306(void *ignore) {
 
   while(1)
   {
      if(cnt % 10) //co 10ms uruchamia procedure
      {
            esp32_code();
      }
      vTaskDelay(1)
      cnt++;
   }
}

void main() {
   
   //Pierwszy sposob
   esp32_timer_handle = xTimerCreate("esp32", 10, pdTRUE, NULL, esp32_code);
   
   if(xTimerStart( esp32_timer_handle, NULL))
   {
      error();
   }
   
   //drugi sposob
    xTaskCreate(&task_test_SSD1306, "task_test_SSD1306", 8192, NULL, 5, NULL);
   
   vTaskStartScheduler();
   
   for(;;);
}



Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: dambo » wtorek 14 mar 2017, 20:21

a może zamiast licznika cnt dać większego delaya? to tez się chyba sprawdzi?
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: inż.wielki » wtorek 14 mar 2017, 21:54

dambo pisze:a może zamiast licznika cnt dać większego delaya? to tez się chyba sprawdzi?


wtedy blokujesz całą pętlę, vTaskDelay niestety nie zwalnia tasku na ten czas a jedynie mrozi cały kod na podaną wartość czasu. No a poza tym można wtedy spokojnie sobie coś jeszcze wrzucić w tą pętlę. [subiektywna_opinia] To jest najbezpieczniejszy sposób według mnie [/subiektywna_opinia] :D

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: dambo » wtorek 14 mar 2017, 23:02

trochę nie rozumiem, sumarycznie sprowadzi się to do tego, że duży delay będzie rozbity na mniejsze. Jeśli mamy do zrobienia tylko jedną funkcję to chyba nie ma to różnicy?

Mechanizmy z % to jest nic innego jak zrobienie swojego taska, który jest timerem, oczywiście będzie to działać, ale takie coś już mamy gotowe we FreeRTOSie - czemu tego nie wykorzystać (tzn dokładnie tego mechanizmu z xTimerCreate co podałeś)?

Sam mam mętlik w głowie co do FreeRTOSa, żeby się poprawnie na to przestawić z wcześniejszego podejścia, bo ciągle mam tendencje do robienia czegoś w 100% niezgodnego z FRTOSem stąd pytania
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: inż.wielki » wtorek 14 mar 2017, 23:18

Ponieważ, jeżeli się nie mylę, użycie vTaskDelay z czasem większym niż 1ms, nie zamrozi nam proca na aż tak długi czas. Jeżeli dasz mu vTaskDelay(200) to przez 200ms cały procek będzie czekał aż skończy się ten "dilej" a potem dopiero spowoduje przełączenie na inny task, w moim rozwiązniu, wszystkie inne taski, które będą tam latać będą się normalnie wykonywać a kod, który jest w funkcji esp32 zostanie wykonany tylko co 10ms.

Jeżeli jednak, okaże się że vTaskDelay (nie pamiętam dokładnie) zamraża jedynie task, a nie cały procesor, wtedy Twoje jak i moje podejście będzie jak najbardziej poprawne :)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: dambo » środa 15 mar 2017, 12:07

vTaskDelay blokuje tylko wątek, więc można wykorzystać zarówno jeden długi delay jak i kilka krótkich.
Można jeszcze wykorzystać vTaskDelayUntil.
Z fajnych materiałów na temat Frtosa polecam jeszcze:
http://www.ue.eti.pg.gda.pl/~bpa/pusoc/ ... SOC5LP.pdf
http://www.socialledge.com/sjsu/index.p ... S_Tutorial
http://foka.ise.pw.edu.pl/MARM/freeRTOS.pdf

Edit:
tutaj fajny blog z ESP32 i Frtosem:
http://blog.pawelszabaciuk.pl/
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
inż.wielki
User
User
Posty: 307
Rejestracja: niedziela 20 gru 2015, 23:11

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: inż.wielki » środa 15 mar 2017, 16:28

dambo pisze:vTaskDelay blokuje tylko wątek, więc można wykorzystać zarówno jeden długi delay jak i kilka krótkich.


No widzisz a ja bym sobie dał rękę uciąć że blokuje wszystko. W takim wypadku, podejście moje jest dobre, jeżeli chcesz w tym tasku wykonywać jakieś inne czynności, podejście dambo jest dobre, jeżeli chcesz zoptymalizować działania tego task'a tylko do tego zadania :)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Sterowanie zadaniami w freeRTOS na ESP32

Postautor: dambo » środa 15 mar 2017, 16:33

dokładnie :)
Nowy blog o tematyce embedded -> https://www.embedownik.pl/


Wróć do „Inne mikroklocki, również peryferyjne”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 14 gości