hello friends i have written the code for ARM RTOS, i have used same priority for all of my 4 task, its working fine
my problem is when i change the priority in the code then all task's are not executing simultaneously.... please any one help
I'll ask again: are you SURE that you need that variable to overflow before you set that event? if it is an unsigned 16 bit variable, you will have to wait 65536 iterations!
Let's try once more:
and code is working fine but i am not understanding os_evt_set (0x00ff,tsk4); ?
Why are you not reading the use manual of RTX? Need to be spoon fed? Not by me thank you very much!
Don't you believe in indenting your code, and posting it using the proper tags, as clearly specified just above the message input box?
void job3 (void) __task { while (1) { SPI(); counter3++; if (counter3 == 0) { os_evt_set (0x00ff,tsk4); os_tsk_pass (); } } }
The above code is almost totally meaningless.
Why?
1) There isn't a single comment telling what it is expected to do, or more specifically why it things it does what it does.
2) You make 2^8 or 2^16 or 2^32 iterations of your loop - each iteration with a single call to SPI (which does some SPI communication without we knowing anything about if it just polls something or if it does a full transfer or whatever) and a single increment of your counter3 (which really is not a descriptive name of a symbol - counter3 third counter of what?)
3) First after having done 2^8 or 2^16 or 2^32 (or maybe even 2^64) iterations of your loop, you get an overflow and enter the body of the if statement. It sends a whole bunch of event flags to your tsk4 (yet another totally meaningless name - the goal of the task can't be to be #4, it really must have a purpose of some kind). Why send many event flags? A task may listen for multiple event flags, but you normally send single event flags depending on what event you want to announce. So you can send MY_EVENT_BEEP_BUZZER, MY_EVENT_HAVE_UART_DATA, MY_EVENT_xx and the task can poll or wait for any of the events to happen and then perform the corresponding action before starting to listen for more events.
4) First when the counter overflow do you call os_tsk_pass() - why? Did you think it would be a good idea to suddenly manually share a bit of the processor CPU time? If the processor is just round-robin-scheduling, then this call doesn't really fill any purpose other than to shorten this specific time slice. if it isn't round-robin-scheduling and this is a high-prio thread - how much CPU time do you think the other threads did get before you entered the if body? How much time do 2^8 or 2^16 or 2^32 or 2^64 calls to SPI() take?
5) Note also that os_tsk_pass() only shares CPU time with other tasks of same priority. If you have tasks with higher priority ready to run, then this task wouldn't have run so it wouldn't have been able to call os_tsk_pass(). And if you had other tasks with lower priority, they would still be at lower priority and not be allowed to run by your call to os_tsk_pass() - it can only send execution to the next task with same priority as your task3. If there are no other ready task with same priority, then task3 will instantly continue and start to do a new round of 2^8 or 2^16 or 2^32 or 2^64 calls to SPI().
So I really think you have to sit down and figure out what you want to do. And then read the documentation for the quite few functions available in RTX. It doesn't take long to read the descriptions and figure out what they do. And it doesn't take long to look at the sample code available in the manual and figure out how they are intended to be used. First then will it be meaningful for you to try to write any multithreaded application.
The os_evt_set function sets the event flags for the task identified by the function argument. i understood up to here The function only sets the event flags whose corresponding bit is set to 1 in the event_flags argument.
please any one describe it properly
I already did - didn't you read item 3 in my previous post?
Thankyou so much , my questions might irritates you all but i am very sorry for that, because i am a beginner, i read the user manual but bit confusion in that ....
my code is here
#include<lpc214x.h> #include"adc.h" #include"buzzer.h" #include"spi.h" /* Include type and function declarations for RTX */ #include <RTX_Config.h> #include <RTL.h> /* RTX kernel functions & defines */ OS_ID semaphore; OS_TID tsk1; /* assigne identification for task 1 */ OS_TID tsk2; /* assigne identification for task 2 */ OS_TID tsk3; /* assigne identification for task 3 */ OS_TID tsk4; /* assigne identification for task 4 */ short counter1; /* counter for task 1 */ short counter2; /* counter for task 2 */ short counter3; /* counter for task 3 */ short counter4; /* counter for task 4 */ void job1 (void) __task; void job2 (void) __task; void job3 (void) __task; void job4 (void) __task; /*---------------------------------------------------------------------------- * Task 1: RTX Kernel starts this task with os_sys_init (job1) *---------------------------------------------------------------------------*/ void job1 (void) __task { os_sem_init (semaphore, 2); os_tsk_prio_self (3); /* higher priority to preempt job3 */ tsk1 = os_tsk_self (); /* get own task identification number */ tsk2 = os_tsk_create (job2,3); /* start task 2 */ tsk3 = os_tsk_create (job3,2); /* start task 3 */ tsk4 = os_tsk_create (job4,2); /* start task 4 */ while (1) /* endless loop */ { buzzer(); /*turn on buzzer whenever we press some key*/ counter1++; /* increment counter 1 */ os_dly_wait (5); /* wait for timeout: 5 ticks */ } } /*---------------------------------------------------------------------------- * Task 2 'job2': RTX Kernel starts this task with os_tsk_create (job2,2) *---------------------------------------------------------------------------*/ void job2 (void) __task /* higher priority to preempt job3 */ { while (1) /* endless loop */ { /*Display the converted value on the LCD*/ ADC(); counter2++; /* increment counter 2 */ os_dly_wait (10); /* wait for timeout: 10 ticks */ } } /*---------------------------------------------------------------------------- * Task 3 'job3': RTX Kernel starts this task with os_tsk_create (job3,1) *---------------------------------------------------------------------------*/ void job3 (void) __task { while (1) /* endless loop */ { SPI(); /*send some data to LED to blink it in some sequence*/ counter3++; /* increment counter 3 */ if (counter3 == 0) /* signal overflow of counter 3 */ { os_evt_set (0x00ff,tsk4); /* to task 4 */ os_tsk_pass (); } } } /*---------------------------------------------------------------------------- * Task 4 'job4': RTX Kernel starts this task with os_tsk_create (job4,1) *---------------------------------------------------------------------------*/ void job4 (void) __task { while (1) /* endless loop */ { SCI(); /*display ADC data on the hyperterminal*/ os_evt_wait_or (0x0001, 0xffff); /* wait for signal event */ counter4++; /* process overflow from counter 3 */ } } /*---------------------------------------------------------------------------- * Main: Initialize and start RTX Kernel *---------------------------------------------------------------------------*/ int main (void) { /* program execution starts here */ os_sys_init (job1); /* initialize and start task 1 */ } /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/
but here its not switching properly for other tasks please tell me where may be the problem?
buzzer(); /*turn on buzzer whenever we press some key*/
Your program seems totally void of any code that checks for any key presses.
Note that the buzzer task can sleep, waiting for any keyboard scan code to detect a key resulting in a key-press event being sent to the thread. Right now, it just calls your buzzer function every 5 ticks without caring if it's needed or not.
The problems with your job3 have already been described in a quite long post - have you read through the comments and taken any actions yet?
job2 contains:
{ /*Display the converted value on the LCD*/ ADC();
job4 contains:
SCI(); /*display ADC data on the hyperterminal*/
They can't both be correct, can they?
What does SCI mean? Why don't you use symbol names that gives a clear description of their meaning?
counter4++; /* process overflow from counter 3 */
Incrementing your variable counter4 will hardly process any overflow from any counter 3.
If job4 is expected to display the measurements made by job2, then how confusing is it that it does not seem to care the slightest about what job2 does, but instead waits for an event from job3 - and job3 will only generate any event after every 65536th call to SPI...
Why haven't you written a description of what events detected in your application (detected by whom) that should result in what actions (performed by whom)? You don't have any single line that looks at any stimuli and makes any decision based on that stimuli. So your four threads don't seem to play for the same team - there is no cooperation anywhere. No producers/consumers. To detect/react relations.
Use google translate if you don't understand English well !
how to change the schedular option's in the KEIL?
What part of this statement don't you understand:
Read the user manual. Read the user manual. Read the user manual. Read the user manual. Read the user manual. Read the user manual.
!
Do you have any reasons to believe that you need to change any scheduler options?
Note that if you do run threads with different priority, then you can't look at the scheduler and magically get it to handle your scheduling problems. Whenever you have multiple priorities, you (Y.O.U.) must write specific code for your specific threads that makes sure that the high-prio threads only runs when they have specific (high-priority) work to do and that whenever that high-priority work is done, you leave the CPU capacities for less prioritized threads.
Whenever you have multiple priorities, then the scheduler can only switch between ready (runnable) tasks of the highest priority. So your goal is to make sure that the highest prioritized threads are not in the state running or runnable for 100% of the time or your (Y.O.U.R) code will starve the less prioritized threads.
It doesn't matter if how long time slices you have or if you play with round-robin scheduling or not. Whenever you have multiple priorities involved, YOU must add schedulling code (sleeps or waits (events, mails, ...) into your threads to get them to cooperate. The RTOS does have the primitives you need for that work. It's like LEGO bricks, that you can combine. We can't do it for you - we don't even know what the goals are with your program.
The Keil samples do show examples of the use of the different OS functions. You can see how threads can sleep. You can see how threads turn over CPU time to threads of same priority. You can see how threads sets events or sends mails. You can see how threads sleeps until they get an event or mail. You can see how threads changes priorities (but don't be too quick to play with dynamic thread priorities).
The total number of functions available is quite low. So the total time needed to read through the manual pages and the related sample code is not so high. Have you spent such time yet? Do you have any specific questions after having read the documentation - specific sentences or paragraphs you don't understand?
Per,
It is really very nice that you are doing your best to help this guy. But really, the OP does not read our comments (at all!), clearly did not read the manuals (to which we have posted multiple links!) and is generally disoriented - maybe it is a language barrier. Just let him be: he simply refuses to make a minimal effort.
Thank you for your active co-operation
i wrote here code for 2 task when the tsk1 is compleed its going for the tsk2..... and its not comming back to the tsk1
according to the above discution i gave some delay after tsk2 completion
__task void task1 (void){ /* Obtain own system task identification number */ id1 = os_tsk_self(); os_tsk_prio_self(1); /* Create task2 and obtain its task identification number */ id2 = os_tsk_create (task2, 2); for (;;) { buzzer(); os_evt_set(0x0002,id2); //after completion of the buzzer operation going to the tsk2 /* Signal to task2 that task1 has compelted */ /* Wait for completion of task2 activity. */ /* 0xFFFF makes it wait without timeout. */ /* 0x0004 represents bit 2. */ os_evt_wait_or(0x0001, 0xFFFF); } } __task void task2 (void) { for (;;) { /* Wait for completion of task1 activity. */ /* 0xFFFF makes it wait without timeout. */ /* 0x0004 represents bit 2. */ os_evt_wait_or(0x0002, 0xFFFF); ADC(); /* Signal to task1 if task2 has compelted */ os_evt_set(0x0001, id1); os_dly_wait(10); } } int main (void) { /* Start the RTX kernel, and then create and execute task1. */ os_sys_init(task1); }
Are you intentionally posting broken code, or are you not better than this?
/* 0x0004 represents bit 2. */ os_evt_wait_or(0x0001, 0xFFFF);
What does 0x0004 have with 0x0001 to do?
for (;;) { buzzer(); os_evt_set(0x0002,id2); //after completion of the buzzer operation going to the tsk2 /* Signal to task2 that task1 has compelted */ /* Wait for completion of task2 activity. */ /* 0xFFFF makes it wait without timeout. */ /* 0x0004 represents bit 2. */ os_evt_wait_or(0x0001, 0xFFFF); } }
So every time your unit boots, it should run buzzer first, and then wait for next buzzer event? Is that logical? Does the door bell at your home always sound once whenever the power company turns on the power?
And you seem to have tried to make task1 and task2 run every other time unconditionally. Isn't that very illogical? So you do one ADC read per activation of the buzzer? Exactly why should buzzer and ADC always run buzzer -> ADC -> buzzer -> ADC? Why not just have a single loop then with one call to buzzer and one call to ADC?
You do realize that the goal with multiple tasks are to prioritize things - letting high-priority tasks take over to perform the critical work before dropping out and returning the processor to lower-prioritized work? And to have multiple tasks because you want multiple things to happen semi-concurrently and normally at individual speeds.
A higher priority task can take the ownership of the CPU. So you don't need any task to wait for another task to finish.
The only really practical reason to implement two tasks that runs in lockstep is when you have a typical producer/consumer situation. The consumer sits and waits until the producer have produced something. The producer signals "data available" and the consumer wakes up, picks up the produced work and performs further processing of it. As soon as the consumer don't have any more data to work on, it goes down to sleep again, waiting for the producer to produce more. But your code is not an example of any producer/consumer. Just an attempt at converting a standard loop:
for (;;) { do_a(); do_b(); }
into something very much more complicated. You don't have any concurrency between do_a() and do_b() so, as written, the threads are not adding any functionality to your system.
What is concurrency then? Concurrency is when you do process ADC values and present on the LCD even when the buzzer is busy buzzing. Concurrency is when you scan a keyboard and process keyboard commands if the buzzer is buzzing or not. Concurrency is about making one task continue doing what it needs to do, while being as little affected as possible by other actions in the system - with the special case that tasks with critical priorities have the ability to jump in and take the processing capacity from tasks with high prio. And tasks with high prio can take the processor from tasks with medium or low prio. So tasks with low prio will only run when all tasks with medium, high or critical priority are sleeping, waiting for more input data or new events.