Skocz do zawartości

Rzutowanie typu void na uint8_t


PaaaV1999

Pomocna odpowiedź

Hej, zajmuję się właśnie FreeRTOS'em na esp32-s3 devkitc-1 i chce stworzyć instancje funkcji aby można było ją wywoływać wielokrotnie w zależności od podanego argumentu.

#define RED 2
#define GREEN 44
#define YELLOW 1

typedef int taskProfiler;

taskProfiler REDLEDProfiler = 0;
taskProfiler GREENLEDProfiler = 0;
taskProfiler YELLOWLEDProfiler = 0;

const uint16_t *redLed = (uint16_t*)RED;
const uint16_t *greenLed = (uint16_t*)GREEN;
const uint16_t *yellowLed = (uint16_t*)YELLOW;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(2000);

  xTaskCreate(ledControllerTask, "RED LED Task", 8192, (void*)redLed, 1, NULL);
  xTaskCreate(ledControllerTask, "GREEN LED Task", 8192, (void*)greenLed, 1, NULL);
  xTaskCreate(ledControllerTask, "YELLOW LED Task", 8192, (void*)yellowLed, 1, NULL);

}

void ledControllerTask(void *pvParameters)
{
  pinMode(pvParameters, OUTPUT);
  while(1)
  {
    digitalWrite(pvParameters, digitalRead(pvParameters)^1);
    vTaskDelay(500);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

Przy próbie kompilacji pojawia się błąd:

exit status 1
invalid conversion from 'void*' to 'uint8_t' {aka 'unsigned char'} [-fpermissive]

Czy jest jakiś dobry sposób na castowanie tych typów zmiennych?

Link do komentarza
Share on other sites

Ten Twój kod jest bliski działania, w gruncie rzeczy, aczkolwiek poszedłeś o krok komplikacji za daleko. Typ całkowity można rzutować na void * i odwrotnie, więc jeżeli jedyne, co potrzebujesz przekazać, to liczba, to coś w stylu:

#define RED 2

...
  
void setup() {
  ...
  xTaskCreate(ledControllerTask, "RED LED Task", 8192, (void *)RED, 1, NULL);
  ...
}

void ledControllerTask(void *pvParameters)
{
  uintptr_t pin = (uintptr_t)pin;
  pinMode(pin, OUTPUT);
  ...
}

uintptr_t to taki typ całkowity, który jest w stanie pomieścić liczby wielkości wskaźnika. Teoretycznie można i na uint8_t rzutować, ale to może powodować ostrzeżenia kompilatora o rzutowaniu do potencjalnie za wąskiego typu.

A inna wersja, która jest bardziej uniwersalna, gdyby przyszło Ci do zadań inne typy przekazywać niż liczbę całkowitą:

uint8_t red = 2;
  
void setup() {
  ...
  xTaskCreate(ledControllerTask, "RED LED Task", 8192, &red, 1, NULL);
  ...
}

void ledControllerTask(void *pvParameters)
{
  uint8_t *pin = (uint8_t *)pvParameters;
  pinMode(*pin, OUTPUT);
  ...
}

Rzutowanie powyżej jest potrzebne w C++, w C nie. Jeżeli dodałbyś const, to wypadałoby wszędzie dodać, a w wywołaniu xTaskCreate rzutować jawnie na void *, bo C++ lubi tu pilnować. Ale nie znam środowiska, którego używasz.

I jeszcze drobna rzecz, co do stylu, zamiast:

while (1) {

rozważ:

for (;;) {

Nie wiem jakie są światowe statystyki, ale wydaje mi się bardziej klasyczne do pętli nieskończonej.

A o wskaźnikach to ewentualnie gdzieś coś poczytaj jeszcze. Ale nie wiem gdzie.

Edytowano przez trainee
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.