Author Topic: FreeRTOS - pre-emptive or not?  (Read 9307 times)

0 Members and 1 Guest are viewing this topic.

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14445
  • Country: fr
Re: FreeRTOS - pre-emptive or not?
« Reply #25 on: October 10, 2021, 05:23:29 pm »
I don't see the point of using polling for buttons if power consumption is a concern and the CPU would be sleeping otherwise. Why periodically wake up the CPU (for instance, on a timer, for basic preemptive scheduling) and poll, when you can just wake it up from an interrupt triggered by button push? Debouncing can be handled in various ways in order for bouncing not to unncessarily wake up the CPU, but it is indeed something to take into account.

Now of course you also have to consider what else may wake up the CPU, and how much time it takes the CPU you're using to go to a low-power mode and get out of it, to decide which approach will be most efficient.

Note that you can use ISRs along with tasks when using FreeRTOS as far as I've read. In simple cases like this, I'm pretty sure this is simpler than going through hoops with tasks.
(Then again, you may question the relevance of using an RTOS for simple cases, but that's yet another question...)
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: FreeRTOS - pre-emptive or not?
« Reply #26 on: October 10, 2021, 05:34:38 pm »
I just poll the RX queue and if there is nothing there (or not enough bytes to form a usable message) then I yield right away. But I can see this increases power consumption.

[...]

But unless you are putting the CPU into a low power mode most of the time, the power benefit must be minimal.
And, once again as often happens to me when peter-h is involved, I'm confused. ???
Didn't you say that you have a number of CPU bound tasks?
Clarification: to me CPU bound means IO on the task must wait for the CPU to finish. IO bound the opposite, the CPU is always ready to process new IO.
So, if there are CPU bound task, what's the point of trying to switch to low power modes? The CPU bound task should be always ready to run :-//
Also, consider that FreeRTOS has an Idle Task - running whenever none of the user defined tasks are (as it has the lowest possible priority).
This Idle task will consume the rest of your CPU time, unless you take specific steps to configure FreeRTOS for using low power modes.

For serial RX, you are on the right track, if you just want a task to wake up when at least 5 characters have been received, use the ISR to put them in a queue (in general terms - might or might not be a FreeRTOS queue) and signal the task when five have been received (e.g. using a cheap direct task notification, or a semaphore).
As a  general rule for inter-task communication it's better to use what the RTOS provides rather than faffing around with volatile atomic flags or variables etc. - unless you are starved for memory or CPU time, the overhead is quite tolerable and they work correctly.

Remember that in FreeROTS ISRs must use special versions of the primitives (e.g. xSemaphoreGiveFromISR) and explicitly yield with portYIELD_FOM_ISR() (otherwise your task will not wake up until the next time the scheduler invoked).
Other RTOS are simpler in this respect, e.g. Azure RTOS/ThreadX: there's a list of API that are allowed from ISR (most are) and that's all.

For me, in most of my stuff:
user inputs are always polled (encoders, buttons) the input task is woken up periodically and checks if anything has happened.
I2S and SPI use DMA + interrupts, I2C just interrupts. The interrupt wakes the relevant task using the provided RTOS primitives.
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3694
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - pre-emptive or not?
« Reply #27 on: October 10, 2021, 05:57:26 pm »
" once again as often happens to me when peter-h is involved, I'm confused"

:) :)

I am not using sleep mode. This is a powered product so no need. I was just commenting on some other posts.

The product I am working on probably takes up about 10% of CPU time. I can't get the RTOS display to work in Cube; I believe there are some code hooks one has to do. So how exactly it is done, doesn't really matter.

But definitely an RTOS is needed. To make my life easier, to make life easier for others writing modules for it, and to run some genuinely complicated stuff.

