HiDEOS Reference Manual

Task
TaskBase
Interface
BPD
TD
TaskGroup
Registry
Message
Queue
MessagePool
Entity
Donut
ResourceManager
InterruptMsg

LockerIRQ
Semaphore
QuickSemaphore
Dog

Global Symbols
Interrupt Services
Utility Macros

Services Reference Manual
User Messages and Classes
Generated Header Files


Task

This is the base class for user processes or tasks, each instance of this class will be given it's own context and be dispatched as a normal process. This is a subclass of TaskBase. This class add message processing to TaskBase.

#include "hideos/task.h"

Task();
Task(const char* name);
Construct a Task with or without a name. The name constructor will automatically register the new task with the system registry. Both constructor create a new context for the process to run in but do not actually start the process, the process must be started explicitly by the system. When creating instances in the HiDEOS initialialization routine, tasks will be automatically be started after the dispatcher is running.

void Release(Task*);
int QueueMessage(Message*);
These are used to put messages onto a task's message queue. Normally a user would not call these directly. The Send() message routines usually call these.

void SetName(const char* name);
const char* GetName();
Set the name of the task if it doesn't have a name. Get the name of the task if it has one.

void SetInstance(int);
int GetInstance();
Set the instance number of the task if it hasn't been set. Get the instance number of a task.

int Register(const char* name);
Register this task with the name name. This is called once per task. It will be called automatically by the task constructor with name.

int Bind(TaskGroup*&, const char* name);
int Bind(Task*&, const char* name);
int Bind(Task*&, int instance, const char* name);
Methods for binding to other tasks registered in the system. Each returns a pointer to the object requested. Return code of zero indicates success, -1 indicates failure or task does not exist. The Bind with instance number returns the nth instance of task group with name name. The Bind to TaskGroup returns the entire task group pointer. The Bind to task with name returns the first instance of the task group with name name.

virtual Lock(Task* t);
virtual Unlock();
Lock another task for exclusive communications. Locking a task means that only messages from this task will be processes by task t, all other will remain queued until Unlock is issued by this task.

void Send(Interface* i,Message* m)
Send a message to interface i. Two interfaces are currently supported: the Task and the BPD. Tasks are what is currently being explained, BPD are the external communicates interface.

void Send(Task* t,Message* m)
Send a message to task t.

void Send(TaskGroup* tg,Message* m)
void Send(TaskGroup* tg,int instance,Message* m)
Send a message to an entire taskgroup or to one member of the task group. When a message is sent to an entire task group, each instance of the group will receive a copy of message m.

void SendBlock(Interface* i,Message* m)
void SendBlock(TaskGroup* tg,int instance,Message* m)
void SendBlock(Task* t,Message* m)
These three methods are the same as their Send() counterparts, but the call blocks until a response comes back from the destination task.

virtual void Receive(Message*);
This is the method that gets invoked when a message needs processing in the message queue. The message is removed from the input message queue and passed to this routine for processing. Subclasses must supply this method to process messages.

Message* WaitForMessage(void);
Message* WaitForMessage(int type);
Message* WaitForMessage(Task*,int type);
Ways to block until messages arrive. WaitForMessage(void) waits for any message to appear at the input queue. WaitForMessage(int type) wait for a specific type of message to appear at the input queue from any task. The last form waits for a message to appear of a certain type from a specific task. If type is -1, then that indicates any message type.

Message* GetMessageBuffer(int type);
void FreeMessageBuffer(Message*);
Get a message buffer of type type. Free a message allocated by GetMessageBuffer().

virtual int OkToWait();
virtual void Wait();
virtual void Process();
Special method to determine when actions take place in the system. Typically only used by HiDEOS internals.


TaskBase

This is the class that controls the low level context of the task, dispatching, and general operating system functions. The user generally does not use the methods of this class directly, task calls they methods. This is a subclass of Interface.

#include "hideos/taskbase.h"

TaskBase();
Set up a process image.

StartMe();
Start the task running.

Schedule();
Suspend();
Schedule this task to run, suspend this task. Schedule adds this task to the dispatching chain. Suspend will cause this task to remove itself from the dispatching chain.

Block();
Release();
Perform the same function as Schedule() and Suspend(). A task suspended by a Block() call can only be scheduled by a call to Release(). This is a way to ensure that a task will not be woken up when it's not supposed to be.

Sleep(int ticks);
Sleep for a time of length ticks. The tick frequency is equivalant to the schedule clock frequency, which is currently 60Hz.

