Jump to content

Que handling

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
2 replies to this topic

#1
Rudd

Rudd

    Newbie

  • Members
  • Pip
  • 3 posts
Hi,

I have a little challenge for you all. I am coding using a fairly limited language with a syntax similar to that of C. It does not support pointers or structures, but it does however support some rather sophisticated multitasking facilities, like semaphores, ques and RPC. It has a global and a module scope. You cannot declare an array inside a function, only single variables. The array has to be either module or global.

Now my problem is, I have a function for reading a value from an external device. This function is blocking, and the code that I am going to use this value in, is running in foreground. I cannot put a blocking function inside a foreground task. This foreground task runs every 250ms, and there is many instances of it.

Now, I am able to create a new task that can perform this reading in the background, but I am a little clueless as to how I could do this the most efficient way.

The synopsises of the que functions are as follows:
QueOpen(STRING queName, INT mode)

mode can be either:
  • 0 - Open existing que
  • 1 - Create new que
  • 2 - Attempt to open new que and create if it is not existing
Returns the que handle.

QueWrite(INT queHandle, INT type, STRING string) 
type and string can be anything you want. These have no meaning to the que.

QueRead(INT queHandle, INT type, STRING string, INT mode)
string and type will get their respective values from the que, mode has two valid values:
  • 0 - None blocking mode
  • 1 - Wait for an element to come into the Que if it's empty.
This removes the element from the que.

QuePeek(INT queHandle, INT type, STRING string, INT mode)
  • 1 - Search for a matching string (string)
  • 2 - Search for a matching number (type)
  • 4 - Search for a matching string and use case-sensitive search (string)
  • 8 - If the element is found, remove it from the que
  • 16 - Search the que, in order, for the element at the offset specified by Type
These can also be OR'd together to combine them.

QueLength(queHandle)
Get the length of the que

QueClose(queHandle)
Closes the cue

I need to find a way to put in some elements in the que from the continously running forground task based on a parameter supplied to it, read the que from a continously running task that performs the reading of the value from the external device, put it back in the que and I'll have to read it back into the forground task.

Any suggestions or ideas on how to accomplish this?

Thanks

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
It is really hard to offer guidance given you have not stated what the language is, and the restrictions you have offered mean many of the conventional solutions cannot be proposed, and you haven't stated what features are available. Do you have some sort of event trigger model that can be used? Can the continuously running process pause to perform the required activities? Does your language support threading?

Everything appears to be handled by function calls, so it would seem like you just need to have something call the appropriate functions. What options you have really depend on what your language supports.
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Rudd

Rudd

    Newbie

  • Members
  • Pip
  • 3 posts
Hi,

The language is called CiCode. It's part of a SCADA package delivered by Citect Pty, and typically used in industrial environments. CitectSCADA. It basically consists of an editor environement, and a runtime environment. You create graphics pages with symbols and objects, that can have code expressions attached to them. This is the code that runs in the foreground, and there may be 50 objects using the same function for displaying information.

There are four page events:
  • On page entry
  • On page shown
  • While page shown
  • On page exit

I guess these are pretty self explainatory.

There also are some other events that it is possible to run user defined events triggered by user defined tags and expressions. This is a little more cumbersome, though, so I'd rather use page events.

The language, or rather, environment supports pre-emptive multitasking. The task continously running in the foreground cannot be paused, though I can spawn a new task which runs in the background if I want to.

The way I was thinking to go about this was something like this:


/*

 * This should be called 'On page entry'

 */

FUNCTION TaskLauncher()

	TaskNew("ReadService","",1); // Spawns a new task

END


/*

 * This should run until I exit the page

 */

FUNCTION ReadService()

	STRING result;


	WHILE 1 DO	

		// Look at element in que

		result = TagRead(someTagFoundInQue); // This one can only be called in a background task

		// Write value back in que

		SleepMS(250); // Sleep 250 milliseconds		

	END

END


/* 

 * This is called by an object on the graphics page every 250 ms

 * 	which is the page scan time.

 */

INT FUNCTION ForegroundTask(STRING baseTag)

	// Take baseTag and append some more text, then place in que

	// Also, this function must look at the que and in some way check

	// if the tag has been read by the service and written back

END

Maybe if I use two ques, one for the tags that are to be read, and one for the tags that already are read. I just need to be able to have some contol over what the foreground task put into the que all the time, maybe it takes some seconds to read a tag placed in the que, and then by the time the tag is read, the forground function may have put the same tag for reading 5 times, and so has other instances of the function that also have tags for reading.

The reason for reading the tags continously is for real time updating from the process value coming from the external device.