mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 11:44:53 +08:00
Merge branch 'new_api' of github.com:wjwwood/serial into new_api
Conflicts: .gitignore
This commit is contained in:
commit
520ccb54f4
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,3 +24,4 @@ wiped
|
|||||||
msg_gen
|
msg_gen
|
||||||
srv_gen
|
srv_gen
|
||||||
doc/html
|
doc/html
|
||||||
|
*sublime-workspace
|
||||||
|
|||||||
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.4.6)
|
|||||||
|
|
||||||
set(ROS_ROOT $ENV{ROS_ROOT})
|
set(ROS_ROOT $ENV{ROS_ROOT})
|
||||||
|
|
||||||
option(SERIAL_BUILD_WIHOUT_ROS "Build without ROS?" OFF)
|
option(SERIAL_BUILD_WIHOUT_ROS "Build without ROS?" ON)
|
||||||
|
|
||||||
if(DEFINED ROS_ROOT AND NOT SERIAL_BUILD_WIHOUT_ROS)
|
if(DEFINED ROS_ROOT AND NOT SERIAL_BUILD_WIHOUT_ROS)
|
||||||
# Build with ROS
|
# Build with ROS
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -99,6 +100,20 @@ struct Timeout {
|
|||||||
write_timeout_constant(write_timeout_constant_),
|
write_timeout_constant(write_timeout_constant_),
|
||||||
write_timeout_multiplier(write_timeout_multiplier_)
|
write_timeout_multiplier(write_timeout_multiplier_)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Convenience function to generate Timeout structs using a
|
||||||
|
* single absolute timeout.
|
||||||
|
*
|
||||||
|
* \param timeout A long that defines the time in milliseconds until a
|
||||||
|
* timeout occurs after a call to read or write is made.
|
||||||
|
*
|
||||||
|
* \return Timeout struct that represents this simple timeout provided.
|
||||||
|
*/
|
||||||
|
static Timeout simpleTimeout(long timeout) {
|
||||||
|
return Timeout(0, timeout, 0, timeout, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*! Number of milliseconds between bytes received to timeout on. */
|
/*! Number of milliseconds between bytes received to timeout on. */
|
||||||
int32_t inter_byte_timeout;
|
int32_t inter_byte_timeout;
|
||||||
/*! A constant number of milliseconds to wait after calling read. */
|
/*! A constant number of milliseconds to wait after calling read. */
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"word_wrap": "on",
|
||||||
|
"wrap_width": 80,
|
||||||
"folders":
|
"folders":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|||||||
@ -371,47 +371,65 @@ inline void get_time_now(struct timespec &time)
|
|||||||
size_t
|
size_t
|
||||||
Serial::SerialImpl::read (uint8_t *buf, size_t size)
|
Serial::SerialImpl::read (uint8_t *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
// If the port is not open, throw
|
||||||
if (!is_open_) {
|
if (!is_open_) {
|
||||||
throw PortNotOpenedException ("Serial::read");
|
throw PortNotOpenedException ("Serial::read");
|
||||||
}
|
}
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
struct timeval timeout;
|
// Setup the total_timeout timeval
|
||||||
timeout.tv_sec = timeout_.read_timeout_constant / 1000;
|
// This timeout is maximum time before a timeout after read is called
|
||||||
timeout.tv_usec = static_cast<int> (timeout_.read_timeout_constant % 1000);
|
struct timeval total_timeout;
|
||||||
timeout.tv_usec *= 1000; // To convert to micro seconds
|
// Calculate total timeout in milliseconds t_c + (t_m * N)
|
||||||
|
long total_timeout_ms = timeout_.read_timeout_constant;
|
||||||
|
total_timeout_ms += timeout_.read_timeout_multiplier*static_cast<long>(size);
|
||||||
|
total_timeout.tv_sec = total_timeout_ms / 1000;
|
||||||
|
total_timeout.tv_usec = static_cast<int>(total_timeout_ms % 1000);
|
||||||
|
total_timeout.tv_usec *= 1000; // To convert to micro seconds
|
||||||
|
// Setup the inter byte timeout
|
||||||
|
struct timeval inter_byte_timeout;
|
||||||
|
inter_byte_timeout.tv_sec = timeout_.inter_byte_timeout / 1000;
|
||||||
|
inter_byte_timeout.tv_usec =
|
||||||
|
static_cast<int> (timeout_.inter_byte_timeout % 1000);
|
||||||
|
inter_byte_timeout.tv_usec *= 1000; // To convert to micro seconds
|
||||||
while (bytes_read < size) {
|
while (bytes_read < size) {
|
||||||
|
// Setup the select timeout timeval
|
||||||
|
struct timeval timeout;
|
||||||
|
// If the total_timeout is less than the inter_byte_timeout
|
||||||
|
if (total_timeout.tv_sec < inter_byte_timeout.tv_sec
|
||||||
|
|| (total_timeout.tv_sec == inter_byte_timeout.tv_sec
|
||||||
|
&& total_timeout.tv_usec < inter_byte_timeout.tv_sec))
|
||||||
|
{
|
||||||
|
// Then set the select timeout to use the total time
|
||||||
|
timeout = total_timeout;
|
||||||
|
} else {
|
||||||
|
// Else set the select timeout to use the inter byte time
|
||||||
|
timeout = inter_byte_timeout;
|
||||||
|
}
|
||||||
FD_ZERO (&readfds);
|
FD_ZERO (&readfds);
|
||||||
FD_SET (fd_, &readfds);
|
FD_SET (fd_, &readfds);
|
||||||
// On Linux the timeout struct is updated by select to contain the time
|
|
||||||
// left on the timeout to make looping easier, but on other platforms this
|
|
||||||
// does not occur.
|
|
||||||
#if !defined(__linux__)
|
|
||||||
// Begin timing select
|
// Begin timing select
|
||||||
struct timespec start, end;
|
struct timespec start, end;
|
||||||
get_time_now(start);
|
get_time_now (start);
|
||||||
#endif
|
// Call select to block for serial data or a timeout
|
||||||
// Do the select
|
|
||||||
int r = select (fd_ + 1, &readfds, NULL, NULL, &timeout);
|
int r = select (fd_ + 1, &readfds, NULL, NULL, &timeout);
|
||||||
#if !defined(__linux__)
|
|
||||||
// Calculate difference and update the structure
|
// Calculate difference and update the structure
|
||||||
get_time_now(end);
|
get_time_now (end);
|
||||||
// Calculate the time select took
|
// Calculate the time select took
|
||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
diff.tv_sec = end.tv_sec - start.tv_sec;
|
diff.tv_sec = end.tv_sec - start.tv_sec;
|
||||||
diff.tv_usec = static_cast<int> ((end.tv_nsec - start.tv_nsec) / 1000);
|
diff.tv_usec = static_cast<int> ((end.tv_nsec - start.tv_nsec) / 1000);
|
||||||
// Update the timeout
|
// Update the timeout
|
||||||
if (timeout.tv_sec <= diff.tv_sec) {
|
if (total_timeout.tv_sec <= diff.tv_sec) {
|
||||||
timeout.tv_sec = 0;
|
total_timeout.tv_sec = 0;
|
||||||
} else {
|
} else {
|
||||||
timeout.tv_sec -= diff.tv_sec;
|
total_timeout.tv_sec -= diff.tv_sec;
|
||||||
}
|
}
|
||||||
if (timeout.tv_usec <= diff.tv_usec) {
|
if (total_timeout.tv_usec <= diff.tv_usec) {
|
||||||
timeout.tv_usec = 0;
|
total_timeout.tv_usec = 0;
|
||||||
} else {
|
} else {
|
||||||
timeout.tv_usec -= diff.tv_usec;
|
total_timeout.tv_usec -= diff.tv_usec;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Figure out what happened by looking at select's response 'r'
|
// Figure out what happened by looking at select's response 'r'
|
||||||
/** Error **/
|
/** Error **/
|
||||||
@ -431,7 +449,7 @@ Serial::SerialImpl::read (uint8_t *buf, size_t size)
|
|||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
// Make sure our file descriptor is in the ready to read list
|
// Make sure our file descriptor is in the ready to read list
|
||||||
if (FD_ISSET (fd_, &readfds)) {
|
if (FD_ISSET (fd_, &readfds)) {
|
||||||
// This should be non-blocking returning only what is avaialble now
|
// This should be non-blocking returning only what is available now
|
||||||
// Then returning so that select can block again.
|
// Then returning so that select can block again.
|
||||||
ssize_t bytes_read_now =
|
ssize_t bytes_read_now =
|
||||||
::read (fd_, buf + bytes_read, size - bytes_read);
|
::read (fd_, buf + bytes_read, size - bytes_read);
|
||||||
@ -785,7 +803,7 @@ Serial::SerialImpl::getDSR ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Serial::SerialImpl::getRI()
|
Serial::SerialImpl::getRI ()
|
||||||
{
|
{
|
||||||
if (is_open_ == false) {
|
if (is_open_ == false) {
|
||||||
throw PortNotOpenedException ("Serial::getRI");
|
throw PortNotOpenedException ("Serial::getRI");
|
||||||
@ -795,7 +813,7 @@ Serial::SerialImpl::getRI()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Serial::SerialImpl::getCD()
|
Serial::SerialImpl::getCD ()
|
||||||
{
|
{
|
||||||
if (is_open_ == false) {
|
if (is_open_ == false) {
|
||||||
throw PortNotOpenedException ("Serial::getCD");
|
throw PortNotOpenedException ("Serial::getCD");
|
||||||
@ -805,7 +823,7 @@ Serial::SerialImpl::getCD()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::readLock()
|
Serial::SerialImpl::readLock ()
|
||||||
{
|
{
|
||||||
int result = pthread_mutex_lock(&this->read_mutex);
|
int result = pthread_mutex_lock(&this->read_mutex);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -814,7 +832,7 @@ Serial::SerialImpl::readLock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::readUnlock()
|
Serial::SerialImpl::readUnlock ()
|
||||||
{
|
{
|
||||||
int result = pthread_mutex_unlock(&this->read_mutex);
|
int result = pthread_mutex_unlock(&this->read_mutex);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -823,7 +841,7 @@ Serial::SerialImpl::readUnlock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::writeLock()
|
Serial::SerialImpl::writeLock ()
|
||||||
{
|
{
|
||||||
int result = pthread_mutex_lock(&this->write_mutex);
|
int result = pthread_mutex_lock(&this->write_mutex);
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -832,7 +850,7 @@ Serial::SerialImpl::writeLock()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::writeUnlock()
|
Serial::SerialImpl::writeUnlock ()
|
||||||
{
|
{
|
||||||
int result = pthread_mutex_unlock(&this->write_mutex);
|
int result = pthread_mutex_unlock(&this->write_mutex);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user