Pumpkin, Inc.

Pumpkin User Forums

Final idea for OS_WaitKey()

Have an idea on how to make Salvo better? Post it here!

Re: Final idea for OS_WaitKey()

Postby aek » Fri Jan 12, 2001 10:22 am

Also, take a look at this event flag feature set:
http://www.artesys.com.au/cgi-bin/artesys/home/asysweb/public_html/cortex/doc/evn.html

This is a good implementation, and we can do most of it ...

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 7:16 am

Hello,

Some thoughts about the OS_WaitKey():

1. After receiving the event the key should not be cleared or set. This could be made by the programmer if desired. In this aspect the key is different from the semaphore, where after receiving the event it’s cleared. The key can accumulate information – the basic idea is to gather information from different tasks and transport it to other tasks. This difference make keys more flexible then semaphores and of course you can imitate semaphores with keys. With one key you can fake 8 BinSemaphores, but with 8 BinSemaphores you can’t do the job of one key (I’ll not mention that 8 BinSem will consume more RAM and ROM memory). Well, you should keep attention of using keys (in your example you brought a case, where bad usage of the keys can “dead lock” the program). So, the first difference between Keys and BinSem is that KEYs can accumulate information.

2. Because keys hold information from different tasks they could be used to control complicated process, where decision is took on the base of key’s bit information. Into one 8 bit key you can declare two absolutely separate keys from 4 bits – it’s just a programmers job. So, keys could be used in different ways, depend on the programmer wishes.

3. The option key into OS_WaitKey () should have values:

. “MASK_1” – the key is compared with the mask, and if ones in the mask all have corresponding 1 into key – event occurs.

. “MASK_0” – the key is compared with the mask, and if ones in the mask all have corresponding 0 into key – event occurs.

. “ANY_1” - if the key contents even only one “1”, that corresponds with the mask – event occures

.”ANY_0” - if any of the masked bits is “0”

. “EXACTLY” – if the key bits exactly mach the bits in the mask.

Of course you can imagine many other logical operation under the mask – like NOT_EXACTLY, TOGGLE1_0, TOGGLE_0_1, etc.

In fact different option keys dramatically change the behavior of the OS_WaitKey(). So, into this function is hidden more functionality, that could be switched with the option keys.

4. Some ideas of the boundaries of using keys. They depend on the option keys.
- MASK – it should be used when multiple tasks signal one recipient task.
- EXACTLY – it should be used when one task controls multiple waiting tasks
- ANY – it should be used when multiple tasks signal one recipient task. The difference from MASK is that if any of the tasks set the bit into the key - the event occurs (the MASK waits some combination of bits)
Because keys are more complicated then BinSEm extra attention should be taken when using them. The example you brought in the forum illustrate that you should care for the priorities of multiple waiting tasks for one key. In addition you have to know where to clear/set the bits of the key. Keys are not BinSem and visa versa. So they need a little bit different style of programming, they are like bit variables.

What I imagined is one example with starting a rocket (something like your example in the manual), but with more “real” functions. As you know, before starting the engine of the rocket you should care for many other things – fuel, power, check integrity of the equipment, check the validity of start command, check if target is set, etc.

code:

// Definition of the key fields


#define mask_CHECK_OK 0x01
#define mask_FUEL_OK 0x02
#define mask_TARGET_OK 0x04
#define mask_POWER_OK 0x08
#define mask_START_OK 0x10
#define mask_START 0x1F


//----------------------- TASK starting the rocket -------------------------------
Void Start_Rocket(void) // this is the task that starts the engine of the roket
{
OS_WaitKey(Start_Condition, mask_START, MASK_1,OSNO_TIMEOUT,label); // wait for start condition –
// all bits in the mask should have corresponding 1 in the key

IGNITION = ON; // start the engine
OSSignalBinSem(Rocket_Started); // use BinSem to bring information that rocket started successfully.
OS_Stop(label); // after starting the roket, stop the task

}


