Re: FreeBSD programming question

2003-08-14 Thread Michael Conlen
select() should work for you, similar to trigering an interrupt. Instead 
of triggering an ISR select() will sleep until there's an event on the 
file descriptors. So you open() the device for the serial port and 
select() on it. When you return from select() the return value will tell 
you why you returned and you handle the situation similar to programing 
for the 8250 (read from the port to see which event).

In any case, you can select() on the file descriptors for the standard 
input and the serial port, though remember that STDIN uses buffered IO 
and open() will return an unbuffered file descriptor, which is what 
select() uses, so you need to find the unbuffered file descriptor for 
the stadard IO, which is either 0, 1 or 2, but I forget which on FreeBSD 
(I've been doing network daemons to much lately).

In any case, you create an FD_SET

fd_set mySet;
FD_ZERO(mySet);
FD_SET(fd, mySet);
where fd is the file descriptor returned from open, or the file 
descriptor for the standard input.

Use the set as a read set with select along iwth a timeout. struct 
timeval is

struct timeval {
   longtv_sec; /* seconds */
   longtv_usec;/* and microseconds */
};
if the pointer to the struct timeval is NULL then it waits forever. (or 
until a signal causes an exit).

(Note, usleep() is often implemented using select on no file descriptors 
and a timeval).

int rc;
struct timeval myTimeout;
rc = select(2, mySet, NULL, NULL, myTimeout);
This call will return when either timeval is up or there's data to read 
on your file descriptors. Be sure to check errno if select returns -1. 
When select returns the fd_set will be set to the descriptors that are 
actionable. Use FD_ISSET(fd, mySet) to see if that file descriptor is 
waiting to be actioned on (read, write, or other) until you've found all 
the ones that are ready (the number returned by select()) and do your thing.

There's a really great book called Advanced Programing in the UNIX 
environment and it will show you all the system calls you ever needed 
to know to work with UNIX, though it's light on the concurrency issues, 
but it doesn't sound like your writing multithreaded memory shared 
programs so it's no worry.

I haven't really looked at the sio driver, but I doubt it, it still 
works with the 8250, which only had one IO address (tell it what you 
want to do, read the result, tell it what you want to do, send it info, 
tell it what you want to know, read the info it has... ...programing was 
much more fun back then).



J. Seth Henry wrote:

It appears that my experience on microcontrollers is throwing me off.
I'm used to having a touch more control at the hardware level.
It sounds like I would be best served by setting up a loop that sleeps
for a certain number of milliseconds, and then looks for new data in the
serial port buffers. Knowing the amount of time per loop, I could handle
the periodic data polling as well. My largest concern was in creating a
CPU hog. I don't want to slow the system down by constantly accessing
the serial port.
It occurred to me that I may be able to deal with this another way. I
can poll the thermostat for MOST things, only the user interface
requires fairly speedy interactions. I can simply listen for the ENTER
button, and then increase the polling rate until the UI exits.
As it were, I'm poking around in the ports to see how other programs
have dealt with this.
Just out of curiousity, since I can check the driver source, does the
sio driver add any additional buffering, or does it simply read the
16byte FIFO on the serial port? Most of the messages I am expecting
should fit in that FIFO anyway.
Thanks,
Seth Henry
On Wed, 2003-08-06 at 09:58, Malcolm Kay wrote:
 

On Wed, 6 Aug 2003 07:00, J. Seth Henry wrote:
   

Not sure if this is the right list or not, but I could really use some
pointers.
How can I code trap serial port interrupts in my C program?

 

For any modern hosted system interrupt trapping and servicing is in the 
province of the system -- it should not be a userland activity.

   

For example, I want to read values from a serial device every
user-specified number of seconds, calculate some stuff and then sit for
a while. Should the serial device decide it wants to send some data
unsolicited, I would like to enter an interrupt service routine, handle
the communication, and then return to the previous loop.
 

There are a number of techniques which may or may not suit your needs;
it is not too clear just what you are trying to do.
Generally the system will provide some buffering of input so it is not usually
important that your code processes each character immediately on arrival.
In many cases using placing the select(2) system call in a loop will meet the 
needs.

In more difficult cases you may need to look at threading pthread(3) or 
forking fork(2) or vfork(2)

   

I can get the loop going by using sleep(n), but I don't know how to
write the ISR in C, and 

FreeBSD programming question

2003-08-09 Thread J. Seth Henry
Not sure if this is the right list or not, but I could really use some
pointers.

How can I code trap serial port interrupts in my C program?

For example, I want to read values from a serial device every
user-specified number of seconds, calculate some stuff and then sit for
a while. Should the serial device decide it wants to send some data
unsolicited, I would like to enter an interrupt service routine, handle
the communication, and then return to the previous loop.

I can get the loop going by using sleep(n), but I don't know how to
write the ISR in C, and (additionally) make it such that it will run on
any *nix like platform. 

Any pointers, HOWTO's, or examples would be greatly appreciated!

Thanks,
Seth

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: FreeBSD programming question

2003-08-08 Thread J. Seth Henry
That looks exactly like what I want. I need to resume programming on
either serial activity and at periodic intervals. Eventually, I plan to
toss networking into the mix, and this program will function as a
daemon, but I'm relatively new to programming for *nix (though not new
to programming in general), so I'm going to steer clear of that until I
get the basic IO working.

