How do I get rest of the pathname?

I’m experimenting with my first resource manager. I want to make calls to
the resmgr like this.

fd=open("/dev/mydevices/muliportdevice/2",O_WRONLY);

I’ve registered it and allowed it to handle everything below the mountpoint
/dev/mydevices/multiportdevice

My question is how to I find the rest of the path i.e. “/2”?
What data structure is it in?

Chris Rose <chris.rose@viasat.com> wrote:

I’m experimenting with my first resource manager. I want to make calls to
the resmgr like this.

fd=open("/dev/mydevices/muliportdevice/2",O_WRONLY);

I’ve registered it and allowed it to handle everything below the mountpoint
/dev/mydevices/multiportdevice

My question is how to I find the rest of the path i.e. “/2”?
What data structure is it in?

In your io_open(), it will be in the “path” member…

Look on www.parse.com in the book section under “download”, there’s a .tar
file that has the examples from my book. One of them is the “atoz” directory
resource manager, which should give you some hints…

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Chris Rose <chris.rose@viasat.com> wrote:

I’m experimenting with my first resource manager. I want to make calls to
the resmgr like this.

fd=open("/dev/mydevices/muliportdevice/2",O_WRONLY);

I’ve registered it and allowed it to handle everything below the mountpoint
/dev/mydevices/multiportdevice

My question is how to I find the rest of the path i.e. “/2”?
What data structure is it in?

You get a message of type io_open_t, the path is:

open_msg.connect.path

It will not be “/2” just “2”.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

In the atoz.c example, I don’t understand what you’re doing here.

“return (iofunc_open_default (ctp, msg, atoz_attrs + msg → connect.path
[0] - ‘a’, extra));”

specifically, what is (msg, atoz_attrs + msg → connect.path [0] - ‘a’)
doing?

Also, once I haved returned a file descriptor for that channel of the
multi-io card back to the client. How does the resource manager know for
later read/write calls what channel that file descriptor is associated with.



“Robert Krten” <nospam91@parse.com> wrote in message
news:a39dip$hba$1@inn.qnx.com

Chris Rose <> chris.rose@viasat.com> > wrote:
I’m experimenting with my first resource manager. I want to make calls
to
the resmgr like this.

fd=open("/dev/mydevices/muliportdevice/2",O_WRONLY);

I’ve registered it and allowed it to handle everything below the
mountpoint
/dev/mydevices/multiportdevice

My question is how to I find the rest of the path i.e. “/2”?
What data structure is it in?

In your io_open(), it will be in the “path” member…

Look on > www.parse.com > in the book section under “download”, there’s a .tar
file that has the examples from my book. One of them is the “atoz”
directory
resource manager, which should give you some hints…

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

Chris Rose <chris.rose@viasat.com> wrote:

In the atoz.c example, I don’t understand what you’re doing here.

“return (iofunc_open_default (ctp, msg, atoz_attrs + msg → connect.path
[0] - ‘a’, extra));”

specifically, what is (msg, atoz_attrs + msg → connect.path [0] - ‘a’)
doing?

It’s looking up a name in an array of attributes. That would be local
to a particular I/O manager.

Once you have the pathname, you must find/create the attribute structure
to be associated with it.

Also, once I haved returned a file descriptor for that channel of the
multi-io card back to the client. How does the resource manager know for
later read/write calls what channel that file descriptor is associated with.

iofunc_open_default() creates an OCB, inside the OCB is a pointer to
your attribute structure.

The rest of the IO_* callbacks all give you the OCB. (The library looks
this up based on the contents of the message information structure.) From
the OCB, you can get back to your attribute structure, telling you which
device this operation is being applied to.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Chris Rose <chris.rose@viasat.com> wrote:

In the atoz.c example, I don’t understand what you’re doing here.

“return (iofunc_open_default (ctp, msg, atoz_attrs + msg → connect.path
[0] - ‘a’, extra));”

specifically, what is (msg, atoz_attrs + msg → connect.path [0] - ‘a’)
doing?

It’s a “clever” hack :slight_smile:

atoz_attrs[] is an array of attribute structures.
Each element of the atoz_attrs[] represents one “file” on the virtual filesystem.
Thus, the line could be rewritten as:

(msg, &atoz_attrs [msg → connect.path [0] - ‘a’])

which really means, “the attribute structure associated with the
file given by the first letter of the pathname (which will be the character
‘a’ through ‘z’) minus the letter ‘a’ (so it now goes from 0 … 26)”

Effectively, I’m binding the appropriate attributes structure to the OCB.
“Appropriate” in this case meaning one of the 26 attributes structures.
Why are we binding the attributes structure to the OCB? So that we can
answer your next question… :slight_smile:

Also, once I haved returned a file descriptor for that channel of the
multi-io card back to the client. How does the resource manager know for
later read/write calls what channel that file descriptor is associated with.

ocb → attr

Since we bound the correct attribute structure in the io_open() call, we now
have it available for all further I/O messages, like read, write, etc.
By examining which attribute structure “ocb → attr” points to, you now know
which device that I/O message refers to.

So, in your case, you’d use the “2” after your mountpoint (the “/dev/mydevices/multiportdevice/”)
part as an index into your attribute structures, and then bind that to the OCB
using the helper routine “iofunc_open_default()” to do the actual binding for you.

Don’t forget that you can extend the attributes structure so that it contains additional
information that’s relevant to your device, e.g., serial baud rate, number of stop bits,
whatever you like…

Clear as mud? Don’t be shy about asking for more clarification…

Cheers,
-RK

“Robert Krten” <> nospam91@parse.com> > wrote in message
news:a39dip$hba$> 1@inn.qnx.com> …
Chris Rose <> chris.rose@viasat.com> > wrote:
I’m experimenting with my first resource manager. I want to make calls
to
the resmgr like this.

fd=open("/dev/mydevices/muliportdevice/2",O_WRONLY);

I’ve registered it and allowed it to handle everything below the
mountpoint
/dev/mydevices/multiportdevice

My question is how to I find the rest of the path i.e. “/2”?
What data structure is it in?

In your io_open(), it will be in the “path” member…

Look on > www.parse.com > in the book section under “download”, there’s a .tar
file that has the examples from my book. One of them is the “atoz”
directory
resource manager, which should give you some hints…

Cheers,
-RK


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

I have a question similar to this.

I have a resource manager that I’m working on that will read 96 12-bit
analog to digital converters and make the data available to a client
program. I created two pathnames “/dev/ad/ad.txt” and “/dev/ad/ad.bin” (and
plan on adding more). Since the behavior of the two virtual devices is very
similar I decided to have them share the same open(), read(), lseek() code.
During my open() code or my lseek() code I scoop up a fresh 96 A/D
conversions and then I then make the judgement in the read() function which
data to return, either textual numbers suitable for outputting to a command
line (i.e. ‘cat /dev/ad/ad.txt’) or binary suitable for use by my client
program depending upon which file has been accessed.

First question: Is this a good idea? What are the pitfalls of sharing the
bulk of the code this way other than the very small possibility that both
files were accessed simultaneously?

Second question: What is the best way to determine which pathame was
accessed to cause my open() and read() to occur? I’m looking at the attr
fields and none of them seem to work well for this. I’m currently using
attr->nbytes to decide since my two buffers are sized differently, but this
is clearly a nasty hack that you wouldn’t take home to mother.

Thanks,

Jason Farque

“Jason Farque” <jasonf@pigging.com> wrote in message
news:a3d2mc$97u$1@inn.qnx.com

I have a question similar to this.

I have a resource manager that I’m working on that will read 96 12-bit
analog to digital converters and make the data available to a client
program. I created two pathnames “/dev/ad/ad.txt” and “/dev/ad/ad.bin”
(and
plan on adding more). Since the behavior of the two virtual devices is
very
similar I decided to have them share the same open(), read(), lseek()
code.
During my open() code or my lseek() code I scoop up a fresh 96 A/D
conversions and then I then make the judgement in the read() function
which
data to return, either textual numbers suitable for outputting to a
command
line (i.e. ‘cat /dev/ad/ad.txt’) or binary suitable for use by my client
program depending upon which file has been accessed.

First question: Is this a good idea?

Yes

What are the pitfalls of sharing the
bulk of the code this way other than the very small possibility that both
files were accessed simultaneously?

As far as the resource framework is concern, it doesn’t matter that files
can be access simultanously. However you may have to protect
your own data.

Second question: What is the best way to determine which pathame was
accessed to cause my open() and read() to occur? I’m looking at the attr
fields and none of them seem to work well for this. I’m currently using
attr->nbytes to decide since my two buffers are sized differently, but
this
is clearly a nasty hack that you wouldn’t take home to mother.

If you don’t plan on having to much pathname, create an attribute
for each and resmgr_attach each of them.

Other possibility is to extend the attribute or ocb structure to hold
a special flag, that you would set during the open.

  • Mario

Thanks,

Jason Farque

Jason Farque <jasonf@pigging.com> wrote:

I have a question similar to this.