Dog* WatchDog(void(*func)(void*),int ticks,void* parm);
Start a watchdog and return a reference to it. The watchdog will invoke function func with parameter parm after ticks ticks.

void KillDog(Dog*);
Delete a watchdog from a previous Watchdog() call.

TaskState GetState();
Return the current process state, valid states are TaskDead, TaskRunning, TaskWaiting, and TaskBlocking. This information is not normally required by the user.

void DispatchingOff();
void DispatchingOn();
Actually turn on and off the dispatcher. This will completely stop all dispatching on HiDEOS. Subclasses can invoke this to gain exclusive use of the processor. This does not shut down interrupts, so other devices in the system will still receive interrupts.

virtual int OkToWait()=0;
virtual int Wait()=0;
virtual int Process()=0;
These three functions must be supplied by subclasses. The Task class defines these so generally the user need not worry about them. The OkToWait() function is called before a task is actually suspended to make sure it is really ok to suspend a task. A situation could arise due to race conditions where the data stuck in and the task should not suspend (suspending the task could cause it never to wake up). When a TaskBase starts running, the RunLoop() method is invoked, RunLoop loops forever calling Process() and Wait(). Process should do the processing associated with a running task, Wait() should cause the process to suspend until an event occurs. Process() and Wait() are the event loop processing routines.


Interface

This is a class that identifies subclasses. Currently two are defined in HiDEOS: Task and BPD. This can be used to identify the communications interface for facilities such as message passing.

#include "hideos/interface.h"

int GetProtocol();
Return the interface type. Current types are HIDEOS_TASK and HIDEOS_BPD.


BPD

This is a subclass of Interface. This is the external interface to HiDEOS, it provides a way for external processes to communicate with HiDEOS using the HiDEOS message system.

#include "hideos/drvBp.h"

BPD();
Create a BPD interface. This constructor internally handlers receiving of messages from HiDEOS.

BPD( void (*func)(void*), void* func_parm );
Create a BPD interface. A BPD constructor in this manner calls func with parameter func_parm when messages arrives for this BPD. Assumes that the user will take care of the incoming message.

BPD( void (*func)(void*) );
Create a BPD interface. A BPD constructor in this manner calls func with parameter of this BPD when messages arrive at this BPD input queue. Assumes that the user will take care of the incoming message.

void SetParms(BP_FUNC,void* func_parm);
Set up a new function to be called when a message has arrived at this BPD.

Message* GetMessage();
Return the message which just arrived. There is no message queue involved here, this interface receives messages one at a time.

int Receive(Message*&);
This is a blocking receive message call. The process calling this routine will block until a message arrives at the BPD. This routine should be used when the BPD is created with the constructor with no arguments. A return code of 0 indicates success.

int Bind(TD& td,int card,const char* name);
Bind td to task with name name on card card. Card 0 is usually the CPU running vxWorks, card 1 is usually the CPU running the standalone HiDEOS. The name must be a task running on the specified card. Returns 0 for success, found the name, -1 for failure.

int Send(TD& td,Message* m);
Send message m to td. The TD must be bound to a task using the Bind() call. Returns 0 if messages was successfully sent.


TD

This is a HiDEOS task descriptor. It hold information on how to sent messages to specific tasks. The Bind() functions of the BPD class will fill the data members of this class.

#include "hideos/registry.h"

TD();
Set up an invalid (unbound) task descriptor.

Interface* router
The local message router or proxy task if the TD refers to a remote interface.

Interface* dest
The interface which will be receiving messages sent via this TD.

char id;
Used to identify the location of Interface dest.


TaskGroup

A group of HiDEOS tasks sharing the same name. Every HiDEOS task is assigned to a task group. The registry system only registers task groups. A single create of a task just makes a taskgroup with one member.

#include "hideos/registry.h"

TaskGroup(const char* name,Task** t,int total);
TaskGroup(const char* name,Task* t);
Constuctor a taskgroup with with name name and one member or total members. The first takes an array of task pointer t of length total and creates a task group. The second creates a taskgroup with one member t. The register methods of the Task class usually handle creating this class instances.

Send(Message* m);
Send(int instance,Message* m);
Send message m to all tasks of the taskgroup or to a specific instance of the taskgroup.

Task* operator()(int nth);
Return a Task pointer to nth instance of the taskgroup.

int GetSize();
Get the number of task instances of the taskgroup.

const char* GetName();
Return the name of the task group.


Registry

