Hello,
I am porting the RTX Kernel to a Cortex-M3 device and ran into a difficulty.
I have set up 2 tasks to toggle 2 LEDs to see if my tasks are running as expected. As below.
/*---------------------------------------------------------------------------- * Task 4 'blink_P2': Blink LED P2 *---------------------------------------------------------------------------*/ __task void blink_P2 (void) { os_itv_set (40); for (;;) { os_itv_wait (); Toggle_P2(); } } /*---------------------------------------------------------------------------- * Task 5 'blink_P3': Blink LED P3 *---------------------------------------------------------------------------*/ __task void blink_P3 (void) { os_itv_set (40); for (;;) { os_itv_wait (); Toggle_P3(); } }
If the time delay is set the same for both tasks then there is no problem. Both tasks toggle each LED at 40mS. This works.
However if I change the time delay on one task,(for example the second task to 50mS) then both tasks now take several seconds to toggle the LEDs.
I have ported the RTX kernel previously to an ARM7 core without difficulty but cannot see the problem on the Cortex-M3 ?
Can someone advise please ?
thanks!
Are any other tasks running? What are the ask priorities? Can you show us the task create section of your code?
Note: the wait functions are in values of systick not miliseconds.
Did you properly configure your systick timer?
Note: to post code you can use < pre> and </ pre> (without the spaces).
M
Thanks for the reply Marc,
Yes only 2 tasks are setup. The init task sets up the 2 tasks as below and exits.
/*---------------------------------------------------------------------------- * Task 4 'init': Initialize *---------------------------------------------------------------------------*/ __task void init (void) { GPIO_INIT(); t_blink_P2 = os_tsk_create (blink_P2, 0); /* start task 'blink' */ t_blink_P3 = os_tsk_create (blink_P3, 1); /* start task 'blink' */ os_tsk_delete_self (); }
In the RTX_Conf_CM.c file it is as default except for :
// </h> // <h>SysTick Timer Configuration // ============================= // <o>Timer clock value [Hz] <1-1000000000> // Set the timer clock value for selected timer. // Default: 6000000 (6MHz) #ifndef OS_CLOCK #define OS_CLOCK 16000000 #endif // <o>Timer tick value [us] <1-1000000> // Set the timer tick value for selected timer. // Default: 10000 (10ms) #ifndef OS_TICK #define OS_TICK 1000 #endif
thanks Mike
So your systick is 10ms Which means an ITV wait of 40 = 40 x 10ms = 400ms.
Also not that your tasks have different priorities.
Try setting the priorities of both tasks the same and see if you get the expected behaviour.
the systick is 1000. the 10000 is just a comment placed by keil.
so 40*1000uS = 1mS. I have tried setting 0 for both priorities and no difference.
Sorry I missed that. So you mean 40 * 1000uS = 40ms.
This would mean your LEDs are toggling very fast and it may not be noticeable to the eye. Could that be the issue?
A systick of 1ms is very fast (and I think uncommon) try a systick of 10ms. Also, don't use 0 as the priority set both priorities to 1 (or greater).
bad maths on the last post , 40 * 1000uS = 40mS.
I'm using a scope on the LEDs so I can see exactly the switch time. I can't attach an image unfortunately, but they toggle every 40ms as expected when both delays are the same. As soon as I change one of the delay times, both become in the order of seconds instead of milliseconds.
Changing the priority to 1 gives the same result.
Priority 0 is reserved for the Idle task. Not sure if this is causing your problems, but you should only use priorities between 1 and 255. 255 is the highest priority a task can be. One approach would be make 100 the default priority and go higher and lower as you need to differentiate the priorities of your tasks. You will probably find most will be 100. (but there may be cases where EVERY task has a different priority - use what is needed, not what someone says is "normal")
@Robert - Who said anything was "normal" or are just speaking generally?
@Mike - that does sound weird. Is anything else going on? Interrupts, watchdog?
Just as a shot in the dark try changing your systick to 10ms and see if you get the same behaviour.
I guess I was sort of implying that 100 is a "normal" priority for a task. I didn't want anything to think that all tasks should be "normal" as they need to be what they need to be, not what someone (meaning me) says is "normal". So in general, I was speaking generally.
Also after looking, I found the the OS changes any task created at priority 0 to priority 1 for you so that is not your issue.
What version of the OS are you using. I have look through many version of code from 3.8 to the current 4.22a and have not found an issue with any of the ITV os stuff.
Note:
I use 1ms timer ticks all the time. I find it more feels more "normal" and "natural" than 10ms ticks.
Hi Robert McNamara,
I think this is for a Cortex-M3 MCU. How about an ARM7 MCU? And how fast the CCLK is? I mean, could you please teach me how to decide a proper timer tick?
I heard that, the current/recent Linux kernel is a tickless kernel, but RTX only checks the task status when a tick comes, am I right?
When Task1 executes the os_tsk_pass(), will Task1 passes control to the next task of the same priority immediately? or it needs to wait for a tick?
When Task1 executes the os_tsk_pass(), and there is no task of the same priority in the ready queue, when will Task1 passes control to the other tasks?
Sorry for asking questions in this thread, I am no longer a frequent visitor of this KEIL forum, but I remember that, it is not easy to encounter Robert McNamara here.
View all questions in Keil forum