I have a resource manager that I’m working on that will read 96 12-bit
analog to digital converters and make the data available to a client
program. I created two pathnames “/dev/ad/ad.txt” and “/dev/ad/ad.bin” (and
plan on adding more). Since the behavior of the two virtual devices is very
similar I decided to have them share the same open(), read(), lseek() code.

But not the same attribute structure, right?

During my open() code or my lseek() code I scoop up a fresh 96 A/D
conversions and then I then make the judgement in the read() function which
data to return, either textual numbers suitable for outputting to a command
line (i.e. ‘cat /dev/ad/ad.txt’) or binary suitable for use by my client
program depending upon which file has been accessed.

First question: Is this a good idea? What are the pitfalls of sharing the

Excellent idea. I’ve always liked the ability to make QNX more UNIX-like than
UNIX, meaning to extend the basic concepts of “everything is a file” and “everything
can be processed with ‘vi’ and ‘grep’”.

bulk of the code this way other than the very small possibility that both
files were accessed simultaneously?

I don’t even see that as a problem; how often does your 12-bit A/D converter
sample? You could simply have the same data area out of which the devices read,
or simply attach your data area to the OCB…

Second question: What is the best way to determine which pathame was
accessed to cause my open() and read() to occur? I’m looking at the attr

There are two simple ways:
a) compare the address of “ocb → attr” against one of your two
global attributes structures (if you’ve done it that way)
b) use the inode member of “attr” as an index. Keep in mind that
inode can’t be zero.

fields and none of them seem to work well for this. I’m currently using
attr->nbytes to decide since my two buffers are sized differently, but this
is clearly a nasty hack that you wouldn’t take home to mother.

LOL! I love that expression :slight_smile:
But yes, you are correct, looking at attr->nbytes is ugly; attr->inode is
pretty clean, or just plain “attr” is clean too…

BTW, how have you registered your resmgr? is “/dev/ad” the resmgr as
a “directory” resmgr, or have you indeed registered two distinct pathnames?
If you’ve registered two distinct pathnames, then you should be able to
compare the addresses of the two distinct attributes structures that you
used in order to determine which one is which.

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

“Mario Charest” <goto@nothingness.com> wrote in message
news:a3e1n5$1nr$1@inn.qnx.com

Yes

Thought so. Good.

What are the pitfalls of sharing the
bulk of the code this way other than the very small possibility that
both
files were accessed simultaneously?

As far as the resource framework is concern, it doesn’t matter that files
can be access simultanously. However you may have to protect
your own data.

Gotcha.

Second question: What is the best way to determine which pathame was
accessed to cause my open() and read() to occur?

If you don’t plan on having to much pathname, create an attribute
for each and resmgr_attach each of them.

Sorry, I should have said. I do have separate attr structures. Actually
didn’t occur to me to try to do it with one… I’m not sure if that makes
me smart or dumb. Heh.

  • Mario

Thanks for the feedback Mario.

Jason Farque

“Robert Krten” <nospam91@parse.com> wrote in message
news:a3e3lm$3df$1@inn.qnx.com

Jason Farque <> jasonf@pigging.com> > wrote:

I have a resource manager that I’m working on that will read 96 12-bit
analog to digital converters and make the data available to a client
program. I created two pathnames “/dev/ad/ad.txt” and “/dev/ad/ad.bin”
(and
plan on adding more). Since the behavior of the two virtual devices is
very
similar I decided to have them share the same open(), read(), lseek()
code.

But not the same attribute structure, right?

In the words of Ed MacMahon, “You are correct, sir!”

First question: Is this a good idea? What are the pitfalls of sharing
the

Excellent idea. I’ve always liked the ability to make QNX more UNIX-like
than
UNIX, meaning to extend the basic concepts of “everything is a file” and
“everything
can be processed with ‘vi’ and ‘grep’”.

In my system everything is a file. I’m still trying to decide if is a Good
Idea or not. Sure it feels good, but not everything that feels good is what
you should be doing. :slight_smile:

bulk of the code this way other than the very small possibility that
both
files were accessed simultaneously?

I don’t even see that as a problem; how often does your 12-bit A/D
converter
sample? You could simply have the same data area out of which the devices
read,
or simply attach your data area to the OCB…

The raw A/D samples are put into an int array during open() or lseek() and
then sprintf’d into a separate char buffer. Since the ocb is not passed to
open() it always takes the time to construct the textual output buffer
(currently a joyous 96 calls to sprintf). Gotta figure a way around this
using the context structure or something since that ad.txt file isn’t going
to be read but once in a blue moon, but I haven’t looked into it yet.

