FreeBSD programming question
J. Seth Henry
jshamlet at comcast.net
Wed Aug 6 13:20:04 PDT 2003
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 {
> long tv_sec; /* seconds */
> long tv_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 (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
> >>
> >>
> >>
> >
> >_______________________________________________
> >freebsd-questions at freebsd.org mailing list
> >http://lists.freebsd.org/mailman/listinfo/freebsd-questions
> >To unsubscribe, send any mail to "freebsd-questions-unsubscribe at freebsd.org"
> >
> >
>
More information about the freebsd-questions
mailing list