If/when I get to running some really complicated stuff then I will need to look at this more carefully. For example one possible version involves driving a 1024x768 or similar colour LCD, probably via SPI, low overhead there at 21mbps especially if using DMA to feed the SPI, but generating the image will need serious processing.

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 
The following users thanked this post: newbrain

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: FreeRTOS - pre-emptive or not?
« Reply #28 on: October 10, 2021, 06:01:39 pm »
Thanks!
I can't get the RTOS display to work in Cube; I believe there are some code hooks one has to do
Cannot help here - I stay as far away from Eclipse as humanly possible.
Task stack display works for me very well using pyocd in Visual Studio Code, both for FreeRTOS and Azure RTOS/ThreadX (the latter, contributed by yours truly).
Nandemo wa shiranai wa yo, shitteru koto dake.
 

Online ejeffrey

  • Super Contributor
  • ***
  • Posts: 3713
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #29 on: October 10, 2021, 06:10:46 pm »
We don't test that a button has been pressed, we test whether the 'button-pressed' ISR has set a semaphore.  A very clean interface!
That is a pretty bad example. You really don't want buttons to be connected to a hardware interrupt line if you want to keep your sanity * (unless you do filtering & debouncing in hardware). Lots of things can go wrong resulting in unpredictable CPU loads. So either you have filtering & debouncing in hardware or software. The latter requires having a process that deals with the buttons. Ofcourse that process can fire an event to a higher process to deal with the button presses.

It's not really a problem to use pin change ISRs for buttons.  You can handle it a couple of ways.  If your ISR code is sufficiently tiny and of an appropriate priority you may be able to just do it.  Maybe a single press fires a few hundred ISRs but if that isn't a big deal for your application who cares?  All you are doing is executing a tiny debounce state machine.  Most of the problems caused by this are if people try to actually do something in response to the button for every event.  If you go this route you do need to consider the contact bounce can vary from part to part and degrade over time, so you need a very healthy margin.  The  more elegant option is that when a button is pressed you temporarily mask the pin change ISR and set a timer to re-enable it X ms later.  This gets you the advantage of a fast initial response, even lower overhead than polling, and all without having to trade off with the wake up interval vs. risk of missing events.  Obviously in a real low power situation you would want to look at the energy cost of a wake-up event and the desired response time to see if this is worth it.

For push buttons it probably doesn't matter.  If you can poll every 50 ms you are usually fine.  That is right around the threshold of perception and it is hard to press a button faster than that.  100 ms is usually too slow, IMO.  However, a lot of people give the same advice for mechanical rotary encoders and I think this is hot garbage.  They need *much* higher polling rates to have acceptable performance and usually people don't poll often enough.  It's OK if you can poll really fast and aren't worried about power consumption but overall it is much better to use pin change interrupts.  You can either handle debouncing and decoding the rotation in the ISR with the same techniques as for buttons, or you are dead set on polling you use the pin-change interrupt to trigger a brief period of high frequency polling that times out when there are no events for a period of time.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8168
  • Country: fi
Re: FreeRTOS - pre-emptive or not?
« Reply #30 on: October 10, 2021, 06:27:49 pm »
I don't see the point of using polling for buttons if power consumption is a concern and the CPU would be sleeping otherwise. Why periodically wake up the CPU (for instance, on a timer, for basic preemptive scheduling) and poll, when you can just wake it up from an interrupt triggered by button push?

Why not. It works, is trivial to implement, and as I commented, has really no downsides regarding power consumption in 99.9999% of cases. There often is some auxiliary housekeeping to do periodically, for example read ADC to check battery voltage to decide if low-voltage cutoff action is needed so all such actions can be combined to one long-interval (low power) periodic task. At 50ms interval, power consumption is meaningless unless you somehow totally manage to bloat the code.

Yes, you can also wire the button to the interrupt line, then in the ISR turn off further interrupts on that line, set another timer interrupt in 50ms where you turn the button interrupt back on. This way you won't hit the problems nctnico described. Yes, why not. It's a bit more complex but a competent programmer easily pulls that off. There are many suitable ways.
« Last Edit: October 10, 2021, 06:30:19 pm by Siwastaja »
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: FreeRTOS - pre-emptive or not?
« Reply #31 on: October 10, 2021, 07:10:35 pm »
We don't test that a button has been pressed, we test whether the 'button-pressed' ISR has set a semaphore.  A very clean interface!
That is a pretty bad example. You really don't want buttons to be connected to a hardware interrupt line if you want to keep your sanity * (unless you do filtering & debouncing in hardware). Lots of things can go wrong resulting in unpredictable CPU loads. So either you have filtering & debouncing in hardware or software. The latter requires having a process that deals with the buttons. Ofcourse that process can fire an event to a higher process to deal with the button presses.

