I am using GPS. I want advice for application design with freertos.
For this, I want to create 2 tasks, one queue and one user-defined function for GPS. This user-defined function takes date, time, latitude and longitude from the GPS module using Uart interrupts. The GPS string starts with character $ and ends with \r\n. After this data is ready,
I want to send them using a queue to another task2 that prints on to the serial port or LCD.
I will call this user-defined GPS function from task1.
Can anyone suggest the right approach to design this application?
I have these points and getting deviated.
- How to pass the information from user-defined function to the task. How to signal the receiver task that data frame is ready.
- How to print the data present in the queue to the serial port as well as LCD without getting any problems.
If please suggest the right methods.
There are lots of ways you could do this.
As a start you might want to consider using a stream buffer to send characters from the UART interrupt to a task. https://www.freertos.org/RTOS-stream-buffer-example.html The receiving task could block on the stream buffer and process characters as they are received, or you could have the task block on a direct to task notification and have the ISR look for the terminating \r\n characters - unblocking the task when the \r\n characters have been written to the stream buffer https://www.freertos.org/RTOS-task-notification-API.html
As for writing to the serial port and LCD at the same time, as these are two different outputs you don’t really have to worry about the order in which they are accesses, or even if the accesses interleave in time. You could just have one task first write to the UART and then to the display. Both the UART and display could be potentially slow so how you do that will depend on the requirements of your system - if the system does not have to update very rapidly then just write to the UART and display in the simplest way possible - if there is no time to wait for the updates to complete you will need to do something more complex like use a DMA.
Thanks for the reply. Can I use queues for this application instead of stream buffers. Which one is best for this application. Stream buffer or Queue and why?
If you have one sender and one receiver, which you seem to have, then a stream buffer is much faster and lighter weight.
In my experience, most GPS’s will periodically send their data string (often once a second) with their information, so I will generally dedicate a task to listening to that data. That task will normally be blocking on the serial port, and gathers the data, and perhaps updates some in memory buffers with the current values and maybe sends out notifications elsewhere.
If instead, the GPS only sends this data in response to a specific request, or you have some task will naturally poll the GPS at the rate it sends data (and a big enough buffer to hold a response), you could make the operation into a function that the task calls.
As to how to pass the data, I would tend to make the independent task fill a global memory object that other tasks can just access, maybe through an access function that makes sure the accesses are atomic. The function could do the same thing, or the calling task could provide a structure to be filled in with the results.
Exactly, I will send a specific command request to the GPS and the GPS will give the response to that particular request and not polling. GPS will output every one second a sentence of 80 characters. I will get the required data and send that data to the calling task.
UART_ISR() //Receive Interrupt service routine that receives GPS characters
//Stores the data between $ and \r\n
//Sends the data to Task1 if \r\n is received (data is ready to process)
GPS(); //This task will execute send commands to GPS and gets the data response
//Receive the data from ISR and send to Task2
//Receive the data from task1
SerialPort(); //Prints the received data from GPS on serial port
LCD(); //Prints the received data from GPS on LCD
How UART_ISR will notify the task1 that data is ready. What is mechanism to be used for stream buffer and Queue.
And at this time Task1() is also running when processing the data. How to manage it?
As you said which notification to be used? and which API to use for atomic access