//----------------------- TASK check engine -------------------------------
Void Check_Engine(void) // this task periodically wakes up and checks if the engine is OK – gathers
// information from sensors into the machine, how they respondes, etc.
{
for ( ; ; ) // main loop
{
if (check_engine_blocks())
OSKeySet(Start_Condition, mask_CHECK_OK); // sets the bit that engine is ready to be started - no problems appered
else
OSKeyReset(Start_Condition, mask_CHECK_OK); // resets the bit – Engine is not ready, can’t start the rocket

OS_Delay(some_time,label); // the period of time between two checks of the engine
}
}


//----------------------- TASK check fuel -------------------------------
Void Check_Fuel(void) // this task periodically wakes up and checks if there is enough fuel – it could wake up not so frequently
{
for ( ; ; ) // main loop
{
if (check_fuel())
OSKeySet(Start_Condition, mask_FUEL_OK); // sets the bit that enough fuel in the tanks - no problems appered
else
OSKeyReset(Start_Condition, mask_FUEL_OK); // resets the bit – not enough fuel – can’t start the rocket

OS_Delay(long_time,label); // the period of time between two checks of the fuel is bigger
}
}


//----------------------- TASK Target set -------------------------------
Void Target_Set(void) // this task periodically wakes up to ensure that target is set.
// If new target comes – blocks the starting of the rocket until rocket accept the new data
{
for ( ; ; ) // main loop
{
OS_WaitMsg(target,t_pointer,some_time,label); // waits until message for new target comes or until some_time passed.


if (!OSTimedOut()) // if message appeared – change the target
{
OSKeyReset(Start_Condition, mask_TARGET_OK); // because new target appeared – block the starting of the rocket until the
// new target is not completely set

change_target_to(t_pointer); // set new target
OS_WaitBinSem(Target_SET_OK,OSNO_TIMEOUT,label); // wait the target is set

OSKeySet(Start_Condition, mask_TARGET_OK);// target set – enable starting of the rocket
}
else
if (check_target()) // checks periodically if the target is still active and correct
OSKeySet(Start_Condition, mask_TARGET_OK);// target set – enable starting of the rocket
else
OSKeyReset(Start_Condition, mask_TARGET_OK);// target somehow not set or current coordinates of the

// rockets are different – stop starting of rocket
}
}
}


//----------------------- TASK POWER_CHECK -------------------------------
Void Power_Check(void) // this task periodically wakes up and checks the power sources
{
for ( ; ; ) // main loop
{
if (check_power())
OSKeySet(Start_Condition, mask_POWER_OK); // sets the bit that POWER OK – batteries and other sources are OK
else
OSKeyReset(Start_Condition, mask_POWER_OK); // resets the bit – something wrong in the power supply

OS_Delay(some_time,label); // the period of time between two checks of power is short – POWER is critical parameter
}
}


//----------------------- TASK COMMAND Reception-------------------------------
Void Command_Reception(void) // this task waits for the password to start of stop the rocket (could be stop only if IGNITION is not ON
{
for ( ; ; ) // main loop
{
do {
OS_WaitMsgQ(PASSWORD, p_pass,OSNO_TIMEOUT,label); // waits the password
} while (!check_ON_password(p_pass)); // waits until password for start appears

OSSignalBinSem(Emergency_LEVEL1); // start task that brings everything in emergency
OSKeySet(Start_Condition, mask_START); // start
do {
OS_WaitMsgQ(PASSWORD, p_pass,OSNO_TIMEOUT,label); // waits the password
} while (!check_OFF_password(p_pass)); // waits until password for stop appears

OSKeyReset(Start_Condition, mask_START); // stop

}
}


//----------------------- TASK DISPLAY -------------------------------
Void Display(void) // displays the starus of the KEY – very low priority, wakes up not often
{
for ( ; ; ) // main loop
{
display(Start_condition);
OS_Delay(big_delay,label); // wakes up not often
}
}



Excuse me that I didn’t describe everything in details, but I want only to mark the ideas of OS_WaitKey

Now the main task


