Skip to content
This repository was archived by the owner on Feb 11, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 26 additions & 26 deletions examples/cpp/device_info/device_info_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static constexpr uint32_t BAUDRATE = 115200;
////////////////////////////////////////////////////////////////////////////////

// Custom logging handler callback
void logCallback(void* _user, const microstrain_log_level _level, const char* _format, va_list _args);
void logCallback(void* _user, const microstrain_log_level _level, const microstrain_log_component_id component, const char* _format, va_list _args);

// Common device initialization procedure
void initializeDevice(mip::Interface& _device);
Expand All @@ -70,18 +70,18 @@ int main(const int argc, const char* argv[])
MICROSTRAIN_LOG_INIT(&logCallback, MICROSTRAIN_LOG_LEVEL_INFO, nullptr);

// Initialize the connection
MICROSTRAIN_LOG_INFO("Initializing the connection.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Initializing the connection.\n");
microstrain::connections::SerialConnection connection(PORT_NAME, BAUDRATE);

MICROSTRAIN_LOG_INFO("Connecting to the device on port %s with %d baudrate.\n", PORT_NAME, BAUDRATE);
MICROSTRAIN_LOG_INFO(nullptr, "Connecting to the device on port %s with %d baudrate.\n", PORT_NAME, BAUDRATE);

// Open the connection to the device
if (!connection.connect())
{
terminate(&connection, "Could not open the connection!\n");
}

