RIOT icon indicating copy to clipboard operation
RIOT copied to clipboard

Implement the `c_oflag`: POSIX terminal interface output modes

Open jmkim opened this issue 3 years ago • 1 comments

Feature Request

POSIX (both IEEE Std 1003.1-2008 and IEEE Std 1003.1-2017) specified c_oflag; output modes for terminal interfaces.

In POSIX:

  • 11.2.3 Output Modes

    If ONLCR is set, the NL character shall be transmitted as the CR-NL character pair. If OCRNL is set, the CR character shall be transmitted as the NL character. If ONOCR is set, no CR character shall be transmitted when at column 0 (first position). If ONLRET is set, the NL character is assumed to do the carriage-return function; the column pointer shall be set to 0 and the delays specified for CR shall be used. Otherwise, the NL character is assumed to do just the line-feed function; the column pointer remains unchanged. The column pointer shall also be set to 0 if the CR character is actually transmitted.

  • Headers - <termios.h>

Some implementation examples:

Issues

Some serial monitors use CR-LF as a new line character, not just LF. GNU Screen, one of widely used serial monitor program, uses it.

In RIOT, uart already holds c_oflag: https://github.com/RIOT-OS/RIOT/blob/73ccd1e2e721bee38f958f8906ac32e5e1fceb0c/cpu/native/periph/uart.c#L112

However, nothing consider this flag. At least, STDOUT printing functions should care this (puts, DEBUG_PUTS, ...).

PR #15619 implements ONLCR, which is opened but in stale (missing review).

Expected results

a
b
c
d

Actual results

a
 b
  c
   d

Screen Shot 2022-06-30 at 15 59 08

Versions

Operating System Environment
----------------------------
         Operating System: "Debian GNU/Linux" 
                   Kernel: Linux 5.18.0-1-amd64 x86_64 unknown
             System shell: /usr/bin/dash (probably dash)
             make's shell: /usr/bin/dash (probably dash)

Installed compiler toolchains
-----------------------------
               native gcc: gcc (Debian 11.3.0-3) 11.3.0
        arm-none-eabi-gcc: arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
                  avr-gcc: missing
         mips-mti-elf-gcc: missing
           msp430-elf-gcc: missing
       riscv-none-elf-gcc: missing
  riscv64-unknown-elf-gcc: missing
     riscv-none-embed-gcc: missing
     xtensa-esp32-elf-gcc: missing
   xtensa-esp8266-elf-gcc: missing
                    clang: missing

Installed compiler libs
-----------------------
     arm-none-eabi-newlib: "3.3.0"
      mips-mti-elf-newlib: missing
        msp430-elf-newlib: missing
    riscv-none-elf-newlib: missing
riscv64-unknown-elf-newlib: missing
  riscv-none-embed-newlib: missing
  xtensa-esp32-elf-newlib: missing
xtensa-esp8266-elf-newlib: missing
                 avr-libc: missing (missing)

Installed development tools
---------------------------
                   ccache: missing
                    cmake: missing
                 cppcheck: missing
                  doxygen: 1.9.1
                      git: git version 2.36.1
                     make: GNU Make 4.3
                  openocd: Open On-Chip Debugger 0.11.0
                   python: missing
                  python2: missing
                  python3: Python 3.10.5
                   flake8: error: /usr/bin/python3: No module named flake8
               coccinelle: missing

jmkim avatar Jun 30 '22 07:06 jmkim

Related issues:

  • PR https://github.com/RIOT-OS/RIOT/pull/15619
  • PR https://github.com/RIOT-OS/RIOT/pull/4899
  • Issue https://github.com/RIOT-OS/RIOT/issues/3040
  • Issue https://github.com/RIOT-OS/RIOT/issues/12540

jmkim avatar Jun 30 '22 07:06 jmkim

Sorry for the long delay.

I have written a reply to a PR that would implement "\n" --> "\r\n" conversion. I understand that this issue is asking for the ability to configure this behavior at runtime through the POSIX API.

Note that RIOT does indeed aim to have a degree of compatibility with POSIX APIs. However, it cannot be POSIX compatible. Fundamentally, POSIX requires user space processes. This cannot be implemented without a memory management unit (MMU) (unless implementing a VM). Hence, full POSIX compliance is fundamentally impossible.

More practical: Even things that we technically could provide may not be provided, as the benefit for the cost is not considered to be worth it. (Or maybe just because nobody missed the feature enough to actually implement and upstream it.) We often try to pass on the decisions on a memory vs feature trade-off to the application developer by implementing features as optional modules. But a large configuration space can also lead to many different code paths being taken depending on settings. So too fine-grained configuration will increase the complexity of our code base and make testing impractical.

I personally think that a POSIX compatible termios.h layer to configure line ending conversion, parity and stop bits, etc. would be a lot of effort for little benefit. In fact, most UART drivers do not even support more than 8N1 mode.

Regarding a compile-time option the PR https://github.com/RIOT-OS/RIOT/pull/15619 would solve this. I am personally not really convinced that this is more useful that just configuring the host side to use just "\n" for line endings. But if there are people who say that this feature is indeed useful to them, I wouldn't oppose.

maribu avatar Aug 25 '22 09:08 maribu

https://github.com/RIOT-OS/RIOT/pull/18731 got merged if one needs LF -> CRLF conversion on UART. It doesn't support changing the behavior at run-time, though.

I close this anyway as I do not believe that there is use case to change line ending conversion at run time. Please feel free to re-open, if you have a real use case for that.

maribu avatar Jan 05 '23 12:01 maribu