AW: [uClinux-dev] Multiple channels on QSPI, using mcf_qspi.c driver
Edgar Weigand
edgar.weigand at hess.de
Fri Oct 5 02:05:09 EDT 2007
Hey Bob,
have you ever tried using SPI polling mode?
ioctl(dev, QSPIIOCS_POLL_MOD, 1); // use polling mode only
We also had racing conditions when using interrupts with SPI since
you're able to start a new SPI transfer before the last one has
been finished.
Our system locked up exactly after 14hours in a simple app with 2
SPI channels activ when using interrupt. Since we changed to
polling mode only we never had any unexspected system hangs due
to SPI. At the moment we use 5 SPI channels simultaneous in a
multithreaded app where the SPI is triggered from various trheads.
Hope it helps, we are using uClinux 2.4.20 with MCF5282. I think the
actual mcf_qspi.c driver has changed meanwhile.
Regards,
Edgar
-----Ursprüngliche Nachricht-----
Von: Bob Grimes [mailto:rsg.uclinux at gmail.com]
Gesendet: Donnerstag, 4. Oktober 2007 00:44
An: uClinux Mailing List
Betreff: [uClinux-dev] Multiple channels on QSPI, using mcf_qspi.c
driver
I have been using the mcf_qspi.c QSPI driver on several mcf5329
Coldfire boards, both the Freescale/LogicPD evaluation board and our
custom hardware, and it has largely worked fine - when using only one
minor device - specifically, minor number 0. However, now that I am
using several separate minor numbers, I get occasional, mysterious
hangs, but never on minor number 0! When I say "hangs", I mean that
the call to write never seems to return.
For example, I open and use them something like this:
int dev0;
int dev5;
...
int main(...) {
...
dev0 = open("/dev/qspi0", O_RDWR);
dev5 = open("/dev/qspi5", O_RDWR);
...
printf("Writing 0\n");
numWritten0 = write(dev0, outbuffer0, num0);
printf("Writing 5\n");
numWritten5 = write(dev5, outbuffer5, num5);
printf("Finished writing\n");
...
Here is the output:
Writing 0
Writing 5
Note, no "Finished writing". If I break out of the code (while using
a BDM debugger), the processor is almost always in the idle task - in
other words, the rest of the system seems fine.
The first write _always_ works - at least, I've never seen it fail.
The second write, however, fails more often than not, but it does
succeed 20-30% of the time. The order of the writes don't matter
either. However, if a write to dev5 actually does succeed, it seems
to work for the duration of the program; in other words, it either
crashes the first time write is called, or it never fails.
I think the problem is in the following snippet of code, where I've
added two printk's to illustrate my theory.
printk("qspi_write: Sleeping\n"); /* RSG */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
save_flags(flag); cli();
#else
local_irq_save(flag);
#endif
QDLYR |= QDLYR_SPE;
sleep_on(&wqueue);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
restore_flags(flag);
#else
local_irq_restore(flag);
#endif
printk("qspi_write: Waking up\n"); /* RSG */
Sure enough, the first printk gets executed, but the second never
seems to get hit. So I'm guessing it's stuck waiting for an interrupt
that is lost somehow.
Anyone have any ideas or similar experiences?
Thanks,
-Bob
More information about the uClinux-dev
mailing list