MICROSTRAIN_LOG_INFO("Initializing the device interface.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Initializing the device interface.\n");
mip::Interface device(
&connection, // Connection for the device
mip::C::mip_timeout_from_baudrate(BAUDRATE), // Set the base timeout for commands (milliseconds)
Expand All @@ -107,7 +107,7 @@ int main(const int argc, const char* argv[])
/// @param _format Printf-style format string for the message
/// @param _args Variable argument list containing message parameters
///
void logCallback(void* _user, const microstrain_log_level _level, const char* _format, va_list _args)
void logCallback(void* _user, const microstrain_log_level _level, const microstrain_log_component_id component, const char* _format, va_list _args)
{
// Unused parameter
(void)_user;
Expand All @@ -117,7 +117,7 @@ void logCallback(void* _user, const microstrain_log_level _level, const char* _f
case MICROSTRAIN_LOG_LEVEL_FATAL:
case MICROSTRAIN_LOG_LEVEL_ERROR:
{
fprintf(stderr, "%s: ", microstrain_logging_level_name(_level));
fprintf(stderr, "%s: [%s] ", microstrain_logging_get_component_name(component), microstrain_logging_level_name(_level));
vfprintf(stderr, _format, _args);
break;
}
Expand All @@ -126,7 +126,7 @@ void logCallback(void* _user, const microstrain_log_level _level, const char* _f
case MICROSTRAIN_LOG_LEVEL_DEBUG:
case MICROSTRAIN_LOG_LEVEL_TRACE:
{
fprintf(stdout, "%s: ", microstrain_logging_level_name(_level));
fprintf(stdout, "%s: [%s] ", microstrain_logging_get_component_name(component), microstrain_logging_level_name(_level));
vfprintf(stdout, _format, _args);
break;
}
Expand All @@ -152,7 +152,7 @@ void initializeDevice(mip::Interface& _device)
{
// Ping the device
// Note: This is a good first step to make sure the device is present
MICROSTRAIN_LOG_INFO("Pinging the device.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Pinging the device.\n");
mip::CmdResult cmdResult = mip::commands_base::ping(_device);
if (!cmdResult.isAck())
{
Expand All @@ -161,15 +161,15 @@ void initializeDevice(mip::Interface& _device)

// Set the device to Idle
// Note: This is good to do during setup as high data traffic can cause commands to fail
MICROSTRAIN_LOG_INFO("Setting the device to idle.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Setting the device to idle.\n");
cmdResult = mip::commands_base::setIdle(_device);
if (!cmdResult.isAck())
{
terminate(_device, cmdResult, "Could not set the device to idle!\n");
}

// Print device info to make sure the correct device is being used
MICROSTRAIN_LOG_INFO("Getting the device information.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Getting the device information.\n");
mip::commands_base::BaseDeviceInfo deviceInfo;
cmdResult = mip::commands_base::getDeviceInfo(_device, &deviceInfo);
if (!cmdResult.isAck())
Expand All @@ -190,14 +190,14 @@ void initializeDevice(mip::Interface& _device)
patch
);

MICROSTRAIN_LOG_INFO("-------- Device Information --------\n");
MICROSTRAIN_LOG_INFO("%-16s | %.16s\n", "Name", deviceInfo.model_name);
MICROSTRAIN_LOG_INFO("%-16s | %.16s\n", "Model Number", deviceInfo.model_number);
MICROSTRAIN_LOG_INFO("%-16s | %.16s\n", "Serial Number", deviceInfo.serial_number);
MICROSTRAIN_LOG_INFO("%-16s | %.16s\n", "Lot Number", deviceInfo.lot_number);
MICROSTRAIN_LOG_INFO("%-16s | %.16s\n", "Options", deviceInfo.device_options);
MICROSTRAIN_LOG_INFO("%-16s | %16s\n", "Firmware Version", firmwareVersion);
MICROSTRAIN_LOG_INFO("------------------------------------\n");
MICROSTRAIN_LOG_INFO(nullptr, "-------- Device Information --------\n");
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %.16s\n", "Name", deviceInfo.model_name);
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %.16s\n", "Model Number", deviceInfo.model_number);
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %.16s\n", "Serial Number", deviceInfo.serial_number);
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %.16s\n", "Lot Number", deviceInfo.lot_number);
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %.16s\n", "Options", deviceInfo.device_options);
MICROSTRAIN_LOG_INFO(nullptr, "%-16s | %16s\n", "Firmware Version", firmwareVersion);
MICROSTRAIN_LOG_INFO(nullptr, "------------------------------------\n");
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -218,33 +218,33 @@ void terminate(microstrain::Connection* _connection, const char* _message, const
{
if (_successful)
{
MICROSTRAIN_LOG_INFO("%s", _message);
MICROSTRAIN_LOG_INFO(nullptr, "%s", _message);
}
else
{
MICROSTRAIN_LOG_ERROR("%s", _message);
MICROSTRAIN_LOG_ERROR(nullptr, "%s", _message);
}
}

if (!_connection)
{
// Create the device interface with a connection or set it after creation
MICROSTRAIN_LOG_ERROR("Connection not set for the device interface. Cannot close the connection.\n");
MICROSTRAIN_LOG_ERROR(nullptr, "Connection not set for the device interface. Cannot close the connection.\n");
}
else
{
if (_connection->isConnected())
{
MICROSTRAIN_LOG_INFO("Closing the connection.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Closing the connection.\n");

if (!_connection->disconnect())
{
MICROSTRAIN_LOG_ERROR("Failed to close the connection!\n");
MICROSTRAIN_LOG_ERROR(nullptr, "Failed to close the connection!\n");
}
}
}

MICROSTRAIN_LOG_INFO("Exiting the program.\n");
MICROSTRAIN_LOG_INFO(nullptr, "Exiting the program.\n");

#ifdef _WIN32
// Keep the console open on Windows
Expand Down Expand Up @@ -274,10 +274,10 @@ void terminate(mip::Interface& _device, const mip::CmdResult _cmdResult, const c
{
va_list args;
va_start(args, _format);
MICROSTRAIN_LOG_ERROR_V(_format, args);
MICROSTRAIN_LOG_ERROR_V(nullptr, _format, args);
va_end(args);

MICROSTRAIN_LOG_ERROR("Command Result: (%d) %s.\n", _cmdResult.value, _cmdResult.name());
MICROSTRAIN_LOG_ERROR(nullptr, "Command Result: (%d) %s.\n", _cmdResult.value, _cmdResult.name());

// Get the connection pointer that was set during device initialization
microstrain::Connection* connection = static_cast<microstrain::Connection*>(_device.userPointer());
Expand Down
51 changes: 29 additions & 22 deletions src/c/microstrain/connections/serial/serial_port.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "serial_port.h"

#include <microstrain/logging.h>

#if defined MICROSTRAIN_PLATFORM_WINDOWS
#include <ctype.h>
#include <stdlib.h>
Expand All @@ -15,6 +13,11 @@

#define INVALID_HANDLE_VALUE -1


MICROSTRAIN_LOGGING_IMPLEMENT_COMPONENT(microstrain_serial_port)
#define MICROSTRAIN_SERIAL_PORT_LOG(LEVEL, ...) MICROSTRAIN_LOG_##LEVEL(MICROSTRAIN_LOGGING_ID(microstrain_serial_port), __VA_ARGS__)


speed_t baud_rate_to_speed(int baud_rate)
{
switch(baud_rate)
Expand Down Expand Up @@ -73,7 +76,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
if (port_str == NULL)
return false;

MICROSTRAIN_LOG_DEBUG("Opening serial port %s at %d\n", port_str, baudrate);
MICROSTRAIN_SERIAL_PORT_LOG(DEBUG, "Opening serial port %s at %d\n", port_str, baudrate);

#if defined MICROSTRAIN_PLATFORM_WINDOWS
BOOL ready;
Expand Down Expand Up @@ -118,14 +121,14 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
// Check for an invalid handle
if (port->handle == INVALID_HANDLE_VALUE)
{
MICROSTRAIN_LOG_ERROR("Unable to open com port (%d)\n", last_error);
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to open com port (%d)\n", last_error);
return false;
}

// Set up the com port buffer sizes
if (SetupComm(port->handle, COM_PORT_BUFFER_SIZE, COM_PORT_BUFFER_SIZE) == 0)
{
MICROSTRAIN_LOG_ERROR("Unable to setup com port buffer size (%d)\n", last_error);
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to setup com port buffer size (%d)\n", last_error);
CloseHandle(port->handle);
port->handle = INVALID_HANDLE_VALUE;
return false;
Expand All @@ -151,7 +154,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
// Close the serial port, mutex, and exit
if (!ready)
{
MICROSTRAIN_LOG_ERROR("Unable to get com state\n");
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to get com state\n");
CloseHandle(port->handle);
port->handle = INVALID_HANDLE_VALUE;
return false;
Expand All @@ -169,7 +172,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
// Close the serial port and exit
if (!ready)
{
MICROSTRAIN_LOG_ERROR("Unable to set com state\n");
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to set com state\n");
CloseHandle(port->handle);
port->handle = INVALID_HANDLE_VALUE;
return false;
Expand All @@ -184,20 +187,20 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)

if (port->handle < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to open port (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to open port (%d): %s\n", errno, strerror(errno));
return false;
}

if (ioctl(port->handle, TIOCEXCL) < 0)
{
MICROSTRAIN_LOG_WARN("Unable to set exclusive mode on serial port (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(WARN, "Unable to set exclusive mode on serial port (%d): %s\n", errno, strerror(errno));
}

// Set up baud rate and other serial device options
struct termios serial_port_settings;
if (tcgetattr(port->handle, &serial_port_settings) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to get serial port settings (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to get serial port settings (%d): %s\n", errno, strerror(errno));
close(port->handle);
port->handle = -1;
return false;
Expand All @@ -206,7 +209,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
#if defined MICROSTRAIN_PLATFORM_LINUX
if (cfsetispeed(&serial_port_settings, baud_rate_to_speed(baudrate)) < 0 || cfsetospeed(&serial_port_settings, baud_rate_to_speed(baudrate)) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to set baud rate (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to set baud rate (%d): %s\n", errno, strerror(errno));
close(port->handle);
port->handle = -1;
return false;
Expand All @@ -226,7 +229,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
// Persist the settings
if (tcsetattr(port->handle, TCSANOW, &serial_port_settings) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to save serial port settings (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to save serial port settings (%d): %s\n", errno, strerror(errno));
close(port->handle);
port->handle = -1;
return false;
Expand All @@ -236,7 +239,7 @@ bool serial_port_open(serial_port* port, const char* port_str, int baudrate)
speed_t speed = baudrate;
if (ioctl(port->handle, IOSSIOSPEED, &speed) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to set baud rate (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to set baud rate (%d): %s\n", errno, strerror(errno));
close(port->handle);
port->handle = -1;
return false;
Expand Down Expand Up @@ -278,20 +281,20 @@ bool serial_port_set_baudrate(serial_port* port, int baudrate)
struct termios serial_port_settings;
if (tcgetattr(port->handle, &serial_port_settings) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to get serial port settings (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to get serial port settings (%d): %s\n", errno, strerror(errno));
return false;
}

if (cfsetispeed(&serial_port_settings, baud_rate_to_speed(baudrate)) < 0 || cfsetospeed(&serial_port_settings, baud_rate_to_speed(baudrate)) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to set baud rate (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to set baud rate (%d): %s\n", errno, strerror(errno));
return false;
}

// Persist the settings
if (tcsetattr(port->handle, TCSANOW, &serial_port_settings) < 0)
{
MICROSTRAIN_LOG_ERROR("Unable to save serial port settings (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Unable to save serial port settings (%d): %s\n", errno, strerror(errno));
return false;
}
#elif defined MICROSTRAIN_PLATFORM_APPLE
Expand Down Expand Up @@ -350,9 +353,13 @@ bool serial_port_write(serial_port* port, const void* buffer, size_t num_bytes,
*bytes_written = write(port->handle, buffer, num_bytes);

if (*bytes_written == num_bytes)
{
return true;
}
else if (*bytes_written == (size_t)-1)
MICROSTRAIN_LOG_ERROR("Failed to write serial data (%d): %s\n", errno, strerror(errno));
{
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Failed to write serial data (%d): %s\n", errno, strerror(errno));
}

#endif // MICROSTRAIN_PLATFORM_WINDOWS

Expand All @@ -376,7 +383,7 @@ bool serial_port_read(serial_port* port, void* buffer, size_t num_bytes, int wai
DWORD last_error = GetLastError();
if (last_error != 0)
{
MICROSTRAIN_LOG_ERROR("Failed to read serial port. Error: %lx\n", last_error);
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Failed to read serial port. Error: %lx\n", last_error);
serial_port_close(port);
return false;
}
Expand Down Expand Up @@ -404,18 +411,18 @@ bool serial_port_read(serial_port* port, void* buffer, size_t num_bytes, int wai
// Keep reading and polling while there is still data available
if (poll_status == -1)
{
MICROSTRAIN_LOG_ERROR("Failed to poll serial port (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Failed to poll serial port (%d): %s\n", errno, strerror(errno));
return false;
}
else if (poll_fd.revents & POLLHUP)
{
MICROSTRAIN_LOG_ERROR("Poll encountered HUP, closing device");
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Poll encountered HUP, closing device");
serial_port_close(port);
return false;
}
else if (poll_fd.revents & POLLERR || poll_fd.revents & POLLNVAL)
{
MICROSTRAIN_LOG_ERROR("Poll encountered error\n");
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Poll encountered error\n");
return false;
}
else if (poll_status > 0 && poll_fd.revents & POLLIN)
Expand All @@ -424,7 +431,7 @@ bool serial_port_read(serial_port* port, void* buffer, size_t num_bytes, int wai

if (local_bytes_read == (ssize_t)-1 && errno != EAGAIN)
{
MICROSTRAIN_LOG_ERROR("Failed to read serial data (%d): %s\n", errno, strerror(errno));
MICROSTRAIN_SERIAL_PORT_LOG(ERROR, "Failed to read serial data (%d): %s\n", errno, strerror(errno));
return false;
}
if (local_bytes_read >= 0)
Expand Down
3 changes: 3 additions & 0 deletions src/c/microstrain/connections/serial/serial_port.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#pragma once

#include <microstrain/platform.h>
#include <microstrain/logging.h>

MICROSTRAIN_LOGGING_DECLARE_COMPONENT(microstrain_serial_port)

#if defined MICROSTRAIN_PLATFORM_WINDOWS

Expand Down
Loading
Loading