Hello, maybe a dumb question and I miss something.
Using Arduino IDE and ESP32, trying to “offload” long reading of OneWire device to a separate task. I’m creating it the usual way using xTaskCreatePinnedToCore() and pinning main core1 (core0 runs other high prio task).
Problem is as soon as I enable this task (even without actual reading of 1Wire, just some loop with vTaskDelay()) - one (or more) of my global variables gets corrupted (assigned some random values). Not immediately, but within 1 minute for sure.
Notes:
This variable is not touched by the task at all, but I marked it as volatile just in case
There are no arrays that can go out of bound and corrupt neighbours
Another task on core0 works fine
Decreasing Task stack size seems to lower the chance of corruption but does not fix it
Using volatile for global variables accessed by tasks is correct and needed. You might stumble into problems when using the optimizer. The compiler has no idea about data shared between tasks and volatile basically means the object might get changed without notice of the compiler/the current code sequence.
However, your problem is strange… depending on the task code I’d expect that increasing the stack size would prevent data corruption. Given that it’s caused by a stack overflow.
Did you define configASSERT and enabled stack checking ?
Did you try to create the task also on core0 ?
@hs2 Thanks for the suggestions, I’ll try stack checking.
But I really doubt that it can overflow as I’m using very simple functions to test and checked stack sizes in range 1k-10k. Lower size gives more time before corruption → yeah, this is strange, but maybe it’s not the stack size itself but just a memory layout is different and corruption reaches the given variable longer.
Hard to say what else can that be… probably I’ll have to disable parts of code to see what fixes it.
I also doubt that the currently rather simple test task causes all the trouble
The root cause problem is most likely somewhere else and just gets revealed (earlier).
I guess you’re using the ESP provided multi-core aware heap.
Do you use DMA transfers somewhere which might get go wild ?
In case the tasks are created in main before the scheduler is started do you provide task parameters from main stack ? That would be bug on ARM MCUs because the main stack is reused for ISRs by FreeRTOS and the parameters might get corrupted.
DMA… Well, I’m using RMT to drive some brushless motor controller using binary protocol. And RMT can optionally use DMA. I need to check the library that I use on top of RMT how it does RMT init (with DMA or w/o). But that part seems to work fine, the core0 task actually is doing that stuff.
No, no task parameters at all, they’re just using some defines (e.g. pin numbers etc) to init themselves up. And since it’s ESP32 (RISC-V) and not ARM probably it’s ok… I have one timer ISR but that’s working fine using volatile var.
Ok - it’s a RISC-V ESP32. Unfortunately I’m not familiar with the RISC-V port of FreeRTOS.
I’ve only seen that there is a configISR_STACK_SIZE_WORDS for the separate ISR stack alternatively specified in the linker script. Is it possible that the ISR stack is too small and overflows ? How do you specify the ISR stack ?
Just a follow-up: sorry for disturbance, that was me stupid.
The initial cause was in PWM measuring code in main loop which, probably, got distorted by running another task alongside (scheduling etc) and was producing unrealistic values which were affecting some other variables through assignments and calculations. So no real corruption.
I’ve switched to ESP32 MCPWM interrupt-based PWM measuring and everything has become smooth.