Right now I read the 96 A/Ds when an open() or lseek() is performed. The
ultimate goal is to hit the ad.bin file up for a fresh of set of samples by
doing: lseek(file,0,SEEK_SET); read(); a maximum of 316 times a second (quit
laughing, the mean time between samples will be more like one half or one
third of that). Right now I’m simply experimenting to see if I can do it
this fast on my 133MHz AMD Elan 520 embedded system because I’m also
storing the data to a solid state disk file (big ol’ data logger).

The cue to perform my lseek(); read(); is taken from a hardware interrupt,
so for ‘bursting’ sample speeds I could construct a linked list of A/D
sample arrays or something, but right now I’m just trying to get a resource
manager going.

BTW, how have you registered your resmgr? is “/dev/ad” the resmgr as
a “directory” resmgr, or have you indeed registered two distinct
pathnames?

Two pathnames, yep.

If you’ve registered two distinct pathnames, then you should be able to
compare the addresses of the two distinct attributes structures that you
used in order to determine which one is which.

Oh yeah. Duh. It’s good to have access to smart people.

Thanks a lot.

Cheers,
-RK

Jason Farque

Jason Farque <jasonf@pigging.com> wrote:

“Robert Krten” <> nospam91@parse.com> > wrote in message
news:a3e3lm$3df$> 1@inn.qnx.com> …
Jason Farque <> jasonf@pigging.com> > wrote:

I have a resource manager that I’m working on that will read 96 12-bit
analog to digital converters and make the data available to a client
program. I created two pathnames “/dev/ad/ad.txt” and “/dev/ad/ad.bin”
(and
plan on adding more). Since the behavior of the two virtual devices is
very
similar I decided to have them share the same open(), read(), lseek()
code.

But not the same attribute structure, right?

In the words of Ed MacMahon, “You are correct, sir!”

LOL! I use that all the time!

First question: Is this a good idea? What are the pitfalls of sharing
the

Excellent idea. I’ve always liked the ability to make QNX more UNIX-like
than
UNIX, meaning to extend the basic concepts of “everything is a file” and
“everything
can be processed with ‘vi’ and ‘grep’”.

In my system everything is a file. I’m still trying to decide if is a Good
Idea or not. Sure it feels good, but not everything that feels good is what
you should be doing. > :slight_smile:

:slight_smile:

bulk of the code this way other than the very small possibility that
both
files were accessed simultaneously?

I don’t even see that as a problem; how often does your 12-bit A/D
converter
sample? You could simply have the same data area out of which the devices
read,
or simply attach your data area to the OCB…

The raw A/D samples are put into an int array during open() or lseek() and
then sprintf’d into a separate char buffer. Since the ocb is not passed to
open() it always takes the time to construct the textual output buffer
(currently a joyous 96 calls to sprintf). Gotta figure a way around this

Since you now know which attribute structure it’s using, you can do the char
buffer stuff only if it’s the “text” file version…

using the context structure or something since that ad.txt file isn’t going
to be read but once in a blue moon, but I haven’t looked into it yet.

You could reduce this dramatically. Is it a “%d” or a “%g” or what?
At the very least, you could have multiple %d or %g’s in each sprintf()

Right now I read the 96 A/Ds when an open() or lseek() is performed. The
ultimate goal is to hit the ad.bin file up for a fresh of set of samples by
doing: lseek(file,0,SEEK_SET); read(); a maximum of 316 times a second (quit
laughing, the mean time between samples will be more like one half or one
third of that). Right now I’m simply experimenting to see if I can do it
this fast on my 133MHz AMD Elan 520 embedded system because I’m also
storing the data to a solid state disk file (big ol’ data logger).

It’s a little bit of a “kludge” to have “lseek (… 0)” trigger a read. I’d
recommend a devctl(); but hey, it’s your party…

The cue to perform my lseek(); read(); is taken from a hardware interrupt,
so for ‘bursting’ sample speeds I could construct a linked list of A/D
sample arrays or something, but right now I’m just trying to get a resource
manager going.

BTW, how have you registered your resmgr? is “/dev/ad” the resmgr as
a “directory” resmgr, or have you indeed registered two distinct
pathnames?

Two pathnames, yep.

If you’ve registered two distinct pathnames, then you should be able to
compare the addresses of the two distinct attributes structures that you
used in order to determine which one is which.

Oh yeah. Duh. It’s good to have access to smart people.

Thanks a lot.

No probs!

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

