I am really surprised that with the latest version of RTX that Keil has changed the functionality of the millisecond parameter to delay functions.
See
http://www.keil.com/support/docs/3766.htm
It sees that now the delay parameter is having 1 added to it in the latest version of RTX.
This is a significant functional change that I would have thought would not have been implemented without reaching out to the community of users. This change breaks a ton of existing code that relies on polling intervals of the tick frequency.
I regularly have threads that implement a 1 ms polling of hardware devices. This is implemented as a simple delay of 1 ms. Granted the first call to this delay function may return in less than 1 ms, but after that it is consistently 1 ms in duration. With the changes I don't believe that I will be able to poll at the tick frequency of 1 ms, it would be 2 ms. It seems to me that minimum polling time has been decreased to 2 times the tick frequency with the latest version.
I would strongly encourage KEIL to put back the original functionality, but I was wondering if others had the same concern.
In my first paragraph of the previous comment I meant ms not seconds.
My comment really relates to the small value you are using for the delay. With a granularity of 1ms, I consider it unwise to play around with delays around that value and I would endeavor not to do so.
I take your point concerning the decrease of the SYSTICK period, but that is the cost/compromise which must be considered.
Anyway. That's my view. It's likely others will have their own take on it.
Keil support just made me aware of another change to RTX that wasn't clear in the release notes.
>>> in this new CMSIS RTOS, you must call your delays in milliseconds, >>> so even if you speed up the OS clock, you can't get a delay of less than 1 mSec. >>> I don't see a way to use the RTOS to generate a timeout of less than 1 mSec. >>> You can use a hardware timer to create any timeout you like, but the RTOS is >>> not set up for that kind of use.
So not my only hope for a work-around (to reduce my SYSTICK period to 0.5ms) won't actually work.
Considering that the old behavior is the way that FreeRTOS, uC/OS-III and ThreadX all work, I am surprised that KEIL wants their RTOS to behave differently and quite unexpectedly to the advanced user.
Again please consider making this new functionality configurable.
"My comment really relates to the small value you are using for the delay. With a granularity of 1ms, I consider it unwise to play around with delays around that value and I would endeavor not to do so."
I agree with this - and would recommend developers to think carefully about potentially adding a manual +1 when they need to play with really short delays with the need for a hard minimum delay limit. Or maybe consider a secondary timing mechanism, like a faster timer + interrupt + event.
But I would not normally expect:
delay(10); delay(10); delay(10); delay(10); delay(10);
to be intentionally designed to give 54-55 ticks of delay. With a more traditional delay, the expected outcome would be 49-50 ticks as long as not something else jumps in and steals time (such as would be normal on a Windows machine where you can't control when next task switch will happen).
It seems Keil provided a simple work around in the original support ticket for the user to add 1 to the delay parameter if they wished for a minimum number of millisecond delay. Actually, I wouldn't call this a work around, I would call it simply explaining how an os delay function works. This is exactly what I do when I need minimum delay.
I use 1ms delay many places in my code, with the understanding that the first time through it may be less than 1ms, which is acceptable for my application. But now, Keil has made a change to RTX making it impossible to set a delay of 1ms. Also, now all the delays that I’ve added 1 to achieve a minimum delay will delay an additional millisecond, which I don’t want.
What isn't safe about using a 1ms delay? The os change was brought about by a user using a 1ms delay. If you assume that the first call to the delay function will delay exactly 1ms, then that is simply incorrect because that is not how delay functions work (at least in the older version).
I cannot take this new version of RTX. I hope Keil will revert this change and simply explain how users can achieve a minimum number of millisecond delay if required. I hope the examples above showing how multiple calls to osDelay do not accumulate time correctly will be justification enough for Keil to revert this change.
Nope. Can't see the problem.
Reading: http://www.keil.com/support/docs/3766.htm
Looking at os_dly_wait (since I use RL-ARM RTX): os_dly_wait(1 /* rest of current tick */ + 1) ; /* in KEIL RL-ARM RTX */
The library code now adds one on entry. I change my code to passing one less and hey-presto, the library uses the same value as it did before.
"RL-ARM/ RTL / RTX" DOES NOT add one for os_dly_wait() I would be careful subtracting 1 from any value you pass to it. You obviously did not look at the code nor did you try subtracting 1 and see that it uses the same value as before.
First off let me help to fix your current issue with something that works the same as before. Actualy EXACTLY the same as before.
1) include "rtl.h" in your file // it is in ARM/RV31\INC 2) call os_dly_wait(1) every place you now call osDelay(1);
Your code will function as it did before the update (yet you still fully have the update) Since Keil's CMSIS OS implementaion uses RTX as the base os, you actually have full access to all of the RTX functionality. If you are looking for functionality that RTX has, then you may want to consider making calls to RTX directly. If you would like to only use the CMSIS OS function calls, then you will be required to work within that framework, not the framework of your choice.
1) rt_dly_wait(uint16_t ticks) // does not add 1 to the tick count 2) os_dly_wait(uint16_t ticks) // does not add 1 to the tick count 3) osDelay(uint32_t ms) // after converting the ms to ticks it DOES add 1 to the ticks. 1) rt_dly_wait() is an RTX function 2) os_dly_wait() calls the rt_dly_wait() function through the SVC interface (RTX API Function) 3) osDelay() calls the rt_dly_wait() function through the SVC (CMSIS_OS API Function)
Lets understand the CMSIS-RTOS approach.
http://www.keil.com/pack/doc/cmsis/RTOS/html/index.html
For Keil, They have choosen RTX as the Basic RTOS and they made an CMSIS-RTOS API wrapper around that OS.
For Keil, the CMSIS-RTOS API is defined in cmsis_os.h This provides the application with the interface to the "Real Time Kernel" RTX.
The change you are referring to is not an RTX change at all, but a CMSIS-API wrapper change. This change was made because in the CMSIS OS API, the time out in ms and is supposed to guarantee "at least as long" as the timeout value. This is the specification for all ms timeout values in the CMSIS OS. IF Keil wants to be CMSIS OS compliant, they need to do what they did. IF you really believe that Keil should do it different, then I believe you will need to get the spec changed. Then asking them to change the code will be easy.
So for now we need to fix your code.
1) The fix above does work. Make the change. 2) Your code is working as it did. Now you can relax and decide how best to fix your code going forward.
RL-ARM/ RTL / RTX" DOES NOT add one for os_dly_wait() I would be careful subtracting 1 from any value you pass to it. You obviously did not look at the code nor did you try subtracting 1 and see that it uses the same value as before.
You're absolutely right, I did not look at or try the code, since I don't have MDK installed on this phone. I realised as soon as I hit post that I'd mucked up what I was trying to say - which was that the documentation that I'd read suggested identical behaviour was possible.
But if it is something that (helped) trigger your explanation of the situation to those that do have concerns, then it's OK with me :)
After considering all the feedback we will remove this change for the next revision. This effectively revert back to behaviour before the fix.
Sorry for the confusion.
Reinhard
Hi,
another CMSIS-RTOS non-conformity: try osSignalWait(0, 100000); You will observe that the function will only wait for 65.53 s. This is due to the fact, that RTX can handle only uint16_t waits. See also the so called "helper function"
static uint16_t rt_ms2tick(uint32_t millisec)
and its use in several wait functions of rt_CMSIS.c.
A change of this or at least a mention in the CMSIS-RTOS documentation was promised to me in a support case in March of this year. I wonder when this will happen.
Best regards, Ralph
Much thanks for your consideration of this request.
Cheers, Andrew Lucas