5
\$\begingroup\$

I am new to RTOS coding practices/architectures, and am specifically learning on RTX. Should I have a get_new_sensor_data task for each sensor, or is sensor data usually taken care of by some other means, such as in the ISR outside of any particular task? How do you flag your applications that you have a new piece of data for them?

I don't want to call hardware reading subroutines from the applications that use the sensor data because the data may be blocking several different applications. e.g. temperature may go into a relative humidity calculation task, it may get used by a task that outputs temperature to the user over the UART, and it may get used in another task that is correcting some other sensor that has a temperature-dependent output.

\$\endgroup\$
  • \$\begingroup\$ You seem to be confusing terms. A "task" is not something you "call" -- it runs autonomously, and you communicate with it via messages or shared memory. In any case, you might want to look at design patterns such as publish-subscribe for ideas about how to organize your system. \$\endgroup\$ – Dave Tweed Dec 19 '13 at 14:53
  • \$\begingroup\$ I'm sorry, on a re-read, there is a lot of ambiguity in my wording, and I did say "call hardware tasks" when I meant "call hardware reads". I will edit to correct my mistake. \$\endgroup\$ – Bob Dec 19 '13 at 15:29
  • \$\begingroup\$ Publish-subscribe does appear to be what I'm looking for. I'll check it out, try to find some RTOS-specific code. Thanks! \$\endgroup\$ – Bob Dec 19 '13 at 15:38
2
\$\begingroup\$

Some kinds of sensor must be read on a very strict schedule or else the information received therefrom will be erroneous, either because the read has to have a certain timing relationship with some other event (e.g. one is measuring light reflected from illuminating lamp which is only for 100us every 10ms), or because readings encapsulate implied timing information (e.g. if one is trying to sample audio at 44100Khz, each reading should encapsulate the fact that it was taken 22.6757 microseconds after the previous one; simply taking 44,100 readings at arbitrary times throughout a one-second interval is not equivalent!). Other kinds of sensor may be read at one's leisure.

If you are dealing with the former type of sensor, you should either have a very-high-priority scheduled task to do the reading, or else do it within a timer interrupt that's dispatched directly rather than through the OS. Arrange things so that unless the application gets so far behind that data loss will be unavoidable, the sensor-reading code will always have someplace to put its data. If you have multiple sensors that need to interact, it's often good to handle them all within the same timer interrupt when practical. If everything can be handled by e.g. a 10Khz sensor-handling interrupt, using one fixed-rate interrupt for everything is often much simpler than trying to deal with changing interrupt rates, even if oftentimes the only thing the interrupt will do is decrement a "how many more ticks until I do something interesting" counter.

Sometimes having different tasks for different sensors can be a good approach, but if any sensors share resources (such as ADC channels) it can be very difficult to ensure that there are never any timing conflicts. For example, if e.g. one has one sensor that needs to be read at a strict 5KHz rate and another that needs to be read at a very strict 2Khz rate, and both sensors use the same ADC, it may be most helpful to have a 20Khz interrupt and arrange things so that each interrupt captures the previously requested reading, requests a new reading, both, or neither, and the two sensors will stagger their readings so they never need to have requests pending simultaneously. If the two sensors were handled by separate tasks, ensuring that no sensor will want to use the ADC when the other sensor is using it may be more difficult.

\$\endgroup\$
2
\$\begingroup\$

The question you ask can not be answered in general. There are some common approaches, each with there pro's and con's.

  • Asynchronous read on demand. Fine when the process that needs the value can wait for the read to complete. Might be the best solution when reading is costly (for instance in terms of mAh).

  • Synchronous (periodic) read into a pool, users read from pool. Often a good compromise, especially when the users must process the value, even when it is not changed.

  • Synchronous (periodic) read, users are notified when needed (publish-subscribe, listener). This is often used for trigger inputs that happen only sporadically, like a key being pressed or released. Good idea when the cost of processing is relatively high.

In the last two approaches interrupts can be used instead of synchronous (periodic) reading.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.