code:
Void main(void)
{

OSCreateTask(Start_Rocket, Start_Rocket_ID,PRIO1); // start engine has highest priority
OSCreateTask(Check_Engine, Check_Engine_ID,PRIO3); // lower priority tasks
OSCreateTask(Check_Fuel, Check_Fuel_ID,PRIO3); // lower priority tasks
OSCreateTask(Target_Set, Target_Set _ID,PRIO3); // lower priority tasks
OSCreateTask(Power_Check, Power_Check _ID,PRIO3); // lower priority tasks
OSCreateTask(Command_Reception, Command_Reception _ID,PRIO3); // lower priority tasks
OSCreateTask(Display,Display_ID,PRIO4); // lowest priority level – control the indication

OSCreatBinSem (Emergency_LEVEL1); .// will set the stuff in emergency – the corresponding task not shown

OSCreateKey(Start_Condition, 0); creates KEY

for (; ; )
{
OSSched()
}
}



In short – the task Start_Rocket waits OS_WaitKey() for all bits in the mask to become 1 – this means – all conditions for starting the rocket are complete. Dinamically the tasks check power supply, fuel, etc. and if something is not OK – the start is impossible. Rocket could be started only is all conditions are OK – if only one of the conditions is not OK – the rocket is blocked. Will be good if the same example could be made with BinSem to be able to compare the advantages and the disadvantages of the both constructions.


Regards
Luben

[This message has been edited by aek (edited January 13, 2001).]

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 7:27 am

Hello,

About the restriction only one task to be able to wait for the key:

I think that this is not neccessary - if the programmer takes care of the key, such dead lockes will never occure. Maybe you misunderstood me about the way how mask work - if there is "MASK" - it needs all corresponding bits in mask that are 1 to be 1 in the key too, ANY - is even 1 bit that is 1 in the key has corresponding 1 in the mask... and EQUAL (EXACTLY) - the mask and the key are absolutely equal.

Because the OS_WaitKey doesn't clear/set the bit in KEY the programmer should care for them in tasks or immediately after the event occures. Maybe this is what is not very "Salvo style", but just this is the most useful quality of the keys.

I'll take look of the URL

Take care
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 7:38 am

Hello,

Seems that the guys from CORTEX already worked good in thes area. I really began to believe that everything is already discovered. Yeah, the idea of KEYs is just the idea of flags in CORTEX. Maybe with some very small variations.
So, if these guys think that flags are OK and wrote so many pages about this - I think it worth to try to implement it in Salvo. But you, like creators of Salvo have the last word - that you know better then me and feel better then me what is good and bad for your "baby"

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby aek » Sat Jan 13, 2001 9:55 am

When posting code sections, please use the UBB code tag so that the structure is legible and I don't have to edit it for legibility.