This class manages a data mapping from character name to task. Tasks must register themselves here with a name. Tasks find other running tasks by performing a query here. Only one instance of this exists in a running HiDEOS system.

#include "hideos/registry.h"

Registry()
The constructor is called automatically at HiDEOS initialization time.

int Register(Task* t,const char* name)
int Register(Task** tg,const char* name, int total)
Register the name name with a task or taskgroup of length total. Tg is an array of task pointers of length total. All tasks in the array will share the same register name and each have a unique instance number within the group.

int Bind(TaskGroup*& tg,const char* name);
Query the list of registered names for name and return the taskgroup. Return code is 0 if the name if found and tg set.

void StartAll();
This routine is called by the system, at system initialization, to start all tasks which have been registered to be started when the dispatcher begins.


Message

The base class of all HiDEOS messages. This class acts as the message protocol header.

#include "hideos/message.h"

Message()
Message(int t)
Constructor a blank message or a message of type t. The user should never be constructing message with new. The MessagePool should be managing them.

int Type()
Return the message ID, each message type in HiDEOS has a unique ID associated with it. All messages in HiDEOS are routed and received as type Message, so this routine must be used to determine the true type of the message, which is going to be a subclass of Message.

Interface* to;
Interface* from;
Interface* token;
These are the source and destination interfaces of the message. The token is filled in if this message went through a router. If the token field is in use, then the from field problably refers to the router task and the token is the real interface that the message came from.

unsigned char card;
The board where the message came from.


Queue

A Queue manages a queue of Message instances. The put and get of messages from the queue is not thread safe, the caller must provide locking of some sort.

#include "hideos/queue.h"

Queue()
Create a Queue for Messages.

int Put(Message* m)
Message* Get()
Put a message on the back of the queue. Get the message from the front of the queue.

int Important(Message* m)
Put a message on the front of the queue.

Message* Current()
Peek at the message at the front of the queue.

int QueueSize()
Return the number of message in the queue.

Message* Find(Task* t, int type)
Find a message of type type from task t. A task of NULL indicates any task, a type of -1 indicates and message type.


MessagePool

The message pool control allocating and freeing message buffers. There is only one instance of this class in a running HiDEOS. All message buffers should be allocated and freed using this class instance.

#include "hideos/msgpool.h"

MessagePool()
Construct a message pool. HiDEOS does this automatically upon initialization.

Message* GetMessage(int type);
void FreeMessage(Message* m);
Retrieve a message buffer of type type from the pool with GetMessage. Return message m to the message pool with FreeMessage.

Message* CopyMessage(Message* m);
Return a copy of message m.

int MessageSize(int type);
Return the size in bytes of a message of type type.


Entity

An entity is basically a registered function that gets invoked at system initialization time. The only place these exist is in the global section of the configuration files in the apps free. The facility allows for sequencing system initialization functions. The constructor is the only function that the user needs to worry about.

#include "hideos/entity.h"

Entity(const char* name,INIT_FUNC func,const char** depends);
Register the function func with name name to be called at system initialization time after the functions with names in the depends array are called.


Donut

This is the dispatcher. The scheduler clock runs at 60Hz. The user should never have to manipulate the dispatcher, the taskbase class does this.

#include "hideos/dount.h"

Donut();
Donut(ServiceManager*);
Constructor the dispatcher. Only one dispatcher instance exists in the running system, HiDEOS initialization creates it.

volatile TaskBase* Current();
Return the current running taskbase.

volatile TaskBase* Rotate();
volatile TaskBase* Rewind();
Force the scheduler to switch to next/previous task on the dispatching list when it is reschedule time. Don't invoke these.

int Schedule(TaskBase* tb);
Schedule tb to run. Tb is put at the end of the dispatching chain.

int Prepend(TaskBase* tb);
Schedule tb to run next. This puts tb at the front of the dispatching chain.

int Suspend(TaskBase* tb);
This removes tb from the dispatching chain.

void Preempt();
void QuickPreempt();
Preempt() causes the current running task to suspend and removed from the dispatching chain immediately. QuickPreempt() does the same, but leaves the task on the end of the dispatching chain. Both cause a trap for a context switch.

int Size();
Return the number of tasks on the dispatching chain.

Dog* SetDog(void(*wd)(void* parm),int delay, void* parm);
void KillDog(Dog*);
void SleepDog(TaskBase*,void(*wd)(void* parm),int delay,void* parm);
Functions for installing and removing watchdogs, and sleeping.