It's not really a problem to use pin change ISRs for buttons.  You can handle it a couple of ways.  If your ISR code is sufficiently tiny and of an appropriate priority you may be able to just do it.  Maybe a single press fires a few hundred ISRs but if that isn't a big deal for your application who cares?
No, it is a recipy for a disaster. Really. What you want for an embedded application is a known / pre-determined CPU load. It is not button presses that cause problems but flaky contacts, external noise sources or just bad wiring can easely produce enough interrupts to drain all your CPU cycles to just handle the ISR routine. I've seen it happen several times resulting in major problems where it comes to product reliability and perceived product reliability by the end user. Also be aware that passing susceptibility testing doesn't mean that your device will never have to deal with interference that is much stronger than is used during the EMC testing. The end user will still expect it to work!
« Last Edit: October 10, 2021, 08:05:45 pm by nctnico »
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #32 on: October 10, 2021, 08:38:01 pm »
Quote
to me CPU bound means IO on the task must wait for the CPU to finish.
In embedded, people write CPU-bound tasks to do IO.
Code: [Select]
while (UART->status & UART_DATA_AVAILABLE)   ;return UART->data;That will work, more or less, in a preemptive RTOS environment, but it's not "RTOS aware", and is poor code.
It will never yield in a cooperative OS environment.

Quote
in FreeROTS ISRs must use (e.g. xSemaphoreGiveFromISR) and explicitly yield with portYIELD_FOM_ISR()
(otherwise your task will not wake up until the next time the scheduler invoked).
Not running until the next scheduler interval might be the preferred behavior.  It depends on how "Real Time" you want to be.

My general opinion is that a lot of people use a preemptive real time OS when they don't really need either preemption or real time behavior.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3694
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - pre-emptive or not?
« Reply #33 on: October 10, 2021, 08:45:07 pm »
Code: [Select]
while (UART->status & UART_DATA_AVAILABLE)   ;return UART->data;
However, it takes just 1 line to yield to RTOS if there is no data arriving. Same on TX.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8168
  • Country: fi
Re: FreeRTOS - pre-emptive or not?
« Reply #34 on: October 11, 2021, 06:17:49 am »
No, it is a recipy for a disaster. Really. What you want for an embedded application is a known / pre-determined CPU load. It is not button presses that cause problems but flaky contacts, external noise sources or just bad wiring can easely produce enough interrupts to drain all your CPU cycles to just handle the ISR routine. I've seen it happen several times resulting in major problems where it comes to product reliability

I've seen it too (in my own code decades ago, when beginner).

For even somewhat competent programmer, there is no problem whatsoever: turn the interrupt off in the ISR! Set a timer to turn it back on after some predetermined time. Completely deterministic CPU load: button press, noise or contact bounce can cause only one interrupt per whatever re-enabling period you use. Not much different from the timer based button checking. OTOH as I said earlier I prefer that timer based checking like you, but it doesn't have to be that way, many ways to skin the cat when done right.
 
The following users thanked this post: nctnico, newbrain, SiliconWizard

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: FreeRTOS - pre-emptive or not?
« Reply #35 on: October 11, 2021, 10:06:31 am »
Quote
to me CPU bound means IO on the task must wait for the CPU to finish.
In embedded, people write CPU-bound tasks to do IO.
Code: [Select]
while (UART->status & UART_DATA_AVAILABLE)   ;return UART->data;That will work, more or less, in a preemptive RTOS environment, but it's not "RTOS aware", and is poor code.
It will never yield in a cooperative OS environment.
I agree. It is better to write code in a way that it tells the OS no processing needs to be done for a while. A simple sleep can do the trick or by using blocking OS functions (for example when waiting for a network packet).
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline bson

  • Supporter
  • ****
  • Posts: 2269
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #36 on: October 11, 2021, 07:21:00 pm »
How would you config the RTOS to run a task when there is say > 5 bytes in an RX queue? Something must be checking that RX queue, whether it is your task or some code in the RTOS.
You set the device to interrupt on a FIFO with more than 5 transfer elements.  In the interrupt handler (which you write) for that device you unblock the task.  The OS will provide synchronization primitives for this, be they BSD-style wait channels, Windows-style event objects, or posix style condition variables.  This way one or more tasks can wait for a particular hardware state change, and the interrupt handler doesn't have to know which ones.  The task then sits in a service loop, waiting for a state change, checks the device to see if it's something interesting (if not it's ignored as spurious), and if so handles it and returns to processing the next state change (or waits for one if there isn't one yet).  The "check and wait" needs to be atomic (and in a good RT OS atomicity is relative, using things like scheduling priority, IPLs for lockout, and interrupt priority).
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14445
  • Country: fr