Right now I read the 96 A/Ds when an open() or lseek() is performed. The
ultimate goal is to hit the ad.bin file up for a fresh of set of samples
by
doing: lseek(file,0,SEEK_SET); read(); a maximum of 316 times a second
(quit
laughing, the mean time between samples will be more like one half or one
third of that). Right now I’m simply experimenting to see if I can do it
this fast on my 133MHz AMD Elan 520 embedded system because I’m also
storing the data to a solid state disk file (big ol’ data logger).

The cue to perform my lseek(); read(); is taken from a hardware interrupt,
so for ‘bursting’ sample speeds I could construct a linked list of A/D
sample arrays or something, but right now I’m just trying to get a
resource
manager going.

You might want to investiage support pread() and pwrite(), they are not
POSIX
nor ANSI, but they are still usefull :wink:

Through these function you pass the offset, it’s like doing seek and read at
the same time.
This will get rid of the overhead of call lseek

Other way is to set the file size to 96 and to alway returns rewind to
zero at each read.

Lastlty you could stick with lseek/read which will work nice with shell
stuff
but you can also do an ioctl/devctl to get the 96 in once operation from
within your program. Best of both world !

“Robert Krten” <nospam91@parse.com> wrote in message
news:a3ep15$j2a$1@inn.qnx.com

[ snip my longwinded resource manager chit-chat ]

It’s a little bit of a “kludge” to have “lseek (… 0)” trigger a read.
I’d
recommend a devctl(); but hey, it’s your party…

Uhh… Never used devctl() before. I’m coming from the 8-bit embedded “You
guys with operating systems have it easy” background so please bear with me;
my POSIX books are in the mail (as is yours Robert, 5 wks from Amazon?
Bleh). Anyhow if I’m reading the docs correctly I can call something like
devctl( MyPrevioslyOpenedFile, DCMD_FSYS, &input_buffer,
sizeof(input_buffer), NULL ); and this would call my read? How would my
read function know the difference between a devctl() and a read()? Can you
point to some examples of this please?

Jason

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

“Jason Farque” <jasonf@pigging.com> wrote in message
news:a3f05t$o27$1@inn.qnx.com

“Robert Krten” <> nospam91@parse.com> > wrote in message
news:a3ep15$j2a$> 1@inn.qnx.com> …

[ snip my longwinded resource manager chit-chat ]

It’s a little bit of a “kludge” to have “lseek (… 0)” trigger a read.
I’d
recommend a devctl(); but hey, it’s your party…

Uhh… Never used devctl() before. I’m coming from the 8-bit embedded
“You
guys with operating systems have it easy” background so please bear with
me;
my POSIX books are in the mail (as is yours Robert, 5 wks from Amazon?
Bleh). Anyhow if I’m reading the docs correctly I can call something like
devctl( MyPrevioslyOpenedFile, DCMD_FSYS, &input_buffer,
sizeof(input_buffer), NULL ); and this would call my read? How would my
read function know the difference between a devctl() and a read()? Can
you
point to some examples of this please?

It wouldn’t call your read. You would need to add another function just
like
you added a read function. They are totaly independant.


Jason

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.

“Mario Charest” <goto@nothingness.com> wrote in message
news:a3f1p6$p2v$1@inn.qnx.com

It wouldn’t call your read. You would need to add another function just
like you added a read function. They are totaly independant.

Ah, ok I get it. Then in io_func.devctl() I’d sample my A/Ds and return the
result.

Neato. Thanks guys.

Jason Farque

Jason Farque <jasonf@pigging.com> wrote:

“Robert Krten” <> nospam91@parse.com> > wrote in message
news:a3ep15$j2a$> 1@inn.qnx.com> …

[ snip my longwinded resource manager chit-chat ]

It’s a little bit of a “kludge” to have “lseek (… 0)” trigger a read.
I’d
recommend a devctl(); but hey, it’s your party…

Uhh… Never used devctl() before. I’m coming from the 8-bit embedded “You
guys with operating systems have it easy” background so please bear with me;
my POSIX books are in the mail (as is yours Robert, 5 wks from Amazon?

That’s odd – we ship books regularly to Amazon.

Folks, call us directly, we ship the next day :slight_smile:

In the meantime, you can grab the examples for the books from www.parse.com,
go to the “books” section, and then to the “download” section. There’s an
example there of using devctl().

Cheers,
-RK

Bleh). Anyhow if I’m reading the docs correctly I can call something like
devctl( MyPrevioslyOpenedFile, DCMD_FSYS, &input_buffer,
sizeof(input_buffer), NULL ); and this would call my read? How would my
read function know the difference between a devctl() and a read()? Can you
point to some examples of this please?

Jason

Cheers,
-RK

Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at > www.parse.com> .
Email my initials at parse dot com.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.