Pumpkin, Inc.

Pumpkin User Forums

TCB Extensions request & questions

If you're having difficulty with Salvo's configuration options, post it here.

TCB Extensions request & questions

Postby Lo_Vaquero » Fri Jan 26, 2007 3:32 am

I have a tcb extension implementation question:

I have multiple tasks that are identical in function, so they can be created from the same function. They each service a different FIFO and they each wait on a different semaphore. Other than that, they are identical.

The basic function is:

function()
{
while(1)
{
OS_WaitSem(...);
// service FIFO
}
}

My question is how can I implement the OS_WaitSem() using tcb extentions where each task waits a differnt OSECBP?

I have tried setting OSTYPE_TCBEXT0 to OStypeEcbP, but ICCAVR doesn't like. The only thing I have been able to think of is to use tcbext0 as an index and use a switch statement, but that doesn't seem correct.

Any ideas or suggestions? This is my first time using tcb extensions, so I apologize if I'm missing something obvoius.

Rodney

[This message has been edited by Lo_Vaquero (edited January 26, 2007).]

Lo_Vaquero
 
Posts: 9
Joined: Tue Sep 27, 2005 11:00 pm

Re: TCB Extensions request & questions

Postby aek » Fri Jan 26, 2007 4:28 am

OStID() always returns an index to uniquely identify the current task -- use when the task is running.

Also note OScTcbExt0|1|2|3|4|5. This returns a pointer to the tcb extension of interest in the current i.e. running task. There's an example of this in the manual (search "OScTcbExt").

In Salvo parlace, the little c (e.g. in OScTcbPExt) stands for "current", as in "currently running".

------------------

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

Re: TCB Extensions request & questions

Postby aek » Fri Jan 26, 2007 4:30 am

Note that if you have a couple of identical tasks, and each one operates on its own buffer, then as long as you created the tasks and then individually linked the tcb ext in each task to its dedicated buffer, then OScTcbExt is what you need at runtime.

------------------

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

Re: TCB Extensions request & questions

Postby Lo_Vaquero » Fri Jan 26, 2007 11:19 am

Would it be possible to get more information on TCB extensions? These are a powerful feature of Salvo, but not very well documents in the manual, IMHO.

Perhaps adding a section to the manual that collects together all the different aspects of TCB extensions? Right now the manual is a bit cryptic on what they really are, how they function, how exactly to use them, etc. The different parts of the manual where they are mentioned help, be are not very clear on the full picture of TCB extensions.

Now the questions:

1 - Are TCBEXTs static? Besides enabling them, setting them to a type and tying them to a task via OStcbExt(), is there anything else that needs to be done to make sure that data the TCBEXT points to will not be corrupted by other code than runs?

2 - Where does the data that the TCBEXT points to reside? Is it safe to assume that salvo adds this to the 'salvoram' section of RAM? If not, where does it go or need to be?

For example, I assign TCBEXT0 to a custom data type (struct). Where will the memory for this data type be placed? Or do I need to manage that via some sort of global variable implementation?

3 - If I enable a TCBEXT, will all tasks have it added to their TCBs, or will only the tasks that are "linked" to the TCBEXT via OStcbExt() have it added?

For example, I enable TCBEXT0. Will every task in my system have it (and access to it) or only those that have been linked via OStcbExt0()?

4 - Related to #3, how does enabling a TCBEXT impact memory requirements? I'm assuming that if I set a TCBEXT to a data type that is 32 bytes in size, it will increase memory requirements by 32 bytes for each task that has TCBEXT enabled. Or are memory requirements increased by 32 bytes for ALL tasks?

For example, I've enabled TCBEXT0 and set it to a custom data type (struct) that is 32 bytes in size. I have 4 different tasks, but only 2 have been linked to TCBEXT via OStcbExt0(). Will memory requirements for TCBEXT0 be increased by 128B (32*4 tasks) or by 64B (32*2 tasks)? This is not made clear to me in the manual.

5 - When I set a TCBEXT via OSTYPE_TCBEXT, do I need to do so as a pointer-to-a-type or just as the type? I know that OSTYPE_TCBEXT is a void* by default, but I have not been successful in locating exactly how to assign it to different type (either start type such as unsigned char or a custom type such as a struct). I've looked through the manual and the source code with no luck.

6 - How exactly do I connect a TCBEXT to a task? Above I've been assuming that it is via OStcbExt(). Is that correct? If so, how exactly does OStcbExt() work? The example shows something like: OStcbExt0(OSTCBP(2)) = <value>. If I do not need to initialize an value, but simply connect the task to the TCBEXT, do I do something like: OStcbExt0(OSTCBP(2))?

The manual does not really provide examples of its usage and I haven't located it yet in source code.

I know that I can simply (try to) implement TCBEXTs and dig for the answers above based on any success I have. Still, it is easier to have you answer these to make sure. It's also a time saver =)

Thanks!

Rodney

