From owner-freebsd-hackers Tue Nov 11 05:18:25 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id FAA21505 for hackers-outgoing; Tue, 11 Nov 1997 05:18:25 -0800 (PST) (envelope-from owner-freebsd-hackers) Received: from hda.hda.com (hda-bicnet.bicnet.net [208.220.66.37]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id FAA21500 for ; Tue, 11 Nov 1997 05:18:19 -0800 (PST) (envelope-from dufault@hda.hda.com) Received: (from dufault@localhost) by hda.hda.com (8.8.5/8.8.5) id UAA20154; Mon, 10 Nov 1997 20:09:19 -0500 (EST) From: Peter Dufault Message-Id: <199711110109.UAA20154@hda.hda.com> Subject: Re: LabPC+ Driver Specifics In-Reply-To: from "Jamil J. Weatherbee" at "Nov 8, 97 09:20:15 pm" To: jamil@trojanhorse.ml.org (Jamil J. Weatherbee) Date: Mon, 10 Nov 1997 20:09:17 -0500 (EST) Cc: hackers@freebsd.org X-Mailer: ELM [version 2.4ME+ PL25 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk > I am currently in the process of writing a driver for an analog input > board and am using your labpc driver as an example (I have a labpc also). > I am kind of curious about your buffer management. It appears that you are > using the onboard fifo for buffering and depending on the user to make > bio buffers available for writing out the fifo once they open the device. > If they don't make buffers available frequently enough through read() then > you have a problem. Yes, and you'll get an error from the hardware when the FIFO overruns. > Here are some questions I have, because I think your driver is good > example and I don't feel a need to make any unnecessary mistakes in design > that conversing with you could save me. > > One thing is the AD_MICRO_PERIOD_SET, does that change the frequency for > the entire board or just one channel. Is that general enough? In my case I > have 128 channels so It is going to get pretty complex managing 128 > channels at 128 different frequencies (with one clock). There is only one clock on that board. If you have (or are implementing) independent clocks you probably have (or are implementing) independent FIFOs or other memory channels and you should handle it as separate instances of the driver, i.e., as if each is a separate board. > Secondly, I don't have a fifo, however I have interrupts driven through a > 8253 chain. I assume than the best thing is for me to pick a decent fifo > size and manage it like the labpc hardware manages its fifo. Would that be > like 512*(128/8) = 8kb? The particular board is not capable of more than > 30000 samples/s. The best solution is to implement a FIFO in software and run it at a restrictive interrupt level, as Bruce has done in the SIO driver. That is the typical and most appropriate solution for that problem. Then the FIFO size can be a config (or even ioctl) time setting. > I was thinking of implementing an AD_START and AD_STOP ioctls(), or am I > missing something? I think an AD_TRIGGER is needed and you can put it in the dataacq header. That would describe what will begin the acquisition, and the default would be AD_TRIG_IMMEDIATE (that is, as soon as read). Another would be AD_TRIG_EXTERNAL (external TTL start), and a scope-like structure for trigger level and slope. I assume this is what you mean for AD_START? I see less of a need for an AD_STOP, but maybe you can describe what it would do. I see advantages to a frame description ioctl (describe the size of a frame independent of user I/O transfer size) so you could do: open ... describe frame ... set trigger ... read a real big chunk of data in a frame with multiple reads and it stops automatically ... set trigger read frame ... etc. > > I noticed , it looks like your chaining together buffers passed to your > strategy routine. Can you breifly explain what is going on there with > tqe.next (b_actf), I realize this is part of the queue management MACROS, > but I > don't think you are actually using those. I just want a qualitative > description since I am pretty unclear on the hardware level stuff of the > labpc. I should be using the queue macros. This is a basic start chain - the I/O requests are enqueued in the chain and then the done interrupt can kick off the next transfer within the interrupt. You can now use "team" or fork a process and get double buffered transfers and soak up the overhead of resuming a user process. If you do: while (read(0, buff, N) == N) ; the system must resume your process before each read whereas if two of these processes are running the next buffer will be ready to receive the data in the done interrupt, reducing the required FIFO elasticity. > If your ad channels just start spewing when you open, then why don't you > implement readselect, why just leave it to seltrue? If your trying to > read all 8 channels this just might be useful to determine which order. Specifically, they start spewing data when you issue a read. To answer your question: the typical A-D card has a single channel list, gain list, timer, etc, and so you know the order the data will arrive in since you specified the frame. A trickier board with multiple resources or a home brew system is best handled as multiple simple boards. I've begged the question, though: If a trigger ioctl is added then there should be a read select. Then you can open multiple boards and process the one that triggers first. Any system with multiple "boards" (physical or in software as I believe you plan) with independent timers per channel will also benefit from the select. Peter -- Peter Dufault (dufault@hda.com) Realtime development, Machine control, HD Associates, Inc. Safety critical systems, Agency approval