I've already written, and for the most part debugged, my configuration
file parser, and this was the next step. :)

When I finish, I want to be able to check the status, and control, the
HVAC system from any terminal on the network. 

Thanks again  for the help,
Seth Henry

On Wed, 2003-08-06 at 13:43, Michael Conlen wrote:
 select() should work for you, similar to trigering an interrupt. Instead 
 of triggering an ISR select() will sleep until there's an event on the 
 file descriptors. So you open() the device for the serial port and 
 select() on it. When you return from select() the return value will tell 
 you why you returned and you handle the situation similar to programing 
 for the 8250 (read from the port to see which event).
 
 In any case, you can select() on the file descriptors for the standard 
 input and the serial port, though remember that STDIN uses buffered IO 
 and open() will return an unbuffered file descriptor, which is what 
 select() uses, so you need to find the unbuffered file descriptor for 
 the stadard IO, which is either 0, 1 or 2, but I forget which on FreeBSD 
 (I've been doing network daemons to much lately).
 
 In any case, you create an FD_SET
 
 fd_set mySet;
 FD_ZERO(mySet);
 FD_SET(fd, mySet);
 
 where fd is the file descriptor returned from open, or the file 
 descriptor for the standard input.
 
 Use the set as a read set with select along iwth a timeout. struct 
 timeval is
 
 struct timeval {
 longtv_sec; /* seconds */
 longtv_usec;/* and microseconds */
 };
 
 if the pointer to the struct timeval is NULL then it waits forever. (or 
 until a signal causes an exit).
 
 (Note, usleep() is often implemented using select on no file descriptors 
 and a timeval).
 
 int rc;
 struct timeval myTimeout;
 rc = select(2, mySet, NULL, NULL, myTimeout);
 
 This call will return when either timeval is up or there's data to read 
 on your file descriptors. Be sure to check errno if select returns -1. 
 When select returns the fd_set will be set to the descriptors that are 
 actionable. Use FD_ISSET(fd, mySet) to see if that file descriptor is 
 waiting to be actioned on (read, write, or other) until you've found all 
 the ones that are ready (the number returned by select()) and do your thing.
 
 There's a really great book called Advanced Programing in the UNIX 
 environment and it will show you all the system calls you ever needed 
 to know to work with UNIX, though it's light on the concurrency issues, 
 but it doesn't sound like your writing multithreaded memory shared 
 programs so it's no worry.
 
 I haven't really looked at the sio driver, but I doubt it, it still 
 works with the 8250, which only had one IO address (tell it what you 
 want to do, read the result, tell it what you want to do, send it info, 
 tell it what you want to know, read the info it has... ...programing was 
 much more fun back then).
 
 
 
 
 J. Seth Henry wrote:
 
 It appears that my experience on microcontrollers is throwing me off.
 I'm used to having a touch more control at the hardware level.
 
 It sounds like I would be best served by setting up a loop that sleeps
 for a certain number of milliseconds, and then looks for new data in the
 serial port buffers. Knowing the amount of time per loop, I could handle
 the periodic data polling as well. My largest concern was in creating a
 CPU hog. I don't want to slow the system down by constantly accessing
 the serial port.
 
 It occurred to me that I may be able to deal with this another way. I
 can poll the thermostat for MOST things, only the user interface
 requires fairly speedy interactions. I can simply listen for the ENTER
 button, and then increase the polling rate until the UI exits.
 
 As it were, I'm poking around in the ports to see how other programs
 have dealt with this.
 
 Just out of curiousity, since I can check the driver source, does the
 sio driver add any additional buffering, or does it simply read the
 16byte FIFO on the serial port? Most of the messages I am expecting
 should fit in that FIFO anyway.
 
 Thanks,
 Seth Henry
 
 On Wed, 2003-08-06 at 09:58, Malcolm Kay wrote:
   
 
 On Wed, 6 Aug 2003 07:00, J. Seth Henry wrote:
 
 
 Not sure if this is the right list or not, but I could really use some
 pointers.
 
 How can I code trap serial port interrupts in my C program?
 
   
 
 For any modern hosted system interrupt trapping and servicing is in the 
 province of the system -- it should not be a userland activity.
 
 
 
 For example, I want to read values from a serial device every
 

Re: FreeBSD programming question

2003-08-07 Thread J. Seth Henry
It appears that my experience on microcontrollers is throwing me off.
I'm used to having a touch more control at the hardware level.

It sounds like I would be best served by setting up a loop that sleeps
for a certain number of milliseconds, and then looks for new data in the
serial port buffers. Knowing the amount of time per loop, I could handle
the periodic data polling as well. My largest concern was in creating a
CPU hog. I don't want to slow the system down by constantly accessing
the serial port.

It occurred to me that I may be able to deal with this another way. I
can poll the thermostat for MOST things, only the user interface
requires fairly speedy interactions. I can simply listen for the ENTER
button, and then increase the polling rate until the UI exits.

As it were, I'm poking around in the ports to see how other programs
have dealt with this.

Just out of curiousity, since I can check the driver source, does the
sio driver add any additional buffering, or does it simply read the
16byte FIFO on the serial port? Most of the messages I am expecting
should fit in that FIFO anyway.

Thanks,
Seth Henry

On Wed, 2003-08-06 at 09:58, Malcolm Kay wrote:
 On Wed, 6 Aug 2003 07:00, J. Seth Henry wrote:
  Not sure if this is the right list or not, but I could really use some
  pointers.
 
  How can I code trap serial port interrupts in my C program?
 
 
 For any modern hosted system interrupt trapping and servicing is in the 
 province of the system -- it should not be a userland activity.
 
  For example, I want to read values from a serial device every
  user-specified number of seconds, calculate some stuff and then sit for
  a while. Should the serial device decide it wants to send some data
  unsolicited, I would like to enter an interrupt service routine, handle
  the communication, and then return to the previous loop.
 
 There are a number of techniques which may or may not suit your needs;
 it is not too clear just what you are trying to do.
 
 Generally the system will provide some buffering of input so it is not usually
 important that your code processes each character immediately on arrival.
 
 In many cases using placing the select(2) system call in a loop will meet the 
 needs.
 
 In more difficult cases you may need to look at threading pthread(3) or 
 forking fork(2) or vfork(2)
 
 
  I can get the loop going by using sleep(n), but I don't know how to
  write the ISR in C, and (additionally) make it such that it will run on
  any *nix like platform.
 
 You might be able to do something at system level by adding your driver to the 
 kernel possibly as a kernel module. This is not generally the way to go if 
 userland alternatives work and it certainly will be very operating system and 
 platform specific possibly even requiring significant editing from one OS 
 version to the next.
 
 
  Any pointers, HOWTO's, or examples would be greatly appreciated!
 
  Thanks,
  Seth
 
 
 Malcolm Kay
 

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: FreeBSD programming question

2003-08-06 Thread Rui Lopes
On Ter, 2003-08-05 at 22:30, J. Seth Henry wrote: 
 Not sure if this is the right list or not, but I could really use some
 pointers.
 
 How can I code trap serial port interrupts in my C program?

You can't attach to interrupts in a userland program, but you can access
serial ports by opening any of /dev/cuaaX device files.


 For example, I want to read values from a serial device every
 user-specified number of seconds, calculate some stuff and then sit for
 a while. Should the serial device decide it wants to send some data
 unsolicited, I would like to enter an interrupt service routine, handle
 the communication, and then return to the previous loop.
 
 I can get the loop going by using sleep(n), but I don't know how to
 write the ISR in C, and (additionally) make it such that it will run on
 any *nix like platform. 
 
 Any pointers, HOWTO's, or examples would be greatly appreciated!


Take a look at these (in no particular order):

- http://www.easysw.com/~mike/serial/
  Serial Programming Guide for POSIX Operating Systems

- http://en.tldp.org/HOWTO/Serial-Programming-HOWTO/index.html
  Serial Programming HOWTO

- http://www.freebsd.org/handbook/serialcomms.html
  Serial Communications

- sio(4)


Good luck!
Rui Lopes

___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]


