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
What code?
What RTOS?
i am using LPC2148 ARM processor, it has RTX Kernel OS in it. and i had posted the code in the above, please tel me which priority can i select to make that code to work for all task
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); }
per, One way for a high-priority task to donate CPU time is to make use of delay/sleep calls, telling the OS that the thread don't need any CPU time for x time slices.
i used high priority for the tsk2, so to switch it from higher priority to lower priority i gave some delay.... am i right here?
in the end of the tsk2 i gave some delay(100msec) to switch/to jump/to go to tsk1.... but its not going to tsk1...... where i am going wrong please tell me .......
its solved i was again waiting their using wait flag it was not occurring just i removed that i.e.
__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); /* Signal to task2 that task1 has compelted */ /* Wait for 50 ms before restarting task1 activity. */ // os_dly_wait(5); //I COMMENTED THIS PART NOW IT IS SWITCHING PROPERLY } }
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.
Delays does not change the priority of tasks. A delay just removes the thread from the runnable list for a while, virtually making your system having one less task.
The scheduler always picks the highst prioritized thread that is runnable, i.e. not occupied by a delay, and not locked while waiting for a non-existing event or mail. When zero tasks are runnable, then the scheduler brings in the idle task - sometimes do-nothing code, but sometimes containing book keeping and cleaning up code potentially scanning the memory and flash for checksum errors etc.
its continuously running the tsk2(because of higher prio) so i called some delay in tsk2 during that particular time its going to tsk1 am i right here?
now i am trying to execute the task3, but its not creating 3rd task itself
can any one tell me the procedure to start the task3 in different priority?
Look dude, this is getting a little out of hand. You code contains exactly that. Who writes your code? A slave? A patsy? Something?
What is your goal? To have four tasks because your teacher have said that you should implement a program using an RTOS and containing 4 tasks. Or do you want four tasks because you have made an analysis of the problem and figured out that you have four different actions that needs to run concurrently in different combinations?
If additional tasks doesn't simplify the design then you either do something wrong or have a program that doesn't need tasks in the first place.
i should implement the program containing 4 task... i have 4 different external modules 1. BUZZER - To turn ON and OFF continuously 2. ADC() - To read the POT value and Display it on the LCD 3. SPI() - To send some sequences to LED PATTERNS continuously 4. SCI() - sending POT value again to the hyper terminal using SCI protocol
But the buzzer doesn't sound like it have any reason at all to know anything about any other thread. It sounds like a thread that should sleep until another thread (anyone) does send an event: Please sound buzzer. Then it should either sound the buzzer for a fixed time, or until it gets an event "shut up". After that, it should start waiting again for an event to sound.
Or are your buzzer thread really intended to decide on the beeping itself? In that case, it doesn't need any events at all. It can just turn on - wait - turn off - wait - repeat.
The ADC should run continuously - it really shouldn't matter if the buzzer is on or off. But since you don't want to consume all CPU capacity for this, you either have to time slice the processor with other tasks of same priority or the ADC task must regularly sleep - sleep length depending on number of ADC updates/second.
The SPI thread shouldn't care about any ADC or buzzer - unless the LED patterns should change depending on ADC value or if the buzzer sounds or not. So just a loop that does what it should and either sleeps to reserve time for other threads or round-robin-schedules with similarly prioritized threads.
Not sure what POT values are. Meaning potentiometer values? As in values read in by the ADC thread? And what is the SCI protocol? Anyway - still a task that can run regularly either with round-robin scheduling or intentional delays to get x number of values sent every second.
Why don't you play with the examples Keil installs with the compiler? They clearly shows how to use the OS functions.
In this program SCI() function will Read the ADC(POT) value(of the same ADC) and displays on the Hyper terminal
per, i am sorry......... i m not understanding this
www.keil.com/.../rlarm_os_evt_wait_or.htm
function................
i have the example code . i am not able to understand please help example code:
/************************************************************/ /* PROJECT NAME: Events */ /* Project: Introduction to RL-ARM */ /* Engineer: T Martin tmartin@hitex.co.uk */ /* Filename: main.c */ /* Language: C */ /* Compiler: Real View 3.4 */ /* Assembler: */ /* O/S: RL-ARM 3.4 */ /************************************************************/ /* COPYRIGHT: Hitex UK Ltd 2007 */ /* LICENSE: THIS VERSION CREATED FOR FREE DISTRIBUTION */ /************************************************************/ /* Function: */ /* */ /* Example */ /* */ /* Demonstrates the handeling of event flags in RTL RTOS */ /* */ /* Oscillator frequency 12.000 Mhz */ /* Target board Keil MCB23000 */ /************************************************************/ #include <rtl.h> #include <LPC23xx.H> #include "LCD.h" void LED_Init(void); void LED_On (unsigned int num); void LED_Off (unsigned int num); void task1 (void); // Function prototypes for tasks void task2 (void); void task3 (void); void task4 (void); OS_TID tsk1,tsk2,tsk3,tsk4; //Define Task-ID variables int main (void) { LED_Init(); lcd_init(); //Setup the LCD display lcd_clear(); lcd_print (" Event "); os_sys_init (task1); //Start the RTX with task1 } __task void task1 (void) //define function as task { tsk1 = os_tsk_self(); //Get Task 1 Handle tsk2 = os_tsk_create(task2,1); //create tasks tsk3 = os_tsk_create(task3,1); tsk4 = os_tsk_create(task4,1); while(1) { os_evt_wait_or(0x0005,0xffff); //Wait for an event to be set, no time out set_cursor (0, 1); //Print running task to LCD lcd_print (" Task 1 "); LED_On(0x01); //Switch on an LED to how the task has run os_dly_wait(50); os_evt_set(0x0001,tsk2); //Set an event for task 2. Each task has 16 event flags os_evt_set(0x0001,tsk3); //Set an event in task 3 } } __task void task2 (void) { while(1) { os_evt_wait_or(0x0001,0xffff); //Wait for an event set_cursor (0, 1); //Print running task to LCD lcd_print (" Task 2 "); LED_On(0x02); //Switch on an LED to how the task has run os_dly_wait(50); os_evt_set(0x0002,tsk3); //Set an event in Task 3 } } __task void task3 (void) { while(1) { os_evt_wait_and(0x0003,0xffff); // Wait for two event flags to be set set_cursor (0, 1); //Print running task to LCD lcd_print (" Task 3 "); LED_On(0x04); //Switch on an LED to how the task has run os_dly_wait(50); LED_Off(0x07); //Clear the led's os_dly_wait(100); //Delay os_evt_set(0x0001,tsk1); //Trigger task 1 to start over } } __task void task4 (void) { os_evt_set(0x0001,tsk1); //Set an event in task 1 to kick off with os_tsk_delete_self(); //Delete the task } void LED_Init(void) { PINSEL10 = 0; // Disable ETM interface, enable LEDs FIO2DIR = 0x000000FF; // P2.0..7 defined as Outputs FIO2MASK = 0x00000000; } // Function that turns on requested LED void LED_On (unsigned int num) { FIO2SET |= num; } // Function that turns off requested LED void LED_Off (unsigned int num) { FIO2CLR |= num; }
ABSTRACT:
This example demonstrates the use of event flags to trigger execution of tasks
The project consists of four tasks
tasks 1 -3 wait for one of their event flags to be set
task four sets the event flag of task1 and then deletes itself
task 1 switches on led 1 and then sets the event flag of task two
task two switches on led two and sets the event flag of task three
task 3 switches on LED three waits for a period then switches off all LEDs and then sets the event flag of task one and the sequence restarts. .......................................................................................... in the above he used event flags as 5,1,3, for each task, what are these events? how the event flag will set?
Everything (basically) is explained by the return value of the function (as described in the manual): OS_R_EVT At least one of the flags specified by wait_flags has been set. OS_R_TMO The timeout has expired.
So a task may wait for flag 1 or flag 2 or flag 3 or flag 4 or flag 5 or ... and will wake when one or more of the flags it waits for (the reason it has an "or" in the name, as in event 1 _or_ event 2 _or_ event 3 ...) gets set, or after a timeout, i.e. having waited too long without anyone setting one of the event flags.
So how to set an event? Don't you think the function os_evt_set(flags,task) does that? Why else would the function be named "evt" and "set"?
The events are nothing more than flags. You decide what each flag stands for. The OS doesn't care. You may decide that bit 0 is "one more beer please" while bit 1 is "please self-destroy". So if you have 16 flags, then you can signal up ti 16 different events and the receiving task can decide which of these 16 events it is interested in servicing.
Alas, that school project is quite meaningless since it doesn't contain any concurrency. It's just a state machine that could have been implemented in a single task like:
for (;;) { do_task1(); do_task2(); do_task3(); }
But alas, not all teachers do give meaningful exercises. It would have been so very much better if one of the tasks had continued doing what it was expected to do, while it requested another task to perform a different job concurrently and then signal back when that other job was done.
Thank you per
if i set the flag 1 in task1 , it means that i should wait for that perticular flag(flag 1) in task2?
example:
__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 (;;) { /* Signal to task2 that task1 has compelted */ os_evt_set(0x0004, id2); setting the flag here /* Wait for completion of task2 activity. */ /* 0xFFFF makes it wait without timeout. */ os_evt_wait_or(0x0003, 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(0x0004, 0xFFFF); should i wait here for same flag? /* Signal to task1 that task1 has compelted */ os_evt_set(0x0003, id1); } }
"if i set the flag 1 in task1 , it means that i should wait for that perticular flag(flag 1) in task2?"
That obviously depends on if your goal is that task 1 should activate task 2.
If task 2 have (at least) same priority unless you put task 1 to sleep after having set the event. As usual, the OS will sort all runnable (not waiting for a delay to end or waiting for event, mail,...) on priority and only look at the threads that have the highest priority among the threads that are running. Threads with lower priority gets ignored. Threads still waiting for something that haven't happened (no timeout , no event, no mail, ...) gets ignored.
Thank you so much per.....
now i resided to change my project procedure
i want ADC to read the value for some time and display it on the LCD as well as Hyper terminal(using SCI protocol), buzzer should be turned ON and OFF according to events(as you mentioned earlier) is it possible?? and what about the SPI() function where shall i put? and for what reason? OR should i develop it in different way? if so please suggest me..
Excuse me, but I believe most of us here are working right now. Can't you find a consultant (=pay) to do your homework for you?
in the below program its switching from tsk1 to tsk2 and tsk2 to tsk3 but its again not going back to the tsk1 where tsk2 is going in to wait state.... can anyone tell me why tsk3 is not going to the wait state?
__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); id3 = os_tsk_create (task3, 3); for (;;) { buzzer();/* ... place code for task1 activity here ... */ os_evt_set(0x0002,id2); /* Signal to task2 that task1 has compelted */ os_evt_wait_or(0x0001,0xffff); } } __task void task2 (void) { for (;;) { ADC();/* ... place code for task2 activity here ... */ //os_evt_set(0x0003, id3); os_evt_wait_or(0x0002, 0xFFFF); //os_dly_wait(10); } } __task void task3(void) { for(;;) { SPI(); /* Signal to task1 that task1 has compelted */ os_evt_set(0x0001, id1); os_evt_wait_or(0x0003,0xffff); os_dly_wait(15); } } int main (void) { /* Start the RTX kernel, and then create and execute task1. */ os_sys_init(task1); }
We don't even know if buzzer(), ADC() or SPI() takes long time in relation to os_dly_wait(15).
You have done some debugging, haven't you? What happens when you singlestep the three threads?
By the way - task 3 is waiting for os_evt_wait_or(0x0003,0xffff). But who is sending any event 0x0001 or 0x0002 to this thread? How long do you think the wait will be if the thread don't get anyone to set one or both of the events?
Another thing - is there are reason why task 3 listens to two flags?
It looks a little as if the OP is copy-pasting pieces of code he finds in example programs without really understanding their impact (and then stumping with his foot: "it is not working!").
View all questions in Keil forum