For more info on the UBB code tag, look in the UBB FAQ (http://www.pumpkininc.com/ubb/faq.html), or edit your message (three down from this one) and see where I added the tag.

Also, please keep each line's comments down to less than 100 characters -- this way, using the code tags does not result in left-right scrollable pages, which is very difficult to read.

I've made these changes to your post below.

NOTE: When posting code segments, the easiest thing is to write the code in a text editor, with the formatting you want. Then, in UBB, insert the code and end-of-code tags into your new message, and then paste the code segment from your editor into the UBB's new message window.

[This message has been edited by aek (edited January 13, 2001).]

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Final idea for OS_WaitKey()

Postby aek » Sat Jan 13, 2001 10:50 am

Re:

quote:
About the restriction only one task to be able to wait for the key:

I think that this is not neccessary - if the programmer takes care of the key, such dead lockes will never occur.


It's not whether it's necessary, but rather, it's the end result of using priority queues, which is integral in Salvo. Therefore, it cannot be avoided that no matter how many tasks as waiting a particular key, only the highest-priority one will be made eligible, regardless of the other tasks' mask values and options.

In your example below (looks like an AA missile, btw) I understand what how you're trying to use keys. We can certainly implement keys fairly easily, and it's much more efficient than multiple binsems.

The one thing you haven't addressed is this: what exactly is the behavior of the system after OS_WaitKey() succeeds? Do you clear all the bits? Do you do nothing?

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 11:09 am

Hello,

After OS_WaitKey() finished (event occurs) nothing specially happens, except that the control is returning to the task (if it's higher priority task at this moment). This is the idea of the flags - they could be used many times, they can accumulate information. This is the biggest difference between flags and semaphores - the semaphores are cleared after event occures, so only one task can receive the semaphore and only one task can signal it.
The keys (understand CORTEX flags) could be set/reset from many places, and can be read from many places too. It's just different structure and of course it needs different way of programming and offers different kind of possible errors and mistakes too.

I think that you can simplify the keys making only one key and some OSBYTES_OF_KEY 1,2,3,4... I mean, you can define one KEY function that could be set to 8,16,24 and 32 bit length. 32 flags is one huge number of flags, I doubt that somebody will use more keys. Well, will be grate if you can allow to the user to create as many flags as he wants.

With two words - keys don't reset after event occures - the scheduler only return the control to the task. I can bring you some analogy - if BinSem are looking like FOR construction, where after end of the loop the program modifies some variables, KEY are similar to WHILE/DO construction, where no action is took after end of loop reached.

And of course the programmer should understand the idea of KEY and use it not in the way like BinSem, or he'll expect awfull results. KEYs (flags) have just different way of working and need different approach.

By the way, after reading the article of CORTEX I don't know anymore which name is better - KEY or FLAG (OS_WaitKEY() or OS_WaitFlag()). The idea of KEY fits better to FLAGS with option key EQUAL, where the "key" should exactly match the "door lock" to open the "door".

And other suggestion - you should add NOT_EQUAL option too, it's important to complete the function. I don't resist for MASK_0 and MASK_1 (to check if the corresponding bits in mask that are 1 have corresponding bit in the key 0 and 1), because they could be imitate somehow, but NOT_EQUAL is impossible to be faked.

There is no sense to try search examples where to show that what BinSem make could be made with KEY and visa versa. They are just DIFFERENT construction and of course one could be faked somehow with the other. What I said "That BinSem are particular case of KEY" should be sorted like <FALSE>, because they are different type of construction like FOR and WHILE(the difference is even bigger). You can make WHILE with FOR and visa versa, but it's not good style of programming. Well, sometimes in your program you can use KEYS like BinSem if you check before set/reset their status and reset them after event occures (it's the behaviour of BinSem) but this will be mistake, bad style of programming. And you can try to obtain the functions of KEY with BinSem, but this will be bad style too.

Regards
Luben

[This message has been edited by luben (edited January 14, 2001).]

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 11:24 am

I'm sorry that I didn't format with UBB my messages, but I just didn't know this feature at all. I supposed that you like owners of this page have possibility to make what you want and in the way you like.

You have to think about the option keys more - the types MASK,ANY,EQUAL,(and maybe NOT_EQUAL) are enough.

About EQUAL:

code:

OS_WaitKey(KEY_ID,mask,EQUAL,OSNO_TIMEOUT,label);


need one more field for the equal, because mask is used to control which bits of the key should be included in the comparision and which no.

code:

OS_WaitKey(KEY_ID,mask,equal_value,EQUAL,OSNO_TIMEOUT,label);


The idea of the flags is that every bit of the KEY is in fact independent and you can use one and the same key like 2 and more different subkeys. So, if one key is used like subkeys - EQUAL has no sense, because it looks in both keys.

But this will change the structure of the operator, so it's better for the user to create more keys, then to use one key with subkeys (on the price of breaking the command rules - one format for EQUAL option and other format for ANY and MASK).

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby luben » Sat Jan 13, 2001 11:31 am

By the way how I can edit my messages. I see so many mistakes sometimes that I'm shame that my name is under them. That's good that you tolerate my muistakes

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Final idea for OS_WaitKey()

Postby aek » Sun Jan 14, 2001 12:10 pm

You can edit your message by clicking on the second icon (the one with the pencil and paper) to the right of the "posted ..." date.
-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

PreviousNext

Return to Feature Requests

Who is online

Users browsing this forum: No registered users and 2 guests

cron