Its our intent to make this kind of application really easy shortly with an API
for DIO that works identically across boards. Actually, the API works seamless
across the ethernet so that one application can control DIO's across multiple
boards as a sort of TCP/IP DIO expander bus. For example: an application that
connects to every TS board on the local 192.168.0 network and blinks their red
leds in unison:
#include <dioctl.h>
int main(void) {
int i, j = 0, sbc[256];
char host[32];
for (i = 0; i < 256; i++) {
sprintf(host, "192.168.0.%d", i);
sbc[i] = dio_open(host);
}
while (1) {
sleep(1);
for (i = 0; i < 256; i++) if (sbc[i] > 0)
dio_set(sbc[i], "red_led", j++ & 1);
}
}
currently has the full spec to this API which should be
finished within a week or so. I can ask him to follow up with the dioctl.h
header file if anybody's curious. I'm pretty excited about it as its going to
make DIO manipulation a lot simpler and more powerful.
Our next software release for the TS7500 will include a new kernel that runs at
1000Hz instead of 100Hz which should improve response times and accuracy of
usleep().
The pipe to the 7500 FPGA register space is not extremely fast. Due to
limitations in programming the internal CPU PLLs, the FPGA interface is
actually faster when running the CPU at 200Mhz (ts7500ctl --extendedtempon)
than at 250Mhz. (50Mhz SPI vs. 37.5Mhz SPI) You may want to try this.
There is overhead in the sbus locking/unlocking, but Linux's implementation of
IPC semaphores (which sbus uses) is actually very fast. It is possible to
optimize SBUS locking cpu usage by changing from SysV IPC semaphores to Linux
futex's or by using atomic asm ops on SysV SHM segments.
Acquiring the SBUS lock is not always uncontested. Your app may have to wait,
for instance, for an SD card operation to complete transferring a block. The
sdctl process will only give up its sbuslock in the middle of an op on 8Kbyte
gaps or upon completion of a kernel request. If SD read/write access is
unpredictable in your app (for instance, you're running an FTP server that can
accept transfer at any time), this will dominate your worst case latency to
sbuslock.
You can temporarily halt all kernel requested SD operations by just holding the
sbuslock indefinitely. If you do, you must take care to either disable the
watchdog or feed it yourself in your app as holding the sbuslock will prevent
the default watchdog feeder process (ts7500ctl --autofeed 2) from running.
Also, for obvious reasons, you should not attempt SD filesystem I/O while
holding the SBUS lock. By holding the SBUS lock in this way, it is possible
for you to
halt kernel I/O processing until its convenient for your app, but you must be
careful to avoid the obvious deadlocks.
XUARTs (xuartctl) also acquires the SBUS lock 100 times per second when in
polling mode (the default). To temporarily halt XUART processing in a critical
section send the process ID the STOP signal. The XUART hardware has a large
4kbyte RX fifo to avoid missing characters. Often times, your app knows better
how often you can let xuartctl run to make sure its RX fifo does not overrun in
which case explicit scheduling of the xuartctl process via SIGSTOP/SIGCONT also
reduces CPU load. For instance, if your app is using one XUART at 9600 baud
then waking xuartctl up once per second would suffice even at 100% throughput.
Perhaps you have a device at 115200 baud will only send a bounded number of
bytes before waiting for a response, in that case you could hold off xuart
processing for minutes until you're ready for it.
Also, we've recently identified some sloppy programming in the Linux ethernet
driver for this CPU. When there is nothing connected to the ethernet, the
driver does what it calls a "patch check" once per second. This would be fine,
but it does some busy-wait CPU intensive delays which stop the entire kernel
from processing anything but the ethernet driver for 16-20mS. Obviously, this
is an unacceptable delay for a realtime application but it can be worked around
by running "ifconfig eth0 down" since the delay only happens when eth0 is up,
but without a cable connected.
Your application may be better met with a combination of FPGA + software
programming. If you'd like, we could create a FPGA load that stores DIO
captures at 1000Hz into a FIFO which can be read with SBUS burst transactions.
//Jesse Off
--- In "ignac.kolenko" <> wrote:
>
> Hi everyone, new to this group.
>
> I'm working with the TS7500 and for a project I need to be able to poll
> and/or manipulate the digital I/O lines at least 1000 times a second (perhaps
> faster), and store the state of digital I/O lines in shared memory for other
> tasks to eventually read from. The project I'm working on involves a number
> of digital I/O signals wired to external sensors whose digital levels can
> change as often as 1000 times a second, perhaps slightly more often in worst
> case scenario. I figure a 1kHz sampling rate should be easy to achieve on a
> 250Mhz processor running a lean OS like Linux.
>
> So to get familiar with the TS7500, I figured i'd do a few tests with some of
> the sample code found on the FTP site, namely the LED control app. I can
> flash the LEDs at about 4 or 5 times a second accurately (usleep() of
> 250000), but going faster than that generates less accurate timing.
>
> I would have figured a stripped down embedded kernel would allow for fairly
> accurate 1ms or 500usec delays between polls or access to hardware.
>
> I figure the overhead comes in the form of the sbus.c routines (locking, port
> access, unlocking). But doing the lock/unlock outside of the test loop
> (running the flashing routine for 10 seconds) yields similar results than
> calling the lock/unlock within the loop. The actual peek/poke code doesn't
> seem overly cumbersome compared to the lock/unlock (semaphore control), so i
> think i'll rule out this code as causing timing issues.
>
> Is usleep() a problem? Is there a better way to do sub second delay timing?
>
> Is there a simpler way to talk to the DIO lines and I/O ports that doesn't
> require the overhead of the sbus.c routines? Can any of the DIO lines
> generate an interrupt?? Would that allow for 1kHz or better sampling rate?
>
> Should I be investigating writing a driver to manage access to and polling of
> digital I/O?
>
> I noticed as well in the TS7500 resource page of embeddedarm.com that it has
> a link to a PDF for the TS7200, and the sample DIO access code in there is
> vastly different. Is that because the TS7200 is a much simpler embedded Linux
> environment?? Is there a similar document for the TS7500??
>
> Any thoughts and direction here would be very welcome.
>
> Thank you all in advance for any assistance you can provide!
>
> -ig
>
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|