XCreateTask with params (newbie)

azz-zza wrote on Thursday, September 12, 2019:

Hello,
attempting to pass parameters to xTaskCreate is not working well for me .
As a reference i use https://embetronicx.com/tutorials/rtos/freertos/freertos-lpc2148-tutorial-task-creation-with-parameters/

the simplified code is:

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"

#define BLINK_GPIO GPIO_NUM_2

extern "C"
{
    void app_main(void);
}

void hello_task(void *pvParameter)
{
    char *p;
    p = (char *)pvParameter;
        printf(p);
}


void app_main(void)
{
   xTaskCreate(hello_task, "hello_task", 2048, "1", 5, NULL, NULL);
 
}

and it failes with :

Processing esp32doit-devkit-v1 (platform: espressif32; board: esp32doit-devkit-v1; framework: espidf)
--------------------------------------------------------------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif32/esp32doit-devkit-v1.html
PLATFORM: Espressif 32 1.9.0 > DOIT ESP32 DEVKIT V1
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
DEBUG: Current (esp-prog) External (esp-prog, iot-bus-jtag, jlink, minimodule, olimex-arm-usb-ocd, olimex-arm-usb-ocd-h, olimex-arm-usb-tiny-h, olimex-jtag-tiny, tumpa)
PACKAGES: toolchain-xtensa32 2.50200.80 (5.2.0), framework-espidf 3.30202.190627 (3.2.2), tool-esptoolpy 1.20600.0 (2.6.0)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 0 compatible libraries
Scanning dependencies...
No dependencies

Compiling .pio/build/esp32doit-devkit-v1/src/main.o
src/main.cpp: In function 'void app_main()':
src/main.cpp:86:61: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
     xTaskCreate(hello_task, "hello_task", 2048, "1", 5, NULL);
                                                             ^
In file included from src/main.cpp:11:0:
/home/az/.platformio/packages/framework-espidf/components/freertos/include/freertos/task.h:432:37: note:   initializing argument 4 of 'BaseType_t xTaskCreate(TaskFunction_t, const char*, uint32_t, void*, UBaseType_t, void**)'
  static inline IRAM_ATTR BaseType_t xTaskCreate(
                                     ^
*** [.pio/build/esp32doit-devkit-v1/src/main.o] Error 1

Please advise.

xz8987f wrote on Thursday, September 12, 2019:

Your problem is that you call it with
xTaskCreate(hello_task, “hello_task”, 2048, “1”, 5, NULL, NULL);
As task additional parameter you pass a pointer to a constant string, but a pointer to void is expected, so use
(void*)“1”
Additionally you pass two NULL parameters after the ‘5’ (which is the task prioritoy). Only one is allowed (for optinal task handle).

Additionally, 2048 would mean 8192 bytes of stack for an ARM Cortex-M (32bit).
(and cast the result to void if you are not interested in the error code).
So better write

(void)xTaskCreate(hello_task, “hello_task”, 8192/sizeof(StackType_t), (void*)“1”, tskIDLE_PRIORITY+5, NULL);

I hope this helps,
Erich

richard_damon wrote on Thursday, September 12, 2019:

You could put an explicit cast to get around the problem, but the issue is that the void pointer passed to the task isn’t made a const pointer because some applications want to pass a writeable buffer through it, which they can’t if the pointer was made const.

In C++, string literals are const, so there pointers will not implicitly decay to a non-const pointer.

That case would work in C, (with perhaps a warning) as in C string literals do not have const type (but shouldn’t be changed) due to historial reasons.

rtel wrote on Thursday, September 12, 2019:

This looks like a C question, not a FreeRTOS question directly, it just
happens to be on a FreeRTOS API function.

https://www.freertos.org/a00125.html shows the fourth parameter to
xTaskCreate() is a void , and you are passing “1”, and in C strings
are referenced using a character pointer (char
). In this case the
string is a const, so you are passing a const char *. The warning
generated is therefore not what I would expect, as it says:

invalid conversion from ‘const void*’ to ‘void*’

whereas I would expect

invalid conversion from ‘const char*’ to ‘void*’

You may be able to avoid the error by casting the const char * to a void

  • as ‘( void * ) “1”’ - but that might just generate another warning
    about casting away a const - but in any case I doubt that is what you
    intended to do anyway. If you want to pass a pointer to the string “1”
    it would be best to know where the string was allocated - in your code
    it could be allocated anywhere (in RAM, on the stack, in flash as it is
    a const, etc.) and its location is likely to change depending on the
    compiler optimisation level.

Recommend reading the docs available here:
https://www.freertos.org/Documentation/RTOS_book.html

azz-zza wrote on Thursday, September 12, 2019:

Gentelmen, enormously helpful. Thank you very much. My C is 3 month old and RTOS is a few days. Thank you for taking time to breakdown the basics for me .
Cheers.
Andrew