[This message has been edited by Lo_Vaquero (edited January 26, 2007).]

[This message has been edited by Lo_Vaquero (edited January 26, 2007).]

Lo_Vaquero
 
Posts: 9
Joined: Tue Sep 27, 2005 11:00 pm

Re: TCB Extensions request & questions

Postby aek » Fri Jan 26, 2007 11:35 am

quote:
1 - Are TCBEXTs static? Besides enabling them, setting them to a type and tying them to a task via OStcbExt(), is there anything else that needs to be done to make sure that data the TCBEXT points to will not be corrupted by other code than runs?
Yes, they are static.
quote:
2 - Where does the data that the TCBEXT points to reside? Is it safe to assume that salvo adds this to the 'salvoram' section of RAM? If not, where does it go or need to be?
Tcb extensions are extensions to the tcbs themselves, i.e. they are elements of each tcb, in OStcbArea[].

quote:
For example, I assign TCBEXT0 to a custom data type (struct). Where will the memory for this data type be placed? Or do I need to manage that via some sort of global variable implementation?

3 - If I enable a TCBEXT, will all tasks have it added to their TCBs, or will only the tasks that are "linked" to the TCBEXT via OStcbExt() have it added?


An enabled tcb extension becomes part of the structure type that is the tcb -- therefore _all_ tcbs will have said tcb extension in them, and all tcbs will grow by the size of the enabled tcb extension(s).

quote:
For example, I enable TCBEXT0. Will every task in my system have it (and access to it) or only those that have been linked via OStcbExt0()?

4 - Related to #3, how does enabling a TCBEXT impact memory requirements? I'm assuming that if I set a TCBEXT to a data type that is 32 bytes in size, it will increase memory requirements by 32 bytes for each task that has TCBEXT enabled. Or are memory requirements increased by 32 bytes for ALL tasks?


All tasks.

quote:
For example, I've enabled TCBEXT0 and set it to a custom data type (struct) that is 32 bytes in size. I have 4 different tasks, but only 2 have been linked to TCBEXT via OStcbExt0(). Will memory requirements for TCBEXT0 be increased by 128B (32*4 tasks) or by 64B (32*2 tasks)? This is not make clear to me by the manual.

5 - When I set a TCBEXT via OSTYPE_TCBEXT, do I need to do so as a pointer-to-a-type or just as the type? I know that OSTYPE_TCBEXT is a void* by default, but I have not been successful in locating exactly how to assign it to different type (either start type such as unsigned char or a custom type such as a struct). I've looked through the manual and the source code with no luck.


You can set each numbered tcb extension type to whatever you want (default is void *).

Two notes:

1) Each different tcb extension type (0, 1, 2, 3, 4, 5) can be unique. However, all the same tcb extensions (e.g. #3) are all of the same type.

2) The best way to get comfortable with tcb extensions is to debug within an IDE that has good debugging of types. E.g. in IAR EW, add OStcbArea[] to your watched variables. Expand it, down to the tcb extension(s) that you have enabled. The watch window will then show the type(s) of the tcb extensions.

------------------

[This message has been edited by aek (edited January 26, 2007).]

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

Re: TCB Extensions request & questions

Postby aek » Fri Jan 26, 2007 11:44 am

BTW, I have never (personally) added a struct to a tcb extension. It would be more efficient to add a tcb extension that is a pointer to the struct, and then separately create the structs for just the tasks that need them. That way, you don't use up memory for structs for those tasks that will never use the structs.

This is similar to the way Salvo does event flag control blocks and message queue control blocks -- these structs are each larger than a pointer, so Salvo only keeps a pointer to the block in the event control blocks, so that not all events have these blocks allocated to them, since only those events that are event flags or message queues need the (RAM-expensive) blocks -- sems, binsems and msgs don't need the structs.

------------------

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

Re: TCB Extensions request & questions

Postby Lo_Vaquero » Fri Jan 26, 2007 12:53 pm

Andrew -

Thanks for the fast reply! I appreciate the clarifications on tcb extensions. It definately clears up many things about them.

It makes sense to add a tcb extension as a pointer rather than the data type itself. I had it in my head that tcb extensions should be treated as some kind of data type that can be overridden. Too much carry over still from my days as a Windows programmer...

I keep forgetting the Salvo doesn't really have a memory manager and that it is MY job to be the memory manager. =)

I'm using ICCAVR to develop with, so to do any IDE debugging I have to use AVR studio. That's a pain. Oh well, I'll have to try out IAR's kickstart EW to play with these things I s'pose.

Thanks again for the reply!

Lo_Vaquero
 
Posts: 9
Joined: Tue Sep 27, 2005 11:00 pm

Re: TCB Extensions request & questions

Postby Lo_Vaquero » Wed Jan 31, 2007 2:31 am

Thank you very much! This works beautifully and clarifies how to use tcb extensions.

Thank you for the patience and assistance.

Lo_Vaquero
 
