I have created project with 8 Tasks.
I will have these taskes communicate with each other via a few queues.
What will the best place be (best practise) to put the queue declarations.?
Many good answers to your question are possible.
What I like personally is a very small main() function: it initialises the minimal hardware and it starts 1 task, my main task.
When that task starts it is sure to be the only task (except the idle task ) so it can safely do everything: create queues, buffers, semaphores, and also initialise peripherals.
Only when that has been done successfully, the main task will start/create all other tasks and services.
The reason to do most of the initialisation from a task ( and not from main() ) is that many functions may depend on a running scheduler.
xTaskCreate (vMainTask, "mainTask", STACKMAINTASK, NULL, PRIOMAINTASK, NULL);
void vMainTask( void *pvParameters )
initialiseresources(); // queues, semaphores etc
initialiseperipherals(); // drivers for peripherals
for( ;; )
// Do the main work
I personally prefer a different method. My main functions calls an init function for every "Module" in the system that creates the task, queue, semaphores excetera and does any simple hardware initilization (that which can be done without use of interrupts and such), and THEN starts the scheduler.
Any initilzations that need FreeRTOS to be up (then need interrupts etc.) will be at the begining of an appropriate task. (This is especially true of 'remote' devices that need a comm link to talk to).
The problem I see of holding off creating things until FreeRTOS has started is you have a much larger surface of things that you need to make sure are setup before use, and all the hidden dependencies between things. Queue are the communication link between tasks or tasks and interrupts, so you need to be sure they are setup before either user of the thing accesses them. If you do it pre scheduler, this isn't normally an issue as the tasks aren't running nor are the interrupts, so nothings should be trying to access them. Setting things up pre-scheduler says I can simply setup the queue in the module that receives from it or that setups what is protected by a semaphore/mutex, and it generally doesn't matter what order they are setup.
If you setup after the schedule has started you have to figure out what CAN be setup first (becuase it doesn't start up accessing something it doesn't setup), which may mean moving the initilization of a queue away from the 'natural' owner of it. You also need to be much more careful with things that use interrupts to make sure an iterrupt can't occur until everything it accesses has been setup.