transmission reception in one task freertos - freertos

I'm working on a freeRTOS project and the SAM4S Xplained Pro.
In a task called every x ms, I would like to:
initiate transmission of datas
extract data from a reception buffer (if an end of frame has been detected)
I'm wandering if there is a way to wake up this task not only periodically, but also when an end of frame has been detected ? And when this task is woken up by this event, only extraction of data would be performed, not the data transmission.
Is the best way consists in creating two tasks ? One for emission, other for reception.
I've not writen any code yet, I'm looking for some advices on how to deal with FreeRTOS and communication issues, as I'm a begginer in it...

You can have the task block on a stream buffer or message buffer (https://www.freertos.org/RTOS-stream-message-buffers.html) and have the interrupt send data to the buffer to unblock the task. Set the read timeout to the period at which you want to transmit, that way the task will unblock when either it is time to transmit again or when data has arrived. You can use https://www.freertos.org/xTaskCheckForTimeOut.html to adjust the timeout to account for any time already spent in the Blocked state (i.e. if the task initially blocks for 100ms, but data arrives after 40ms which causes the task to unblock, then adjust the next block time to 60ms before blocking again to make up the whole 100ms).

Related

Is it sufficient to set ROS publisher buffer to 1 and Subscriber buffer to 1000 and still not loose any messages

I am trying to understand subscriber and publisher buffers. If I set subsrciber buffer to 1000 and publisher buffer to 1, are there any chances that I loose messages ? Could anyone please explain me the same?
Yes, in theory you may lose messages with these settings, in practice it depends.
Theory: spinner threads
On both sides, publisher as well as subscriber, there are so called spinner threads responsible for handling the callbacks (for message sending on the publisher side and message evaluation on the subscriber-side). These spinner threads are working in parallel to the main thread. If messages are arriving faster from the main thread than they are being processed by the spinner thread, the number of messages given by the queue size will be buffered up before beginning to throw away the oldest ones. Therefore if you publish at a very high rate the publisher-sided spinner thread might drop older messages, while if your callback function on the subscriber side takes too long to execute your subscriber queue will start dropping messages. To improve this one can use multi-threaded spinners where one increases the number of spinner threads and activate concurrency in order to process the callback queue more quickly. Read more about it here.
Practice: Choosing the queue size
The queue size of the publisher queue you should set depends on which rate you publish and if you publish in bursts. If you publish in bursts or at higher frequencies (e.g. > 10 Hz) a publisher queue size of 1 won't be sufficient. On the subscriber side it is harder to give recommendations as it also depends on how long the callback takes to process the information.
It is actually also possible to set the value 0 for the queues which results in an arbitrarily large queue but this might be problematic as the required memory might grow indefinitely, well at least until your computer freezes. Furthermore having a large queue size might often be disadvantageous: If you set a large queue and the callback takes long to execute you might be working on very outdated data while the queue gets longer and longer.
Alternative communication patterns
If you want to guarantee that information is actually being processed (e.g. real-time or safety-relevant information) ROS topics are probably the wrong choice. Depending on what precisely you need the other two communication methods services or actions might be an alternative. But for things like large information streams of safety-relevant real-time data there are no perfect communication mechanisms in ROS1.

FreeRTOS: two tasks with interrupt

I'm completely new with FreeRTOS. I have two tasks: the first one must be performed continuously in the loop and the second one should turn on only after interrupt and after the second one is done it should return to the first one, which needs to start from the beginning(it's important because the first task collects data and if I continue to perform it from the place where I interrupt I will get the trash.).
Can I use Semaphore for it or is there something better? Thank you in advance.
It is not clear what you are asking or what you want to use the semaphore for. Protecting data access by both the interrupt and the first task? Or maybe signaling the first task? From what I can make out it sounds like you want to have a lower priority task running continuously, then when an interrupt occurs have the interrupt handler unblock a higher priority task that will then preempt the lower priority task and execute. Then when it finishes and blocks again the scheduler will naturally continue running the lower priority task. I'm confused by your statement that if you continue executing from where it was interrupted you will get trash though - interrupts always return to where they interrupted.
The most efficient way of unblocking a task from an interrupt would be a direct-to-task notification. I would also recommend reading some of the generic FreeRTOS documentation and books available on the FreeRTOS.org site.

