Commit 9c29783bfc17aef37b4cde583204ca6103e8b8c6

Authored by Geoffrey Hunter
1 parent 5a48f672

Added baud rate configure unit tests.

include/CppLinuxSerial/SerialPort.hpp
@@ -22,11 +22,13 @@ @@ -22,11 +22,13 @@
22 namespace mn { 22 namespace mn {
23 namespace CppLinuxSerial { 23 namespace CppLinuxSerial {
24 24
25 -/// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class 25 + /// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class
26 enum class BaudRate { 26 enum class BaudRate {
27 - none,  
28 - b9600,  
29 - b57600 27 + B_9600,
  28 + B_38400,
  29 + B_57600,
  30 + B_115200,
  31 + CUSTOM
30 }; 32 };
31 33
32 enum class State { 34 enum class State {
@@ -69,7 +71,7 @@ namespace mn { @@ -69,7 +71,7 @@ namespace mn {
69 71
70 /// \brief Configures the tty device as a serial port. 72 /// \brief Configures the tty device as a serial port.
71 /// \warning Device must be open (valid file descriptor) when this is called. 73 /// \warning Device must be open (valid file descriptor) when this is called.
72 - void ConfigureDeviceAsSerialPort(); 74 + void ConfigureTermios();
73 75
74 //! @brief Closes the COM port. 76 //! @brief Closes the COM port.
75 void Close(); 77 void Close();
src/SerialPort.cpp
@@ -41,37 +41,13 @@ namespace CppLinuxSerial { @@ -41,37 +41,13 @@ namespace CppLinuxSerial {
41 void SerialPort::SetDevice(const std::string& device) 41 void SerialPort::SetDevice(const std::string& device)
42 { 42 {
43 device_ = device; 43 device_ = device;
44 - ConfigureDeviceAsSerialPort(); 44 + ConfigureTermios();
45 } 45 }
46 46
47 void SerialPort::SetBaudRate(BaudRate baudRate) 47 void SerialPort::SetBaudRate(BaudRate baudRate)
48 { 48 {
49 -  
50 - // Get current termios struct  
51 - termios myTermios = this->GetTermios();  
52 -  
53 - switch(baudRate)  
54 - {  
55 - case BaudRate::none:  
56 - // Error, baud rate has not been set yet  
57 - throw std::runtime_error("Baud rate for '" + device_ + "' cannot be set to none.");  
58 - break;  
59 - case BaudRate::b9600:  
60 - cfsetispeed(&myTermios, B9600);  
61 - cfsetospeed(&myTermios, B9600);  
62 - break;  
63 - case BaudRate::b57600:  
64 - cfsetispeed(&myTermios, B57600);  
65 - cfsetospeed(&myTermios, B57600);  
66 - break;  
67 - }  
68 -  
69 - // Save back to file  
70 - this->SetTermios(myTermios);  
71 -  
72 - // Setting the baudrate must of been successful, so we can now store this  
73 - // new value internally. This must be done last!  
74 baudRate_ = baudRate; 49 baudRate_ = baudRate;
  50 + ConfigureTermios();
75 } 51 }
76 52
77 void SerialPort::Open() 53 void SerialPort::Open()
@@ -102,7 +78,7 @@ namespace CppLinuxSerial { @@ -102,7 +78,7 @@ namespace CppLinuxSerial {
102 throw std::runtime_error("Could not open device " + device_ + ". Is the device name correct and do you have read/write permission?"); 78 throw std::runtime_error("Could not open device " + device_ + ". Is the device name correct and do you have read/write permission?");
103 } 79 }
104 80
105 - ConfigureDeviceAsSerialPort(); 81 + ConfigureTermios();
106 82
107 std::cout << "COM port opened successfully." << std::endl; 83 std::cout << "COM port opened successfully." << std::endl;
108 84
@@ -120,45 +96,13 @@ namespace CppLinuxSerial { @@ -120,45 +96,13 @@ namespace CppLinuxSerial {
120 this->SetTermios(settings); 96 this->SetTermios(settings);
121 } 97 }
122 98
123 - void SerialPort::ConfigureDeviceAsSerialPort() 99 + void SerialPort::ConfigureTermios()
124 { 100 {
125 std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl; 101 std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl;
126 102
127 //================== CONFIGURE ==================// 103 //================== CONFIGURE ==================//
128 104
129 - termios tty = this->GetTermios();  
130 - /*struct termios tty;  
131 - memset(&tty, 0, sizeof(tty));  
132 -  
133 - // Get current settings (will be stored in termios structure)  
134 - if(tcgetattr(this->fileDesc, &tty) != 0)  
135 - {  
136 - // Error occurred  
137 - this->sp->PrintError(SmartPrint::Ss() << "Could not get terminal attributes for \"" << this->filePath << "\" - " << strerror(errno));  
138 - //return false;  
139 - return;  
140 - }*/  
141 -  
142 - //========================= SET UP BAUD RATES =========================//  
143 -  
144 - // this->SetBaudRate(BaudRate::b57600);  
145 -  
146 - /*  
147 - switch(this->baudRate)  
148 - {  
149 - case BaudRates::none:  
150 - // Error, baud rate has not been set yet  
151 - this->sp->PrintError(SmartPrint::Ss() << "Baud rate for \"" << this->filePath << "\" has not been set.");  
152 - return;  
153 - case BaudRates::b9600:  
154 - cfsetispeed(&tty, B9600);  
155 - cfsetospeed(&tty, B9600);  
156 - break;  
157 - case BaudRates::b57600:  
158 - cfsetispeed(&tty, B57600);  
159 - cfsetospeed(&tty, B57600);  
160 - break;  
161 - }*/ 105 + termios tty = GetTermios();
162 106
163 //================= (.c_cflag) ===============// 107 //================= (.c_cflag) ===============//
164 108
@@ -170,6 +114,32 @@ namespace CppLinuxSerial { @@ -170,6 +114,32 @@ namespace CppLinuxSerial {
170 tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) 114 tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
171 115
172 116
  117 + //===================== BAUD RATE =================//
  118 +
  119 + switch(baudRate_) {
  120 + case BaudRate::B_9600:
  121 + cfsetispeed(&tty, B9600);
  122 + cfsetospeed(&tty, B9600);
  123 + break;
  124 + case BaudRate::B_38400:
  125 + cfsetispeed(&tty, B38400);
  126 + cfsetospeed(&tty, B38400);
  127 + break;
  128 + case BaudRate::B_57600:
  129 + cfsetispeed(&tty, B57600);
  130 + cfsetospeed(&tty, B57600);
  131 + break;
  132 + case BaudRate::B_115200:
  133 + cfsetispeed(&tty, B115200);
  134 + cfsetospeed(&tty, B115200);
  135 + break;
  136 + case BaudRate::CUSTOM:
  137 + // See https://gist.github.com/kennethryerson/f7d1abcf2633b7c03cf0
  138 + throw std::runtime_error("Custom baud rate not yet supported.");
  139 + default:
  140 + throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized.");
  141 + }
  142 +
173 //===================== (.c_oflag) =================// 143 //===================== (.c_oflag) =================//
174 144
175 tty.c_oflag = 0; // No remapping, no delays 145 tty.c_oflag = 0; // No remapping, no delays
@@ -180,7 +150,7 @@ namespace CppLinuxSerial { @@ -180,7 +150,7 @@ namespace CppLinuxSerial {
180 // c_cc[WMIN] sets the number of characters to block (wait) for when read() is called. 150 // c_cc[WMIN] sets the number of characters to block (wait) for when read() is called.
181 // Set to 0 if you don't want read to block. Only meaningful when port set to non-canonical mode 151 // Set to 0 if you don't want read to block. Only meaningful when port set to non-canonical mode
182 //tty.c_cc[VMIN] = 1; 152 //tty.c_cc[VMIN] = 1;
183 - this->SetNumCharsToWait(1); 153 + SetNumCharsToWait(1);
184 154
185 // c_cc[VTIME] sets the inter-character timer, in units of 0.1s. 155 // c_cc[VTIME] sets the inter-character timer, in units of 0.1s.
186 // Only meaningful when port is set to non-canonical mode 156 // Only meaningful when port is set to non-canonical mode
@@ -219,21 +189,19 @@ namespace CppLinuxSerial { @@ -219,21 +189,19 @@ namespace CppLinuxSerial {
219 }*/ 189 }*/
220 } 190 }
221 191
222 - void SerialPort::SetNumCharsToWait(uint32_t numCharsToWait)  
223 - { 192 + void SerialPort::SetNumCharsToWait(uint32_t numCharsToWait) {
224 // Get current termios struct 193 // Get current termios struct
225 - termios myTermios = this->GetTermios(); 194 + termios myTermios = GetTermios();
226 195
227 // Save the number of characters to wait for 196 // Save the number of characters to wait for
228 // to the control register 197 // to the control register
229 myTermios.c_cc[VMIN] = numCharsToWait; 198 myTermios.c_cc[VMIN] = numCharsToWait;
230 199
231 // Save termios back 200 // Save termios back
232 - this->SetTermios(myTermios); 201 + SetTermios(myTermios);
233 } 202 }
234 203
235 - void SerialPort::Write(const std::string& data)  
236 - { 204 + void SerialPort::Write(const std::string& data) {
237 if(fileDesc_ == 0) { 205 if(fileDesc_ == 0) {
238 //this->sp->PrintError(SmartPrint::Ss() << ); 206 //this->sp->PrintError(SmartPrint::Ss() << );
239 //return false; 207 //return false;
test/unit/BasicTests.cpp
@@ -53,16 +53,43 @@ namespace { @@ -53,16 +53,43 @@ namespace {
53 EXPECT_EQ(true, true); 53 EXPECT_EQ(true, true);
54 } 54 }
55 55
  56 + TEST_F(BasicTests, BaudRateSetCorrectly) {
  57 + SerialPort serialPort0(device0_, BaudRate::B_57600);
  58 + serialPort0.Open();
  59 + auto retVal = TestUtil::Exec("stty -a -F " + device0_);
  60 + EXPECT_NE(std::string::npos, retVal.find("speed 57600 baud"));
  61 +
  62 + serialPort0.SetBaudRate(BaudRate::B_115200);
  63 + retVal = TestUtil::Exec("stty -a -F " + device0_);
  64 + EXPECT_NE(std::string::npos, retVal.find("speed 115200 baud"));
  65 + }
  66 +
56 TEST_F(BasicTests, CanOpen) { 67 TEST_F(BasicTests, CanOpen) {
57 - SerialPort serialPort0(device0_, BaudRate::b57600); 68 + SerialPort serialPort0(device0_, BaudRate::B_57600);
58 serialPort0.Open(); 69 serialPort0.Open();
59 } 70 }
60 71
61 TEST_F(BasicTests, ReadWrite) { 72 TEST_F(BasicTests, ReadWrite) {
62 - SerialPort serialPort0(device0_, BaudRate::b57600); 73 + SerialPort serialPort0(device0_, BaudRate::B_57600);
  74 + serialPort0.Open();
  75 +
  76 + SerialPort serialPort1(device1_, BaudRate::B_57600);
  77 + serialPort1.Open();
  78 +
  79 + serialPort0.Write("Hello");
  80 +
  81 + std::string readData;
  82 + serialPort1.Read(readData);
  83 +
  84 + ASSERT_EQ("Hello", readData);
  85 + }
  86 +
  87 +
  88 + TEST_F(BasicTests, ReadWriteDiffBaudRates) {
  89 + SerialPort serialPort0(device0_, BaudRate::B_9600);
63 serialPort0.Open(); 90 serialPort0.Open();
64 91
65 - SerialPort serialPort1(device1_, BaudRate::b57600); 92 + SerialPort serialPort1(device1_, BaudRate::B_57600);
66 serialPort1.Open(); 93 serialPort1.Open();
67 94
68 serialPort0.Write("Hello"); 95 serialPort0.Write("Hello");