I'm asking myself which is the best way to access to a shared resource between task, for example:
I've a file containing raw data and two task that should access to this resources:
-) The first task is getting data from serial port one and should write data to the file.
-) The second task should read data from this file and send these to another serial port (based on external request).
The first solution is to use a Mutex on this file.
The other solution I'm thinking is to create a third task managing access to this file and receiving request (and data) from other other task and sending data to other task through Queue.
Which is the best solution?
Thanks for your help
It depends on how complex the actions will be. Are you using real files in a FAT (or other) file-system? In that case a third task could open the file in update mode ("w+") and provide read- and write-services. That task can indeed open a QueueHandle_t and receive commands.
Note that a QueueHandle_t is not ideal for hi-volume data exchange. It is useful for small messages, for instance a token (enum), a pointer to data, or a pointer to a (command) structure.
If the "file" is not really a file but just shared memory, a simpler mutex of binary semaphore will be sufficient and a lot cheaper.
Thanks for your answer.
You 're right I'm using a FAT system (FatsFS and STM32Cube lib) on a SD card.
Data that tasks should pass through Queue will not exceed 10 bytes.
I'm using a FAT system (FatsFS and STM32Cube lib)
I'm not sure how FatFS (by ChaN) will behave if you open the same file two times: once in read- and once in write-mode.
FreeRTOS' own +FAT library has decided to either allow to open a file by:
- a single task using "w" or "w+" mode
- multiples tasks all using "r" mode
In other words: there may be many readers but just one writer.
Writing data to a file is often the realisation of a transaction. It may be a payment, a reservation, a commitment. Now if you think of it as transactions, it becomes more meaningful to introduce a third party (task) who can do the transactions. This task will handle one transaction at a time without getting interrupted, you make that sure by design.
One product I make has four FM tuners. It is very easy to send some SPI data to a tuner and change the frequency. I have several tasks which must interact with the tuners somehow, in read- and/or write-more. Doing that directly gave problems at some point, and so I also introduced a separate
void vTunerTask( void *pvParameters )
which handles request for all four FM tuners, and that works well.