Semaphores in NSOperationQueues

I'm taking my first swing at a Swift/NSOperationQueue based design, and I'm trying to figure out how to maintain data integrity across queues.
I'm early in the design process, but the architecture is probably going to involve one queue (call it sensorQ) handling a stream of sensor measurements from a variety of sensors that will feed a fusion model. Sensor data will come in at a variety of rates, some quite fast (accelerometer data, for example), but some will require extended computation that could take, say, a second or more.
What I'm trying to figure out is how to capture the current state into the UI. The UI must be handled by the main queue (call it mainQ) but will reflect the current state of the fusion engine.
I don't want to hammer the UI thread with every update that happens on the sensor queue because they could be happening quite frequently, so an NSOperationQueue.mainQueue.addOperationWithBlock() call passing state back to the UI doesn't seem feasible. By the same token, I don't want to send queries to the sensor queue because if it's processing a long calculation I'll block waiting for it.
I'm thinking to set up an NSTimer that might copy the state into the UI every tenth of a second or so.
To do that, I need to make sure that the state isn't being updated on the sensor queue at the same time I'm copying it out to the UI queue. Seems like a job for a semaphore, but I'm not turning up much mention of semaphores in relation to NSOperationQueues.
I am finding references to dispatch_semaphore_t objects in Grand Central Dispatch.
So my question is basically, what's the recommended way of handling these situations? I see repeated admonitions to work at the highest levels of abstraction (NSOperationQueue) unless you need the optimization of a lower level such as GCD. Is this a case I need the optimization? Can the dispatch_semiphore_t work with NSOperationQueue? Is there an NSOperationQueue based approach here that I'm overlooking?
How much data are you sending to the UI? A few numbers? A complex graph?
If you are processing all your sensor data on an NSOperationQueue (let's call it sensorQ), why not make the queue serial? Then when your timer fires, you can post an "Update UI" task to sensorQ. When your update task arrives on the sensorQ, you know no other sensor is modifying the state. You can bundle up your data and post to the main (UI) queue.
A better answer could be provided if we knew:
1. Do your sensors have a minimum and maximum data rate?
2. How many sensors are contributing to your fusion model?
3. How are you synchronizing access from the sensors to your fusion model?
4. How much data and in what format is the "update" to the UI?
My hunch is, semaphores are not required.
One method that might work here is to decouple the sensor data queue from your UI activities via a ring buffer. This effectively eliminates the need for semaphores.
The idea is that the sensor data processing component pushes data into the ring buffer and the UI component pulls the data from the ring buffer. The sensor data thread writes at the rate determined by your sensor/processing and the UI thread reads at whatever refresh rate is appropriate for your application.

How can I change the background operation priority dynamically using Dispatch or Operation queues.

Here is the problem that I got. I have several tasks to complete in background when application is running. When I run these tasks in background by pushing them to concurrent dispatch queue it takes more then 10 seconds to complete all of them. They basically load data from disk and parse it and represent the result to the user. That is they are just cached results and hugely improve the user experience.
This cached results are used in a particular functionality inside the app, and when that functionality is not used immediately after opening the application, it is not a problem that it takes 10 seconds to load the data that supports that functionality, because when user decides to use it, that data will already be loaded.
But when user immediately enters that function in the app after opening it, it takes considerable time (from the point of view of the user) to load the data. Also the whole data is not needed at the same moment, but rather the piece of it at a given moment.
That's why we need concurrently load the data, and if possible bring the results as soon as possible. That's why I decided to break the data into chunks, and when user requests the data, we should load the corresponding chunk by background thread and give that thread the highest priority. I'll explain what I mean.
Imagine there are 100 pieces of data and it takes more than 10 seconds to load them all. Whenever user queries the data first time, the app determines which chunk of the data user needs and starts loading that chunk. After that part is loaded the remaining data will also be loaded in the background, in order to make later queries faster (without the lag of loading the cache). But here a problem occurs, when user decides to change the query immediately after he has already entered one, and that change occurs for instance on the 2nd second of data loading process (remember it takes more than 10 seconds to load the data and we still have more than 8 seconds to complete the loading process), then in the extreme case user will receive his data waiting until all data will be loaded. That's way I need somehow manage the execution of the background tasks. That is, when user changes the input, I should change the priorities of execution, and give the thread that loads the corresponding chunk the highest priority without stopping it, so it will receive more processor time, and will finish sooner, and deliver results to the user faster, than it would if I have left the priorities the same. I know I can assign priorities to queues. But is there a way that I can change them dynamically while they are still executing?
Or do I need to implement custom thread management, in order to implement these behaviour? I really don't want to dive into thread management, and will be glad if it is possible to implement using only dispatch or operation queues.
I hope I've described the problem well. If not please comment bellow what is unclear, I'll explain.
Thank you so much for reading so far :) And special thanks to one who will provide an answer. And very special thanks to one, who will give me solution using dispatch or operation queues :)))
I think you need to move away from thinking about the priority at which the queues are running (which actually doesn't sound very important for the scenario you are describing) and more towards how you can use Dispatch I/O or an even simpler Dispatch source to control how the data is being read in. As you say, it takes 10 seconds the load the data and if the user suddenly changes their query immediately after asking, you need to essentially stop reading the data for the previous request and do whatever needs to be done to fulfill the most recent query. Using Dispatch I/O to chunk the data (asynchronously) and update the UI also asynchronously will allow you to change your mind mid-stream (using some sort of semaphore or cancellation flag) and either continue to trickle the data in (you don't say whether or not that data will remain useful if the user changes their mind or not), suspend the reading process, or cancel it altogether and start a new operation. Eithe way, being able to suspend/resume a source and also have it fire callbacks for reasonably small chunks of data will certainly enable you to make decisions on a much more granular chunk of time than 8 seconds!
I'm afraid the only way to do that is to cancel running operation before starting new one.
You cannot remove it from queue until it's done or canceled.
As an improvement for your problem I would suggest to load things even user doesn't need them in background - so you can load them from cache after it's there.
You can create 2 NSOperationQueue with 2 different priorities and download things in background whenever user is idle on LowPriorityQueue. For important operations you can have high priority queue - which you will cancel each time search term changes.
On top of that you just need to cache results from both of those queues.