void DispatchingOff();
void DispatchingOn();
Completely stop dispatching by stopping scheduler interrupts, Turn dispatching back on after it has been shut off.


ResourceManager

The resource manager is a globally accessible object that allow the user to locate system resources. One of instance of this class is present in a running HiDEOS system, it is created by the HiDEOS initialization routines automatically.

#include "hideos/resources.h"

ServiceManager* GetServiceManager();
Get the service manager for the system. The service manager manages board level services.

MessagePool* GetMessagePool();
Get the message pool manager for the system.

Registry* GetRegistry();
Get the system registry.

Donut* GetDonut();
Get the system dispatcher.


InterruptMsg

This is a useful message to send from interrupt handlers. Remember that messages sent from interrupt handlers must be preallocated, the message pool must not be used to allocate the message buffer. This is a subclass of Message.

#include "msg/sysmsg.h"

unsigned long status;
User defined and assigned value;

unsigned long data[5];
A simple array to set and read five unsigned longs.


LockerIRQ

This is a class to handle locking of interrupts. The class can be also performs a TAS lock, so it can be used across CPU boundaries. The class implements a spin lock if the TAS variable is not available.

#include "hideos/utils.h"

LockerIRQ()
Constructor an instance of a interrupt locker.

void Get();
Lock the interrupts and get lock the TAS variable.

void Release();
Unlock the interrupts and release the TAS variable.


Semaphore

This class implements a semaphore. The implementation is operating system specific. Under vxWorks it uses the vxWorks semLib. Under HiDEOS it is implemented as a QuickSemaphore.

#include "hideos/utils.h"

Semaphore();
Constructor an "empty" semaphore (a "given" semaphore).

Semaphore(SemType);
Constructor an semaphore initially set to SemType. SemType can be SemEmpty or SemFull.

Give();
Release the semaphore.

Take();
Try to get the semaphore. The task will block until it gets the semaphore.


QuickSemaphore

This class implements a quick semaphore. The implementation is operating system specific. Under vxWorks it uses the vxWorks semLib. Under HiDEOS, a task trying to get a locked semaphore remains on the dispatching chain but gives up the processor to the next runnable task. Each time the waiting task gets scheduled to run, it checks for the semaphore to become available.

#include "hideos/utils.h"

QuickSemaphore();
Constructor an "empty" semaphore (a "given" semaphore).

QuickSemaphore(SemType);
Constructor an semaphore initially set to SemType. SemType can be SemEmpty or SemFull.

Give();
Release the semaphore.

Take();
Try to get the semaphore. The task will not return from this call until it gets the semaphore.


Dog

A watch dog descriptor class. Setting a watchdog from the Task class returns one of these. This class describes a watchdog function to the system. The construction and setup methods of this class are called internally by the system.

#include "hideos/utils.h"

Dog();
Construct an empty watch dog descriptor. Users never invoke this.

void Setup(void(*f)(void*),void* parm, int ticks);
Setup the descriptor up for watchdog function f to be called with parameter parm after ticks ticks go by. The period of the tick is determined by the scheduling timer.

void Start();
Start the watchdog.

void Start();
Stop the watchdog.


Global Symbols

This is a description of the global symbols (variables and functions) available in a running HiDEOS system.

#include "hideos/globals.h"
#include "sys/irq.h"

typedef void* (*IRQHANDLER)(void*);

ResourceManager* hideos_resources;
This is the one instance of the resource manager in a running system.

long SysSafeRead(void* address,void* ret_addr, int size);
Attempt to read size bytes from address and place the data into ret_addr. The valid sizes are 1 (char), 2 (short), and 4 (long). This function returns 0 if the read succeeds, and a -1 if an access fault was generated. With is a very slow operation, it is intended to be used to check if devices exist in the memory space.

long SysRegisterIrq(int vector,IRQHANDLER func,void* parm,IRQHANDLER ofunc);
Register an interrupt handler for vector vector. Call func to be called with parameter parm when that interrupt occurrs. The old interrupt handler function can be returned in ofunc if it is not null.


Utility Macros

This is a description of the macros available.

#include "hideos/util_macros.h"

INT_DISABLE(int save)
Disable the interrupts and place the current level setting in save.

INT_ENABLE(int saved)
Restore the interrupt level settings to saved.

DO_TAS(int lock,int return_code)
Perform tas instruction on variable lock, return 0 if lock was not set, return 1 if lock was set.


Argonne National Laboratory Copyright Information
Jim Kowalkowski (jbk@aps.anl.gov)
updated 4/12/95