Hi there,
We are using FreeRTOS Posix Simulation for SIL Testing our device.
Therefore we implemented a virtual CAN Driver.
The virtual CAN driver receives messages in a separate Linux thread over ZMQ.
The thread then calls xQueueSendFromISR with the received message.
Note that the ZMQ / virtual CAN Thread is created outside of the FreeRTOS context.
Inside the FreeRTOS context there is a task which uses uxQueueMessagesWaiting and xQueueReceive to read the messages from the queue.
I noticed that there is a race condition between these two tasks.
My first way to resolve this was to use an event (event_wait and event_signal) to surround all calls using this CAN queue.
This actually solves the problem, but I don’t think this is a general solution, because I think if the queue was used by two FreeRTOS tasks, this would create a deadlock.
I think this should be somehow prevented by the portDisableInterrupt / portEnableInterrupt Functions.
Maybe someone else has an idea or has a solution?
The virtual CAN Driver calls the actual Interrupt service routine from the embedded code, which uses queueSendFromISR.
It is probably possible to move the ZMQ message handling to a FreeRTOS Task, but therefore we would have to change the target code as well.
Also I am wondering:
The current Implementation uses zmq_msg_recv, which blocks the current Thread until a message is received.
Would this not block the whole FreeRTOS scheduler?
We call the ISR from within the Unix Thread created outside of the FreeRTOS context.
It is not a Unix ISR itself. I am not sure how could this be done? Using signals?
I dont think it is. Probably would have to integrate the whole TCP/IP stack and use direct socket communication instead of ZMQ?
I found a working solution, basically using a Mutex surrounding critical sections. I uploaded it here on githb: https://github.com/oliverbl/FreeRTOS-Kernel/blob/feat-sync-for-irq/portable/ThirdParty/GCC/Posix/port.c
This works in our system, but I am not sure of any side effects this may cause