[Lldb-commits] [lldb] 21bb808 - [lldb] Support serial port parity checking
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 25 01:51:54 PDT 2021
Author: Michał Górny
Date: 2021-10-25T10:51:46+02:00
New Revision: 21bb808eb4867b35b08fa962c7c25e812fcc8836
URL: https://github.com/llvm/llvm-project/commit/21bb808eb4867b35b08fa962c7c25e812fcc8836
DIFF: https://github.com/llvm/llvm-project/commit/21bb808eb4867b35b08fa962c7c25e812fcc8836.diff
LOG: [lldb] Support serial port parity checking
Differential Revision: https://reviews.llvm.org/D112365
Added:
Modified:
lldb/include/lldb/Host/File.h
lldb/include/lldb/Host/Terminal.h
lldb/source/Host/common/File.cpp
lldb/source/Host/common/Terminal.cpp
lldb/unittests/Host/posix/TerminalTest.cpp
Removed:
################################################################################
diff --git a/lldb/include/lldb/Host/File.h b/lldb/include/lldb/Host/File.h
index c192700590a30..d10ec1fe282a1 100644
--- a/lldb/include/lldb/Host/File.h
+++ b/lldb/include/lldb/Host/File.h
@@ -439,6 +439,7 @@ class SerialPort : public NativeFile {
struct Options {
llvm::Optional<unsigned int> BaudRate = llvm::None;
llvm::Optional<Terminal::Parity> Parity = llvm::None;
+ llvm::Optional<Terminal::ParityCheck> ParityCheck = llvm::None;
llvm::Optional<unsigned int> StopBits = llvm::None;
};
diff --git a/lldb/include/lldb/Host/Terminal.h b/lldb/include/lldb/Host/Terminal.h
index ff5db4c6b9b05..81930cdf02361 100644
--- a/lldb/include/lldb/Host/Terminal.h
+++ b/lldb/include/lldb/Host/Terminal.h
@@ -28,6 +28,18 @@ class Terminal {
Mark,
};
+ enum class ParityCheck {
+ // No parity checking
+ No,
+ // Replace erraneous bytes with NUL
+ ReplaceWithNUL,
+ // Ignore erraneous bytes
+ Ignore,
+ // Mark erraneous bytes by prepending them with \xFF\x00; real \xFF
+ // is escaped to \xFF\xFF
+ Mark,
+ };
+
Terminal(int fd = -1) : m_fd(fd) {}
~Terminal() = default;
@@ -54,6 +66,8 @@ class Terminal {
llvm::Error SetParity(Parity parity);
+ llvm::Error SetParityCheck(ParityCheck parity_check);
+
llvm::Error SetHardwareFlowControl(bool enabled);
protected:
diff --git a/lldb/source/Host/common/File.cpp b/lldb/source/Host/common/File.cpp
index 27a47cab78925..daac1fef2f36d 100644
--- a/lldb/source/Host/common/File.cpp
+++ b/lldb/source/Host/common/File.cpp
@@ -794,6 +794,21 @@ SerialPort::OptionsFromURL(llvm::StringRef urlqs) {
llvm::inconvertibleErrorCode(),
"Invalid parity (must be no, even, odd, mark or space): %s",
x.str().c_str());
+ } else if (x.consume_front("parity-check=")) {
+ serial_options.ParityCheck =
+ llvm::StringSwitch<llvm::Optional<Terminal::ParityCheck>>(x)
+ .Case("no", Terminal::ParityCheck::No)
+ .Case("replace", Terminal::ParityCheck::ReplaceWithNUL)
+ .Case("ignore", Terminal::ParityCheck::Ignore)
+ // "mark" mode is not currently supported as it requires special
+ // input processing
+ // .Case("mark", Terminal::ParityCheck::Mark)
+ .Default(llvm::None);
+ if (!serial_options.ParityCheck)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Invalid parity-check (must be no, replace, ignore or mark): %s",
+ x.str().c_str());
} else if (x.consume_front("stop-bits=")) {
unsigned int stop_bits;
if (!llvm::to_integer(x, stop_bits, 10) ||
@@ -831,6 +846,11 @@ SerialPort::Create(int fd, OpenOptions options, Options serial_options,
if (llvm::Error error = term.SetParity(serial_options.Parity.getValue()))
return std::move(error);
}
+ if (serial_options.ParityCheck) {
+ if (llvm::Error error =
+ term.SetParityCheck(serial_options.ParityCheck.getValue()))
+ return std::move(error);
+ }
if (serial_options.StopBits) {
if (llvm::Error error =
term.SetStopBits(serial_options.StopBits.getValue()))
diff --git a/lldb/source/Host/common/Terminal.cpp b/lldb/source/Host/common/Terminal.cpp
index 23cd1dea114bf..1efd1bb9139d3 100644
--- a/lldb/source/Host/common/Terminal.cpp
+++ b/lldb/source/Host/common/Terminal.cpp
@@ -335,6 +335,26 @@ llvm::Error Terminal::SetParity(Terminal::Parity parity) {
#endif // #if LLDB_ENABLE_TERMIOS
}
+llvm::Error Terminal::SetParityCheck(Terminal::ParityCheck parity_check) {
+ llvm::Expected<Data> data = GetData();
+ if (!data)
+ return data.takeError();
+
+#if LLDB_ENABLE_TERMIOS
+ struct termios &fd_termios = data->m_termios;
+ fd_termios.c_iflag &= ~(IGNPAR | PARMRK | INPCK);
+
+ if (parity_check != ParityCheck::No) {
+ fd_termios.c_iflag |= INPCK;
+ if (parity_check == ParityCheck::Ignore)
+ fd_termios.c_iflag |= IGNPAR;
+ else if (parity_check == ParityCheck::Mark)
+ fd_termios.c_iflag |= PARMRK;
+ }
+ return SetData(data.get());
+#endif // #if LLDB_ENABLE_TERMIOS
+}
+
llvm::Error Terminal::SetHardwareFlowControl(bool enabled) {
llvm::Expected<Data> data = GetData();
if (!data)
diff --git a/lldb/unittests/Host/posix/TerminalTest.cpp b/lldb/unittests/Host/posix/TerminalTest.cpp
index 0313007f89e12..1cf7b9bc8f3b0 100644
--- a/lldb/unittests/Host/posix/TerminalTest.cpp
+++ b/lldb/unittests/Host/posix/TerminalTest.cpp
@@ -190,6 +190,36 @@ TEST_F(TerminalTest, SetParity) {
#endif
}
+TEST_F(TerminalTest, SetParityCheck) {
+ struct termios terminfo;
+
+ ASSERT_THAT_ERROR(m_term.SetParityCheck(Terminal::ParityCheck::No),
+ llvm::Succeeded());
+ ASSERT_EQ(tcgetattr(m_fd, &terminfo), 0);
+ EXPECT_EQ(terminfo.c_iflag & (IGNPAR | PARMRK | INPCK), 0U);
+
+ ASSERT_THAT_ERROR(
+ m_term.SetParityCheck(Terminal::ParityCheck::ReplaceWithNUL),
+ llvm::Succeeded());
+ ASSERT_EQ(tcgetattr(m_fd, &terminfo), 0);
+ EXPECT_NE(terminfo.c_iflag & INPCK, 0U);
+ EXPECT_EQ(terminfo.c_iflag & (IGNPAR | PARMRK), 0U);
+
+ ASSERT_THAT_ERROR(m_term.SetParityCheck(Terminal::ParityCheck::Ignore),
+ llvm::Succeeded());
+ ASSERT_EQ(tcgetattr(m_fd, &terminfo), 0);
+ EXPECT_NE(terminfo.c_iflag & IGNPAR, 0U);
+ EXPECT_EQ(terminfo.c_iflag & PARMRK, 0U);
+ EXPECT_NE(terminfo.c_iflag & INPCK, 0U);
+
+ ASSERT_THAT_ERROR(m_term.SetParityCheck(Terminal::ParityCheck::Mark),
+ llvm::Succeeded());
+ ASSERT_EQ(tcgetattr(m_fd, &terminfo), 0);
+ EXPECT_EQ(terminfo.c_iflag & IGNPAR, 0U);
+ EXPECT_NE(terminfo.c_iflag & PARMRK, 0U);
+ EXPECT_NE(terminfo.c_iflag & INPCK, 0U);
+}
+
TEST_F(TerminalTest, SetHardwareFlowControl) {
#if defined(CRTSCTS)
struct termios terminfo;
More information about the lldb-commits
mailing list