Hello,
If you violate RTX's rule that you are not to mix the interval and delay timers (thus a task that needs to wake-up at a certain interval is blocked), RTX will try to fix the periodic task's schedule but waking it up sooner that expected. It might take anything between 1 and 10 cycles until the original period is restored. It is possible to call "os_itv_set" again to fix it immediately, though.
Hi, I think, it might not be a good idea to volatile RTX's rule(s). When I need os_dly_wait and os_itv_wait in the same task, I create a new task where I call os_dly_wait instead of calling it directly. This task sets an event or sends a message, when the time has expired.
I think you mean, "violate RTX's rule(s)" ?
Of course, if anything thells you, "do not do this" and you go ahead and do it, then you are obviously asking for trouble!
www.antronics.co.uk/.../dilbert_dont_touch.gif
As I was trying to explain, it is not the same thing. when one writes trashy code, the compiler must not intervene in any way. I think we all agree about that. but when you are using an OS and break the rules, I think the OS is VERY MUCH in a position to take actions to prevent unexpected behavior! Are you seriously comparing the C standard to the vagaries of commercial software package?!
Undefined or not, I cannot accept that a common programming mistake (that can take place in a couple of year from now, during maintenance etc.) will cause equipment to fail or to behave in an undefined manner itself.
If that's actually true, especially the part about "cannot accept", then with all due respect I must tell you that you're in the wrong line of work. This is real work for real men, using rather sharp-edged tools. Use them incorrectly and you'll cut yourself. So don't do that, then.
You keep requesting systems which cannot generally afford any overhead to waste valuable CPU power on all kinds of run-time checking. That's just not gonna happen. There be rules, and if you can't be bothered to learn and follow them, the consequences are on you.
Hans-Bernhard - critical as ever :-)
This is real work for real men
I would have posted:
This is real work for real people.
"Are you seriously comparing the C standard to the vagaries of commercial software package?!"
No, I am talking of the skills required by the developer to read and understand the documentation. All documentation, for all parts used to build a project - And appreciate the pitfalls of undefined behaviour.
Code that relies on the undefined operation of an OS is simply TRASHY CODE!
No, I am talking of the skills required by the developer to read and understand the documentation
You start sounding like Jack Sprat (that is not necessarily an offense). Aha. I hope I don't need to tell you how complex and big these programs can become. The failure above can be introduced by someone that knows the rules and the software by heart, but there is a (asynchronous) path in the program that introduces this failure, and it is unlikely to occur very often. If and when one has expensive stuff or even lives at the tip of his/her fingers, I would like to have some guarantees that SOME safeguards are in place. Don't faint, Steve :-)
"The failure above can be introduced by someone that knows the rules and the software by heart, but there is a (asynchronous) path in the program that introduces this failure, and it is unlikely to occur very often."
Sorry Tamir, but that simply sounds like a badly designed project.
Stunned Steve,
It did not happen yet, and the project is not badly designed.
But, surely, such a person would be aware of this possibility and, therefore, take steps to ensure that it can't happen - by design...?
That's exactly right Andy - the design of the operating system in question :-)
No, the design of the OS says, "you must not do this" - so it is up to you to ensure that your application cannot do it.
eg, have a flag to tell you when you're using one type of timer, and check that flag before using the other type
Andy, I believe your latest reply is a summary of the philosophical differences between me and the rest. As stated once, "arrogance and self awareness seldom go in hand in hand". People are flawed. No matter how smart you are or think you are, you will make mistakes, some of them lurking, waiting to bite you when you least expected. How much ROM space will it cost to implement a simple test and return a error code in necessary, just to indicate "there is something wrong here and it could be dangerous"? Will it delay execution by a too a significant amount of time? How many accidents can be prevented? How many lives can be saved?
For some "normal" OS, there are checked builds - special versions of the OS that incorporates extra tests to try to catch problems in the OS and in the user applications.
For an RTOS, it can be hard to make augmented versions, since extra code will take extra time, and possibly change the balance of the application. Of course, it would be good if every single application with real-time requirements was always fast enough that there was exctra cycles to spare for run-time testing.
Calling os_itv_set(N) causes a logical "interval timer" to start running repeatedly expiring every N ticks starting N ticks from the time os_itv_set(N) is called. If for any reason, the task that called os_itv_set(N) is not waiting on os_itv_wait() when this time period expires (This could be because the programmer called os_dly_wait() or just ended up executing more lines of code then could be processed in the timer interval or a higher priority task took all of the processor time), when the os_itv_wait() is called it will return IMMEDIATELY. If for some reason the interval is missed M times, then for sure, the next M times that os_itv_wait() is called, it will return immediately. Calling os_itv_set(N) does not "FIX" this "ISSUE", it is behaving properly, but you must be expecting it to behave differently. Calling os_itv_set(N) just stops the currently interval processing and restarts it based on the current time, removing any "missed" intervals. If this is what you want it to do, then that is how you should be using it.
If you want YOUR code to behave in a certain way, than you should not use code that causes it to not behave the way you want it to behave. It is in no way clear how you want your code to behave from what was posted, but it is clear that it is not behaving how you want it too. It is clear looking at the RTL code how the os_itv_wait() behaves and that it is not doing something that it should not.
Calling os_dly_wait() in no way makes os_itv_wait() behave in a non-deterministic way, it just makes it more likely that you are not waiting at os_itv_wait() when the interval is missed. It also makes it more likely that it is missed many times, essentially queuing up MANY missed intervals. The call to os_itv_set() just empties the "queued" intervals and restarts it now.
You might want to consider buying the RTL source code.
Sounds like os_itv_wait() function could make use of a configuration option. To either "queue" n ticks, or just queue one tick.
Keeping track of how many times the timer has expired is great if the thread is intended to work like a clock, and tick a fixed amount of ticks / hour. If the timer is instead intended to make sure that a thread polls something with a specific time interval, then there would be no need to have the thread perform multiple polls directly after each other in case the thread for some reason did a job that took multiple tick intervals.
Of course a thread just needing a delay between polls could use other methods to create the delay.
Per,
I fully agree with you. Just to reiterate: I also think this behavior must be configurable - the current state of affairs makes it possible for a task to use outdated sensor data because it woke up too early/too often. As I stated numerous times on this thread and others, I think systems should try to protect themselves and their environment. Robert: Surely you agree that this potential behavior is not desirable to have when controling, say, a stepper motor in a mission critical system? I'll be very careful in the mean time!
<why_special_case_now?> I'll be very careful in the mean time! </why_special_case_now?>
Looks like you want to produce your mission critical systems in this way:
1 - Read the documentation regarding what is and is not permitted. 2 - Write the code to comply with what is not permitted. 3 - Whinge about the system not doing what you think it should do when you ask it to do something out of bounds.
The OP sounds like the type of guy who gets a recipie for fish-pie, decides to use beef and then complains to the author that the dish doesn't taste of fish!
As I see it, it may be nice if the behaviour is configurable. But if the goal isn't to have a specific number of ticks/hour, but instead to have a specific delay between each sampling of a sensor, then you could instead start a delay once/loop iteration. The true iteration frequency would be the delay time + jitter + execution time, but that sounds ok if all that is needed is to make sure that n ms has passed since the previous reading of the sensor.
I agree that you are trying to use a set of functions to do something that they were not designed to do. I suggest you stop doing that and write code does what you want it to do.
You might save yourself a lot of time if you bought the source code for yourself and actually see what it does.
The os_itv_set() and os_itv_wait() provide deterministic behavior. If you would like some other kind of behavior, then that should be implemented in a separate set of functions and not configurable options for these well defined items.
Do you have difficulties in understanding fundamental English language constructs? When I state that I will be careful, I meant: "I discovered this behavior, it is not what I want, thus - I will be careful not to fall into this trap". I genuinely hope got it this time around.
This thread (at least so far) is a vivid demonstration of how some people react when they encounter something that they are not accustomed to and seems initially "wrong". First they cringe, and finally, after rolling in the mud for a while, they refer to kitchen metaphors before yelling: "go read the manual and do what it says". I would have thought most people here had a little more sense of creativity and, perhaps I should say - a sense of responsibility toward the people that use the products they make! It is unfortunate that not everyone that disagreed with me used a sensible line of argumentation as Robert did.
Robert: Surely you agree that this potential behavior is not desirable to have when controling, say, a stepper motor in a mission critical system? I'll be very careful in the mean time!
I was just commenting on the part about me surely agreeing that the behavior not being desirable. The behavior of the os_itv functions is correct as is. There is nothing to change. They work as advertised. THEY do not control any stepper motors, mission critical or not.
Sorry this is causing you so much trouble, that was never my intent. What was your intent when you started this thread? Maybe we can just focus on that.
Robert,
Contrary to what others here think, this "problem" does not trouble me at all! A colleague discovered it, and since it is not documented, we decided to address technical support. My intent was to hear what other think - nothing more. No harm done, no damage, no motors involved, everybody is happy - even RTX. Thanks for your reply.
But it is documented: it is documented that you must not do this!
Where?
It is documented that: "You cannot intermix with a single task the wait method os_itv_wait () and os_dly_wait ()."
But where is the documentation that tells what happens if the thread is busy for one or more full periods before calling os_itv_wait()?
Contrary to what others here think, this "problem" does not trouble me at all!
Interesting you should say that, given that earlier you said you "cannot accept" existing behaviour. If that's not troubling you, what would?
Hans-Bernhard,
Despite me not being willing to accept this, the project's budget forces me to...
That's not the issue actually under discussion here. Robert McNamara undertook it to post lots of details about the exact working of os_itv_wait() into this thread, including the answer to your question here. But while that may have had some relevance to the actual issue under discussion, but it's not "it".
So Andy's answer to Tamir's criticism still stands: it's documented just as it should be Don't do that, then!
No, I don't really agree with you.
Tamir made his post discussing the continuous zero delays from os_itv_wait() after the thread had been busy for a long time. In this case, because he violated the mentioned information that the two wait methods shouldn't be mixed.
But it really doesn't matter exactly what you do. Any (!) operation that makes the thread spend more than a full period before calling os_itv_wait() will result in one or more instant returns. And even if it has been discussed in this thread, it doesn't seem to be documented in the manual page for the function.
So I really do think that that is a big issue, and on topic for this thread. The behaviour will be there even if you don't mix os_itv_wait() and os_os_dly_wait(). It may happen if the thread calls os_evt_wait_and(), os_evt_wait_or(), os_mbx_wait(), os_mut_wait(), os_sem_wait(), or if a higher prioritized thread for some reason over-consumes time, or an ISR gets activated too many times within a time interval.
The fact is that Robert McNamara shouldn't have had to undertake the job of posting the details of os_itv_wait() here, since the documentation should have described if the function tracks number of pending timeouts or just the latest timeout.
Tamir brought up a specific situation only trigged by violating the documentation, but the same situation exists for a large number of cases that does not violate the documentation. That is most definitely relevant.
And Andys note is too narrow. There should not be a "don't mix with os_dly_wait()" in the manual. There should either be a "don't do anything that makes the thread not call os_itv_wait() before the interavl is up" or the manual should consider it ok, but describe the repetitive behaviour.
I just discovered that I can lock up my program with an infinite loop.
This is not acceptable.
Someone might start changing my code later on and not realize the danger. Someone might die.
The compiler should detect that I don't want it infinite and terminate it prematurely.
It should be optional behaviour.
View all questions in Keil forum