Re: FreeRTOS - pre-emptive or not?
« Reply #37 on: October 11, 2021, 08:53:24 pm »
But definitely an RTOS is needed.

Well, that sounded a bit strong. You could probably do without one. But the following explained it.

To make my life easier, to make life easier for others writing modules for it, and to run some genuinely complicated stuff.

If it really makes your life easier, then that would be a decent reason already. But IMO, the part dealing with making it "easier for others" (assuming this is a design for which you share the firmware and allow modifications/customization) is the most important here. I agree FreeRTOS gives a well documented and familiar environment for other developers, and requires a lot less documentation and technical support than if your firmware was 100% your own code with ad -hoc scheduling of various tasks and a bunch of ISRs that would make it harder to figure out and easier to mess.
 

Offline ogden

  • Super Contributor
  • ***
  • Posts: 3731
  • Country: lv
Re: FreeRTOS - pre-emptive or not?
« Reply #38 on: October 11, 2021, 09:07:09 pm »
It's not really a problem to use pin change ISRs for buttons.  You can handle it a couple of ways.  If your ISR code is sufficiently tiny and of an appropriate priority you may be able to just do it.  Maybe a single press fires a few hundred ISRs but if that isn't a big deal for your application who cares?
No, it is a recipy for a disaster. Really. What you want for an embedded application is a known / pre-determined CPU load. It is not button presses that cause problems but flaky contacts, external noise sources or just bad wiring can easely produce enough interrupts to drain all your CPU cycles to just handle the ISR routine.

Fully agree. Wild IRQ storms is bad design by definition. Hardware interrupt for "bouncy mechanical contacts w/o RC filter" shall be used only as wake-up for succeeding polling debounce. When IRQ fired - disable I/O hardware interrupt, initiate polling process for some time long enough to detect successful keypress or other signal of interest. At the end of the polling - rearm hardware interrupt. This is most power-efficient way of waiting for noisy I/O signals.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #39 on: October 12, 2021, 12:18:14 am »
Quote
It is better to write code in a way that it tells the OS no processing needs to be done for a while.
I put together some other examples, for some "generic" preemptive OS:
Code: [Select]
// Simple version - we're running under an RTOS, but we're only using
// the preemptive scheduler, and haven't convert our low-level code.

void UARTRXISR() {
  buffer(UART1_info, UART1->data);  // stick data into a FIFO
}

int getc() {
  if (hasData(UART1_info))  // if there's data in the FIFO, get it.
    return unbuffer(UART1_info);  // from the FIFO
  return -1;                // otherwise indicate no data.
}

//
int main() {
  int c;
  // Bad, RTOS-unaware, compute-bound IO.
  while ((c = getc()) == -1)   
    ; // wait for data
  doSomething(c);

  // Slightly better code
  while ((c = getc()) == -1)   
    yield();  // let other tasks run while we wait.
  doSomething(c);

  // Better still
  while ((c = getc()) == -1)   
    mssleep(50);  // let other tasks run for a reasonable user-oriented time
  doSomething(c);
}
Code: [Select]
//
// To really support RTOS, make the ISR and getc() "RTOS enabled."
//
void UARTRXISR() {
  buffer(UART1_info, UART1->data);  // put data into FIFO
  RTOS_wakeup(UART_info->task);  // move the task waiting for input to runable.
}

