I have timer and want to sample analog pin and push the samples to queue. I know the variables I'm accessing in the timer function need to be volatile, but from googling it seems I can't turn std::queue into volatile thing by just labeling it as volatile.
Do I have options different from filling volatile array?
Thanks, I'm aware they are not thread-safe, but want to experiment a little. I could do similar things in Java, but won't get exception or kernel panic. Yes, some data will be corrupt but in this case I'm OK with that, I'm toying around.
I'm not 100% sure if I get the panic because the variable was not declared volatile (that matters only during compilation, right?) or because of illegal memory access?
To phraze my question differently: If I use semaphores, locks, etc. + std::queue should I expect the code to run OK?
Even if you manage to put in critical section (disable interrupts) all the calls to the queue instance you have challenges related to the fact that you don't control the back end data and its volatile requirements. Theoretically the compiler might optimize things and keep pointers in registers that would not be modified through the ISR so controlling what's happening for the storage is challenging.
The queue might not be the best class to use on a small micro-controller. Implementing your own circular buffer for example with a fixed size (like the Serial buffer for example) to store the results of your analog reads might be more efficient (no dynamic allocation from within an interrupt context) and easier to keep under control.
Seems to me the whole point of queues in an RTOS is to support inter-thread data transfer. Why wouldn't they be thread-safe? Additionally, the ESP32 port of FreeRtos has xQueueSendToBackFromISR(), which seems like exactly what @gdanov needs. Nothing needs to volatile for this to work.
Of course the FreeRtos queues work by making copies of the data to be enqueued. So they only work with plain old data and not fancier C++ constructs.
EDIT:
I'm assuming @gdanov wants to push data into the queue in the ISR and pull it out in non-ISR code.
Thanks everyone, I have working prototype with queue (espressif have ring buffer based one). The article is also very good for C++ beginner.
Additionally I realized that my timer ISR was labeled with the IRAM_ATTR by the arduino_esp32 library and this caused number of weird crashes.
you may doubt, but this effectively tells the rtos to not disable my ISR when flash cache is disabled and when I initiate OTA I get guru meditation error because I'm using analogRead in the ISR. Registering my handler without the IRAM_ATTR removes this problem.
Here are the cases when parts of application may or should be placed into IRAM.
Interrupt handlers must be placed into IRAM if ESP_INTR_FLAG_IRAM is used when registering the interrupt handler. In this case, ISR may only call functions placed into IRAM or functions present in ROM. Note 1: all FreeRTOS APIs are currently placed into IRAM, so are safe to call from interrupt handlers. If the ISR is placed into IRAM, all constant data used by the ISR and functions called from ISR (including, but not limited to, const char arrays), must be placed into DRAM using DRAM_ATTR.