[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [paho-dev] Design question - how to best approach background tasks for the embedded clients
|
And a further reply
"I think the priority is something that will need to be configurable -
so a parameter to whichever function will create the thread, or a #define.
Whether it is best to have the priority high or low depends on the usage
scenario. If an application thread is going to send lots of individual
small packets via the background task then you don't necessarily want
the background task to be a higher priority otherwise you will switch
back and forth between the threads on each send (which may not in itself
be an issue). On the other hand, if an application thread is going to
send one packet via the background thread, then wait for a result, you
would probably want the background thread to be higher priority so it
processes the message immediately.
....hence, its best to have the priority configurable."
On 05/29/2015 10:54 AM, Ian Craggs wrote:
FYI, Richard replied with the following:
"Are the two tasks at the same priority? If not, then the higher
priority of the two will always get the semaphore. If this is the
scenario you have, and you need the other task to get the semaphore
too, then let me know.
If on the other hand the two tasks are running at the same priority,
and the tasks take the mutex almost straight after giving it, then you
can find that the opportunity for a switch between giving and taking
is small enough that it appears that the same task always gets it. If
this is the scenario you have, then call taskYIELD() after giving the
mutex. That will force a switch to the other task and should work for
you. Older versions of FreeRTOS used to do that automatically, but it
could lead to thrashing switches, so the behaviour was changed."
I changed the priority of the background task to be less than or equal
to the task starting it (the application task in this case) and
everything started working as expected.
Ian
On 05/28/2015 09:32 PM, Ian Craggs wrote:
Hi Richard,
in implementing synchronization between two tasks in the FreeRTOS
Windows "simulator" I'm having a problem. I'm starting a background
MQTT task -- that works fine. Then I'm trying to use a mutex for
mutual exclusion between the two tasks.
I create the mutex with xSemaphoreCreateMutex().
One task successfully locks the mutex with SemaphoreTake().
The second task attempts to lock the mutex with SemaphoreTake() and
blocks.
The first task then calls SemaphoreGive() to release the mutex.
But the second task is not unblocked before the first task locks the
mutex again with SemaphoreTake().
Do I need to do something to make sure a task switch occurs when
SemaphoreGive() is called?
Thanks
Ian
On 05/25/2015 05:50 PM, Richard Barry wrote:
Hi Ian,
For ease of use and maintainability reasons it would, in my humble
opinion, be best to not only hide the cycle() function, but also the
yield() function. That would mean, if yield were called at all, it
would be inside the public API functions.
I am still not completely clear as to the purpose of yield(), but
suspect if a separate MQTT thread were allowed then yield() would
not be required. A background thread would free up processing time
by being event driven (important in low power systems that want to
sleep), so improve run time resource usage. If it is considered
that there is not enough RAM resource for the background thread then
consider how much RAM could be saved in each thread using MQTT if
the RAM were instead spent in a single MQTT thread. If it were
still a problem then there is already a TCP/IP thread, so maybe that
could be enhanced to allow user defined extensions - then run the
MQTT stuff in there [that last suggestion would not be a quick
change!].
I would envisage an application thread using the MQTT thread as a
sort of proxy server. The application thread just sends data via
the MQTT thread - all the ins and outs of how the data is sent, and
QoS level maintained, would be entirely inside the MQTT thread
itself. The application thread can sleep until notified by the MQTT
thread as to the the success or failure of the send. Likewise when
receiving data, the receive can be handled inside the MQTT thread,
and then a callback function (or queue, or whatever) used to send
received data to application threads that need it.
If you can we suggest one send or receive scenario to concentrate
on, and describe the sequence used to implement the scenario that
involves calls to yield(), then perhaps I could follow up with a
suggestion of how it could possibly be implemented without the yield().
Regards,
Richard.
+ http://www.FreeRTOS.org
Designed for simplicity. More than 113000 downloads in 2014.
+ http://www.FreeRTOS.org/plus
IoT, Trace, Certification, FAT FS, TCP/IP, Training, and more...
On 22/05/2015 12:36, Ian Craggs wrote:
Hello all,
as I've been updating the C "high level" embedded client for FreeRTOS:
(http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.embedded-c.git/commit/?h=develop)
I've been pondering how to best have background tasks completed. I
originally envisaged two styles of APIs, similar to the standard
Paho C
client libraries, synchronous and asynchronous. I haven't yet created
the asynchronous version, but that would use a background thread,
at the
cost of using more resources.
The "synchronous" or blocking API would be easy to use, and all
processing would take place on the application's thread. Because no
separate threads were involved, this would both simplify
implementation
and reduce resource usage. To allow messages to be received, there
is a
yield() call, which takes as its parameter a time to run. The API also
has a a function (or method) called cycle(), which processes one
incoming MQTT packet. Yield() just calls cycle() under the covers. I
didn't originally intend to make cycle() a public function.
The problem with yield() is that it might spend most of its time doing
nothing. An MQTT packet might arrive at the end of the timeout
period,
and not get processed until the next call to yield(). One
solution is
to make cycle() a public function and allow the application to
interleave application with MQTT processing at a fine-grained level.
For FreeRTOS I was considering also a background task to be
started. But
this would still have the negative effects of increased resource usage
and complexity as synchronization of the common data structures
would be
needed. So I'm reconsidering this once more, and thinking of leaving
the background thread to an (almost) totally non-blocking API.
I had also been thinking of changing the semantics of yield() in some
way to be more event driven. But I don't know whether this would buy
any advantages over making cycle() a public function.
Thoughts?
_______________________________________________
paho-dev mailing list
paho-dev@xxxxxxxxxxx
To change your delivery options, retrieve your password, or
unsubscribe from this list, visit
https://dev.eclipse.org/mailman/listinfo/paho-dev
--
Ian Craggs
icraggs@xxxxxxxxxx IBM United Kingdom
Paho Project Lead; Committer on Mosquitto