Posts: 9
Joined: Tue Sep 27, 2005 11:00 pm

Re: TCB Extensions request & questions

Postby aek » Wed Jan 31, 2007 12:08 pm

OK, here is a simple example.

main.c

code:
#include <salvo.h>
#include <io430x14x.h>

myObject objectA, objectB;

void Task ( void)
{
while (1)
{
OS_Yield();
OScTcbExt0->number++;
printf("tID: %d flags: %u number %d
", OStID(OScTcbP), OScTcbExt0->flags, OScTcbExt0->number);
}
}


void main( void )
{
OSInit();

OSCreateTask( Task, OSTCBP(1), 6);
OSCreateTask( Task, OSTCBP(2), 6);

objectA.flags = 0x55;
objectA.number = 5000;
objectB.flags = 0x33;
objectB.number = 7777;

OStcbExt0(OSTCBP(1)) = &objectA;
OStcbExt0(OSTCBP(2)) = &objectB;

for (;;)
{
OSSched();
}
}



salvocfg.h
code:
#include "struct.h"

#define OSTASKS 3
#define OSEVENTS 1
#define OSMESSAGE_QUEUES 0
#define OSEVENT_FLAGS 0

#define OSENABLE_TCBEXT0 1
#define OSTYPE_TCBEXT0 myObject *



struct.h
code:
typedef struct
{
unsigned char flags;
unsigned int number;
} myObject;


And here's the output:
code:
tID: 1   flags: 85  number 5001
tID: 2 flags: 51 number 7778
tID: 1 flags: 85 number 5002
tID: 2 flags: 51 number 7779
tID: 1 flags: 85 number 5003
tID: 2 flags: 51 number 7780

This shows that in the case of a tcb extension type that's a struct, it's necessary to include the typedef as shown so that the Salvo code can see it properly.

In the example you sent me, you also included a Salvo object of type OStypeEcbP in one of your structs. i) I'm not sure how that can be added, due to the order in which Salvo's header files are included, and ii) we do not support / condone direct manipulation of Salvo's internals except via the services provided. So to solve that one, you're on your own.

------------------

[This message has been edited by aek (edited January 31, 2007).]

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

Re: TCB Extensions request & questions

Postby aek » Wed Jan 31, 2007 12:28 pm

Ah, OK, I see what you wanted to do with your event pointer ... here's how to deal with the #include typedef problem:

main.c

code:
#include <salvo.h>
#include <io430x14x.h>

myObject objectA, objectB, objectC;

void Task ( void)
{
while (1)
{
if (OStID(OScTcbP) == 3)
{
OS_WaitBinSem(OScTcbExt0->myEventP, OSNO_TIMEOUT, label);
printf("Task with tID of %d successfully waited binsem.
", OStID(OScTcbP));
}
else
{
OS_Yield();
OScTcbExt0->number++;
}
printf("tID: %d flags: %u number %d
", OStID(OScTcbP), OScTcbExt0->flags, OScTcbExt0->number);
}
}


void main( void )
{
OSInit();

OSCreateTask(Task, OSTCBP(1), 6);
OSCreateTask(Task, OSTCBP(2), 6);
OSCreateTask(Task, OSTCBP(3), 4);

OSCreateBinSem(OSECBP(1), 0);

objectA.flags = 0x55;
objectA.number = 5000;

objectB.flags = 0x33;
objectB.number = 7777;

objectC.flags = 0x00;
objectC.number = 2001;
objectC.myEventP = (OStypeEcbP) OSECBP(1);

OStcbExt0(OSTCBP(1)) = &objectA;
OStcbExt0(OSTCBP(2)) = &objectB;
OStcbExt0(OSTCBP(3)) = &objectC;

for (;;)
{
OSSched();
if (objectB.number == 7780)
{
OSSignalBinSem(OSECBP(1));
}
}
}



salvocfg.h
code:
#include "struct.h"

#define OSTASKS 3
#define OSEVENTS 2
#define OSMESSAGE_QUEUES 0
#define OSEVENT_FLAGS 0

#define OSENABLE_BINARY_SEMAPHORES TRUE

#define OSENABLE_TCBEXT0 TRUE
#define OSTYPE_TCBEXT0 myObject *



struct.h
code:
typedef struct
{
unsigned char flags;
unsigned int number;
void * myEventP;
} myObject;


And here's the output:
code:
tID: 1   flags: 85  number 5001
tID: 2 flags: 51 number 7778
tID: 1 flags: 85 number 5002
tID: 2 flags: 51 number 7779
tID: 1 flags: 85 number 5003
tID: 2 flags: 51 number 7780
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001
Task with tID of 3 successfully waited binsem.
tID: 3 flags: 0 number 2001

Note that this is the correct output, since the third task is preventing the second task from incrementing its number field past 7780 (because of priorities).

------------------

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

Next

Return to Configuration

Who is online

Users browsing this forum: No registered users and 1 guest

cron