Re: FreeBSD programming question

2003-08-06 Thread Malcolm Kay
On Wed, 6 Aug 2003 07:00, J. Seth Henry wrote:
 Not sure if this is the right list or not, but I could really use some
 pointers.

 How can I code trap serial port interrupts in my C program?


For any modern hosted system interrupt trapping and servicing is in the 
province of the system -- it should not be a userland activity.

 For example, I want to read values from a serial device every
 user-specified number of seconds, calculate some stuff and then sit for
 a while. Should the serial device decide it wants to send some data
 unsolicited, I would like to enter an interrupt service routine, handle
 the communication, and then return to the previous loop.

There are a number of techniques which may or may not suit your needs;
it is not too clear just what you are trying to do.

Generally the system will provide some buffering of input so it is not usually
important that your code processes each character immediately on arrival.

In many cases using placing the select(2) system call in a loop will meet the 
needs.

In more difficult cases you may need to look at threading pthread(3) or 
forking fork(2) or vfork(2)


 I can get the loop going by using sleep(n), but I don't know how to
 write the ISR in C, and (additionally) make it such that it will run on
 any *nix like platform.

You might be able to do something at system level by adding your driver to the 
kernel possibly as a kernel module. This is not generally the way to go if 
userland alternatives work and it certainly will be very operating system and 
platform specific possibly even requiring significant editing from one OS 
version to the next.


 Any pointers, HOWTO's, or examples would be greatly appreciated!

 Thanks,
 Seth


Malcolm Kay
___
[EMAIL PROTECTED] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-questions
To unsubscribe, send any mail to [EMAIL PROTECTED]