TaskHandle_t passing object reference crashing on execution

It’s probably user error, but I can’t figure out how to properly pass created object to task, so it can be used along with other tasks.
Here is bit of code when I am creating a task and passing an object

LinHandler lin;
TaskHandle_t Task1;
void loop2(void* parameter) {
    LinHandler& lin = *((LinHandler*)parameter);
    for (;;) {
        lin.write();  // Write data to LIN
        delay(100);
    }
}

void setup() {
  // Initialize your task (2nd loop)
    xTaskCreatePinnedToCore(
        loop2,        // name of the task function
        "ledCheck",   // name of the task
        1000,         // memory assigned for the task
        (void*)&lin,  // parameter to pass if any
        1,            // priority of task, starting from 0(Highestpriority) *IMPORTANT*( if set to 1 and there is no activity in your 2nd loop, it will reset the esp32)
        &Task1,       // Reference name of taskHandle variable
        0); 
}

Outside task, lin.write() works just fine, but when it’s inside the task, it crashed esp on execution. So My assumption is I am not actually passing proper reference ?

And just for reference, inside my object that’s how I initialize it

private:
 lin_bus _lin = lin_bus(LIN_SERIAL, LIN_V2, LIN_EN, LIN_WK, LIN_TX);

and _lin.write is what’s causing the crash.

What I am doing wrong ?

Unfortunately the code snippets are a bit incomplete…
Is

private:
 lin_bus _lin = lin_bus(LIN_SERIAL, LIN_V2, LIN_EN, LIN_WK, LIN_TX);

a member of
LinHandler lin;
which also has a public wrapper write() calling _lin.write internally ?
Is the global lin object properly created ?
The code to pass the object pointer to the task seems correct (which can be checked with a debugger).

So I have other code that uses same object passing and it seems to work.
So to complete the code.

class LinHandler {
public:
    LinHandler();
    void begin(Logger &log, bool master = false);
    void write();
  private:
      lin_bus _lin = lin_bus(LIN_SERIAL, LIN_V2, LIN_EN, LIN_WK, LIN_TX);
}

void LinHandler::write() {
    uint8_t msg[3] = {0x10, 0x49, 0x0F};
    _lin.write(0x80, msg, 3);

where lin_bus is external library object.

So basically you were right, lin.write is a member of LinHandler and it calls _lin.write() internally.
And as I mentioned, outside the task, in main loop() it works just fine. So I would assume that object I am passing is object I’ve initialized with lin.begin()

Unfortunately it compile fine and only gives some random errors, just when _lin.write() happens and reboots

ESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40377268
SPIWP:0xee
mode:DIO, clock div:1
load:0x3fce3808,len:0x43c
load:0x403c9700,len:0xbec
load:0x403cc700,len:0x2a3c
entry 0x403c98d8

Maybe also worth mentioning, _lin.write() uses hardware Serial1, and I’ve head problem before with using same Serial in Task and main loop, maybe that’s related ?

I also think the problem is caused by _lin.write() internal implementation and is not related to your code. Given that Serial1 HW is exclusively used for the link handler.
I afraid you’ve to step into the write routine to get an idea what’s going wrong sometimes.
Is there an interrupt / ISR involved ?
Did you define/use configASSERT for development as recommended ?

I haven’t define configAssert, but I think I accidently figured it out - I just have task more memory as apparently 1000 wasn’t enough ? 2024 seems to do the trick.

ups … that’s a pretty huge stack. However, if it’s needed you’ve to provide it.
BTW besides the extremely helpful configASSERT if you’d have enabled stack checking for development very likely you’d already found the problem :wink:
I’d really recommend to add that to your todo list for the future.

1 Like

I definitely will look into it as i want to use more complex and multiple tasks in the future so it wouls be handy. Thank you