char RTOS_getc() {
  if (!hasData(UART1_info))
    RTOS_suspend(UART1_info->task);  // no data means the task isn't runnable.
  return unbuffer(UART1_info); // if we woke up, there must be data.
}

//
int main() {
  char c;
  c = RTOS_getc();  // Simpler as well as fully RTOS-Aware.
  doSomething(c);
}
I find it very frustrating to get something like "Arduino on FreeRTOS" when it's not clear how far this sort of chain has been followed.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3694
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - pre-emptive or not?
« Reply #40 on: October 13, 2021, 08:30:10 am »
Code: [Select]
void UARTRXISR() {
  buffer(UART1_info, UART1->data);  // put data into FIFO
  RTOS_wakeup(UART_info->task);  // move the task waiting for input to runable.

I don't think there is any great difference between the above and having an RTOS task polling the RX buffer #bytes and if zero, just yield to RTOS.

The above turning the task on and off is more elegant and wastes less time, but if you yield to RTOS then other stuff will be getting done, and there is only so much that can be done, and if the CPU can't do it all then you need a faster one :)

The RTOS wakeup will be many many instructions too. Will it run the task immediately, or at the next tick?

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline newbrain

  • Super Contributor
  • ***
  • Posts: 1719
  • Country: se
Re: FreeRTOS - pre-emptive or not?
« Reply #41 on: October 13, 2021, 09:04:25 am »
The RTOS wakeup will be many many instructions too. Will it run the task immediately, or at the next tick?
That depends on the RTOS, as I described above. For FreeRTOS if you want immediate scheduling you should use portYIELD_FROM_ISR(), otherwise scheduling will only happen when then RTOS kernel is entered the next time (not from an ISR), which might or might not be due to a tick and might be after a "long" time, depending on your needs.
Azure RTOS will, IIRC, schedule if you use any of its API in the ISR (otherwise it has no way to know!) - it does not have special API versions for ISR.

As for efficiency, using the ISR will only use the CPU when something happens, instead of continuously invoking the scheduler for yielding - a costly operation in itself as it has to decide if any of the other tasks needs waking up.
As a side note FreeRTOS can also use direct to task notifications, which are very efficient WRT to queues and semaphores.
Nandemo wa shiranai wa yo, shitteru koto dake.
 
The following users thanked this post: SiliconWizard

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #42 on: October 13, 2021, 05:42:02 pm »
I put together some other examples, for some "generic" preemptive OS:
Code: [Select]
// Simple version - we're running under an RTOS, but we're only using
// the preemptive scheduler, and haven't convert our low-level code.

void UARTRXISR() {
  buffer(UART1_info, UART1->data);  // stick data into a FIFO
}

int getc() {
  if (hasData(UART1_info))  // if there's data in the FIFO, get it.
    return unbuffer(UART1_info);  // from the FIFO
  return -1;                // otherwise indicate no data.
}

//
int main() {
  int c;
  // Bad, RTOS-unaware, compute-bound IO.
  while ((c = getc()) == -1)   
    ; // wait for data
  doSomething(c);

  // Slightly better code
  while ((c = getc()) == -1)   
    yield();  // let other tasks run while we wait.
  doSomething(c);

  // Better still
  while ((c = getc()) == -1)   
    mssleep(50);  // let other tasks run for a reasonable user-oriented time
  doSomething(c);
}
Code: [Select]
//
// To really support RTOS, make the ISR and getc() "RTOS enabled."
//
void UARTRXISR() {
  buffer(UART1_info, UART1->data);  // put data into FIFO
  RTOS_wakeup(UART_info->task);  // move the task waiting for input to runable.
}

char RTOS_getc() {
  if (!hasData(UART1_info))
    RTOS_suspend(UART1_info->task);  // no data means the task isn't runnable.
  return unbuffer(UART1_info); // if we woke up, there must be data.
}

//
int main() {
  char c;
  c = RTOS_getc();  // Simpler as well as fully RTOS-Aware.
  doSomething(c);
}

Nice examples!
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: FreeRTOS - pre-emptive or not?
« Reply #43 on: October 13, 2021, 06:21:16 pm »
Code: [Select]
// Simple version - we're running under an RTOS, but we're only using
// the preemptive scheduler, and haven't convert our low-level code.

Why not? Since you started using RTOS, your UART buffer has become a shared resource, so you should create a mutex to protect the resource from other threads, a la:

Code: [Select]
  mutex_acquire(UART1_RX_mutex);
  buffer(UART1_info, UART1->data);  // stick data into a FIFO
  mutex_release(UART1_RX_mutex);
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3237
  • Country: gb
Re: FreeRTOS - pre-emptive or not?
« Reply #44 on: October 14, 2021, 11:21:29 am »
Why not? Since you started using RTOS, your UART buffer has become a shared resource, so you should create a mutex to protect the resource from other threads, a la:

Code: [Select]
  mutex_acquire(UART1_RX_mutex);
  buffer(UART1_info, UART1->data);  // stick data into a FIFO
  mutex_release(UART1_RX_mutex);

It's only a shared resource if more than one thread is using it, and that doesn't seem to be implied at all from the code snippet.  If the UART is only accessed in a single thread then no mutex would be needed.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3694
  • Country: gb
  • Doing electronics since the 1960s...
Re: FreeRTOS - pre-emptive or not?
« Reply #45 on: October 14, 2021, 01:33:51 pm »
That's very true but a UART rx channel shared by several RTOS threads is very unlikely to be doing anything useful ;)

At a push you could have one thread doing RX and another doing TX.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3142
  • Country: ca
Re: FreeRTOS - pre-emptive or not?
« Reply #46 on: October 14, 2021, 05:33:30 pm »
It's only a shared resource if more than one thread is using it, and that doesn't seem to be implied at all from the code snippet.

The original example certainly implies two threads - one is buffering the data then waking the other one to "unbuffer" it. Look here:

... examples, for some "generic" preemptive OS

 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14445
  • Country: fr
Re: FreeRTOS - pre-emptive or not?
« Reply #47 on: October 14, 2021, 06:11:37 pm »
That's very true but a UART rx channel shared by several RTOS threads is very unlikely to be doing anything useful ;)

Well, a design with several threads potentially reading from the UART would be questionable, but I think NorthGuy was more talking about sharing the buffer - I suppose in memory - with received data, and not the UART RX peripheral itself.

Say one task reads incoming data from the UART, and puts it in a buffer. Then another task reads the buffer to process data. Then the buffer is effectively shared.
That's typically a use-case, IMO, which should be implemented with queues. They are designed for exactly that, sharing data between tasks in a safe way, and the FIFO nature of the data here lends itself to that. No need to reinvent the wheel with a hand-implemented buffer and mutexes. Now I don't know FreeRTOS a lot, but I'm sure it has queues that can be shared without dealing with mutexes directly.
 

Offline rstofer

  • Super Contributor
  • ***
  • Posts: 9889
  • Country: us
Re: FreeRTOS - pre-emptive or not?
« Reply #48 on: October 14, 2021, 06:17:58 pm »
That's very true but a UART rx channel shared by several RTOS threads is very unlikely to be doing anything useful ;)

Well, a design with several threads potentially reading from the UART would be questionable, but I think NorthGuy was more talking about sharing the buffer - I suppose in memory - with received data, and not the UART RX peripheral itself.

Which is why I said earlier that, IMO, the peripheral itself is not a shared resource.  The queue is shared and the pointers need to be protected during updates but only one process will be dealing with the peripheral device itself.

Here's the 'book' on FreeRTOS Queues
https://www.freertos.org/a00018.html
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14445
  • Country: fr
Re: FreeRTOS - pre-emptive or not?
« Reply #49 on: October 14, 2021, 07:03:22 pm »
That said, even if in the above case, sharing the UART RX wouldn't make much sense, there can still be use cases for sharing a peripheral. Peripherals can definitely be shared resources - you just need to make sure there isn't another, better way of handling things than sharing one before doing it. Ideally, no more than 1 task should access any peripheral, but this rule can and sometimes has to be broken.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf