[RTEMS Project] #2176: fishy behavior in termios tx task mode
RTEMS trac
trac at rtems.org
Thu Dec 18 12:35:42 UTC 2014
#2176: fishy behavior in termios tx task mode
--------------------+----------------------------
Reporter: johill | Owner: joel.sherrill
Type: defect | Status: new
Priority: low | Milestone: 5.0
Component: cpukit | Version: 4.10
Severity: normal | Resolution:
Keywords: |
--------------------+----------------------------
Changes (by sebastian.huber):
* priority: normal => low
* milestone: 4.11 => 5.0
Old description:
> I have a look around in the drivers in the various BSPs and I notice that
> none of the termios drivers appear to transmit characters at task level
> even if they are running in termios task mode. Maybe all (most) of them
> send characters in the ISR. If there was a large frame of characters to
> send then this could lock out task activity for too long.
>
> FWIW, I had a closer look at this today, and maybe something is fishy in
> the termios code when the TX part of termios runs in task driven mode. It
> seems that in task mode if the UART can accept characters immediately in
> the write routine then we wouldnt need to turn on any interrupts at all.
> The write routine would need to somehow tell termios how many characters
> it sent; presumably this would occur by calling
> rtems_termios_dequeue_characters in the driver's write function. I see in
> the code that this tries to work, rtems_termios_dequeue_characters posts
> the semaphore of termios tx and increases the characters sent count of
> termios. However after the write routine returns it goes badly.
>
> If the transmitter runs in termios TASK mode and the driver's write
> routine does not immediately enable an interrupt, then it returns to the
> code below in rtems_termios_puts and it sets the transmitter to rob_busy.
> After that the termios tx daemon proceeds to step through all of the
> characters remaining (I think that I see this in the debugger) and
> discards them because the transmitter stays in rob_busy state.
>
> It's also probably odd that termios calls the write function with
> interrupts disabled when it is in task driven mode; we could loop
> outputting a large frame of characters in the write routine at task level
> with interrupts globally disabled.
>
> if (tty->rawOutBufState == rob_idle) {
> /* check, whether XOFF has been received */
> if (!(tty->flow_ctrl & FL_ORCVXOF)) {
> (*tty->device.write)(tty->minor,
> (char
> *)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
> }
> else {
> /* remember that output has been stopped due to flow
> ctrl*/
> tty->flow_ctrl |= FL_OSTOP;
> }
> tty->rawOutBufState = rob_busy;
> }
>
> [debug]#0 rtems_termios_puts (_buf=0x9ca60, len=1, tty=0x11509c) at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:677
> [debug]#1 0x00015c68 in oproc (c=99 'c', tty=0x11509c) at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:748
> [debug]#2 0x00015d9c in rtems_termios_write (arg=0x9cad8) at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:770
> [debug]#3 0x00002ef0 in console_write (major=0, minor=0, arg=0x9cad8) at
> /home/hill/nios2-rtems/rtems/rtems-git/rtems-4.10/c/src/lib/libbsp/nios2
> /altera-sys-config/./console/console.c:171
> [debug]#4 0x0006c328 in rtems_io_write (major=0, minor=0,
> argument=0x9cad8) at /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/sapi/src/iowrite.c:47
> [debug]#5 0x00068044 in device_write (iop=0x114988, buffer=0x3366d4,
> count=44) at /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libfs/src/imfs/deviceio.c:160
> [debug]#6 0x00017ef4 in write (fd=1, buffer=0x3366d4, count=44) at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libcsupport/src/write.c:51
> [debug]#7 0x0007f078 in _write_r (ptr=0x9d638, fd=1, buf=0x3366d4,
> nbytes=44) at /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libcsupport/src/write_r.c:38
> [debug]#8 0x0006d488 in _fflush_r (ptr=0x9d638, fp=0x9d98c) at
> ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
> patched/gcc-4.1/newlib/libc/stdio/fflush.c:214
> [debug]#9 0x000754e8 in __sfvwrite_r (ptr=0x9d638, fp=0x9d98c,
> uio=0x9cbe0) at ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools
> /rtems-patched/gcc-4.1/newlib/libc/stdio/fvwrite.c:257
> [debug]#10 0x0007830c in __sprint_r (ptr=0x9d638, fp=0x20, uio=0x9cbe0)
> at ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
> patched/gcc-4.1/newlib/libc/stdio/vfprintf.c:322
> [debug]#11 0x00072fc8 in _vfprintf_r (data=0x9d638, fp=0x9d98c,
> fmt0=<value optimized out>, ap=0x0) at
> ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
> patched/gcc-4.1/newlib/libc/stdio/vfprintf.c:1501
> [debug]#12 0x0006dce8 in printf (fmt=0x1 "") at
> ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
> patched/gcc-4.1/newlib/libc/stdio/printf.c:52
> [debug]#13 0x00057de0 in bootpc_init (update_files=false, forever=true)
> at /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libnetworking/nfs/bootp_subr.c:997
> [debug]#14 0x0002960c in rtems_bsdnet_do_bootp () at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libnetworking/rtems/rtems_bootp.c:23
> [debug]#15 0x0002b218 in rtems_bsdnet_initialize_network () at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/libnetworking/rtems/rtems_glue.c:980
> [debug]#16 0x00001528 in Init (ignored=565432) at init.c:47
> [debug]#17 0x0006ccb0 in _Thread_Handler () at
> /home/hill/nios2-rtems/rtems/rtems-
> git/rtems-4.10/c/src/../../cpukit/score/src/threadhandler.c:145
> [debug]#18 0x0006cc28 in _Thread_Is_heir (the_thread=0x6cc28) at
> ../../cpukit/../../../altera-sys-
> config/lib/include/rtems/score/thread.inl:82
> [debug]Backtrace stopped: frame did not save the PC
New description:
I have a look around in the drivers in the various BSPs and I notice that
none of the termios drivers appear to transmit characters at task level
even if they are running in termios task mode. Maybe all (most) of them
send characters in the ISR. If there was a large frame of characters to
send then this could lock out task activity for too long.
FWIW, I had a closer look at this today, and maybe something is fishy in
the termios code when the TX part of termios runs in task driven mode. It
seems that in task mode if the UART can accept characters immediately in
the write routine then we wouldnt need to turn on any interrupts at all.
The write routine would need to somehow tell termios how many characters
it sent; presumably this would occur by calling
rtems_termios_dequeue_characters in the driver's write function. I see in
the code that this tries to work, rtems_termios_dequeue_characters posts
the semaphore of termios tx and increases the characters sent count of
termios. However after the write routine returns it goes badly.
If the transmitter runs in termios TASK mode and the driver's write
routine does not immediately enable an interrupt, then it returns to the
code below in rtems_termios_puts and it sets the transmitter to rob_busy.
After that the termios tx daemon proceeds to step through all of the
characters remaining (I think that I see this in the debugger) and
discards them because the transmitter stays in rob_busy state.
It's also probably odd that termios calls the write function with
interrupts disabled when it is in task driven mode; we could loop
outputting a large frame of characters in the write routine at task level
with interrupts globally disabled.
if (tty->rawOutBufState == rob_idle) {
/* check, whether XOFF has been received */
if (!(tty->flow_ctrl & FL_ORCVXOF)) {
(*tty->device.write)(tty->minor,
(char
*)&tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
}
else {
/* remember that output has been stopped due to flow
ctrl*/
tty->flow_ctrl |= FL_OSTOP;
}
tty->rawOutBufState = rob_busy;
}
[debug]#0 rtems_termios_puts (_buf=0x9ca60, len=1, tty=0x11509c) at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:677
[debug]#1 0x00015c68 in oproc (c=99 'c', tty=0x11509c) at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:748
[debug]#2 0x00015d9c in rtems_termios_write (arg=0x9cad8) at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libcsupport/src/termios.c:770
[debug]#3 0x00002ef0 in console_write (major=0, minor=0, arg=0x9cad8) at
/home/hill/nios2-rtems/rtems/rtems-git/rtems-4.10/c/src/lib/libbsp/nios2
/altera-sys-config/./console/console.c:171
[debug]#4 0x0006c328 in rtems_io_write (major=0, minor=0,
argument=0x9cad8) at /home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/sapi/src/iowrite.c:47
[debug]#5 0x00068044 in device_write (iop=0x114988, buffer=0x3366d4,
count=44) at /home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libfs/src/imfs/deviceio.c:160
[debug]#6 0x00017ef4 in write (fd=1, buffer=0x3366d4, count=44) at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libcsupport/src/write.c:51
[debug]#7 0x0007f078 in _write_r (ptr=0x9d638, fd=1, buf=0x3366d4,
nbytes=44) at /home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libcsupport/src/write_r.c:38
[debug]#8 0x0006d488 in _fflush_r (ptr=0x9d638, fp=0x9d98c) at
../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
patched/gcc-4.1/newlib/libc/stdio/fflush.c:214
[debug]#9 0x000754e8 in __sfvwrite_r (ptr=0x9d638, fp=0x9d98c,
uio=0x9cbe0) at ../../../../../../nios2-rtems/altera/altera11.0/gnu-tools
/rtems-patched/gcc-4.1/newlib/libc/stdio/fvwrite.c:257
[debug]#10 0x0007830c in __sprint_r (ptr=0x9d638, fp=0x20, uio=0x9cbe0) at
../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
patched/gcc-4.1/newlib/libc/stdio/vfprintf.c:322
[debug]#11 0x00072fc8 in _vfprintf_r (data=0x9d638, fp=0x9d98c,
fmt0=<value optimized out>, ap=0x0) at
../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
patched/gcc-4.1/newlib/libc/stdio/vfprintf.c:1501
[debug]#12 0x0006dce8 in printf (fmt=0x1 "") at
../../../../../../nios2-rtems/altera/altera11.0/gnu-tools/rtems-
patched/gcc-4.1/newlib/libc/stdio/printf.c:52
[debug]#13 0x00057de0 in bootpc_init (update_files=false, forever=true) at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libnetworking/nfs/bootp_subr.c:997
[debug]#14 0x0002960c in rtems_bsdnet_do_bootp () at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libnetworking/rtems/rtems_bootp.c:23
[debug]#15 0x0002b218 in rtems_bsdnet_initialize_network () at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/libnetworking/rtems/rtems_glue.c:980
[debug]#16 0x00001528 in Init (ignored=565432) at init.c:47
[debug]#17 0x0006ccb0 in _Thread_Handler () at
/home/hill/nios2-rtems/rtems/rtems-
git/rtems-4.10/c/src/../../cpukit/score/src/threadhandler.c:145
[debug]#18 0x0006cc28 in _Thread_Is_heir (the_thread=0x6cc28) at
../../cpukit/../../../altera-sys-
config/lib/include/rtems/score/thread.inl:82
[debug]Backtrace stopped: frame did not save the PC
--
--
Ticket URL: <http://devel.rtems.org/ticket/2176#comment:2>
RTEMS Project <http://www.rtems.org/>
RTEMS Project
More information about the bugs
mailing list