Suspending already executing task NSOperationQueue

I have problem suspending the current task being executed, I have tried to set NSOperationQueue setSuspended=YES for pausing and setSuspended=NO for resuming the process.
According to apple docs I can not suspend already executing task.
If you want to issue a temporary halt to the execution of operations, you can suspend the corresponding operation queue using the setSuspended: method. Suspending a queue does not cause already executing operations to pause in the middle of their tasks. It simply prevents new operations from being scheduled for execution. You might suspend a queue in response to a user request to pause any ongoing work, because the expectation is that the user might eventually want to resume that work.
My app needs to suspend the time taking upload operation in case of internet unavailability and finally resume the same operation once internet is available. Is there any work around for this? or I just need to start the currently executing task from zero?
I think you need to start from zero. otherwise two problems will come there. If you resume the current uploading you cant assure that you are not missed any packets or not. At the same time if the connection available after a long period of time, server may delete the data that you uploaded previously because of the incomplete operation.
Whether or not you can resume or pause a operation queue is not your issue here...
If it worked like you imagined it could (and it doesn't) when you get back to servicing the TCP connection it may very well be in a bad state, it could have timed out, closed remotely...
you will want to find out what your server supports and use the parts of a REST (or similar) service to resume a stalled upload on a brand new fresh connection.
If you haven't yet, print out this and put it on the walls of your cube, make t-shirts for your family members to wear... maybe add it as a screensaver?

Resources