Merge pull request 'feature/IO' (#32) from feature/IO into main

Reviewed-on: https://git.intern.spaceteamaachen.de/ALPAKA/sta-core/pulls/32
Reviewed-by: carlwachter <carlwachter@noreply.git.intern.spaceteamaachen.de>
This commit is contained in:
dario 2024-07-14 17:15:20 +00:00
commit f0dd514bdd
11 changed files with 327 additions and 80 deletions

3
.gitignore vendored
View File

@ -10,6 +10,9 @@
Debug/ Debug/
Release/ Release/
!include/sta/debug/
!src/debug/
# Doxygen # Doxygen
docs/html docs/html
docs/latex docs/latex

View File

@ -15,34 +15,46 @@ namespace sta
/** /**
* @brief Debug print message. * @brief Debug print message.
* *
* @param ... See @ref sta::PrintableUART::print * @param ... See @ref sta::Printable::print
* *
* @ingroup sta_core_debug * @ingroup sta_core_debug
*/ */
# define STA_DEBUG_PRINT(...) sta::Debug->print(__VA_ARGS__) # define STA_DEBUG_PRINT(...) sta::Debug->print(__VA_ARGS__)
/** /**
* @brief Debug print message followed by new-line to UART. * @brief Debug print message followed by new-line to the printable.
* *
* @param ... See @ref sta::PrintableUART::println * @param ... See @ref sta::Printable::println
* *
* @ingroup sta_core_debug * @ingroup sta_core_debug
*/ */
# define STA_DEBUG_PRINTLN(...) sta::Debug->println(__VA_ARGS__) # define STA_DEBUG_PRINTLN(...) sta::Debug->println(__VA_ARGS__)
/** /**
* @brief Formatted debug printing with new-line. * @brief Formatted debug printing with new-line.
* *
* @param fmt See @ref sta::PrintableUART::printf * @param fmt See @ref sta::Printable::printf
* @param ... See @ref sta::PrintableUART::printf * @param ... See @ref sta::Printable::printf
*
* @ingroup sta_core_debug
*/ */
# define STA_DEBUG_PRINTF(fmt, ...) sta::Debug->printf(fmt, __VA_ARGS__) # define STA_DEBUG_PRINTF(fmt, ...) sta::Debug->printf(fmt, __VA_ARGS__)
/**
* @brief Read data via printable.
*
* @param ... See @ref sta::Printable::read
*
* @ingroup sta_core_debug
*/
# define STA_DEBUG_READ(buffer, length) sta::Debug->read(buffer, length)
#else // !STA_DEBUGGING_ENABLED #else // !STA_DEBUGGING_ENABLED
# define STA_DEBUG_PRINT(...) ((void)0) # define STA_DEBUG_PRINT(...) ((void)0)
# define STA_DEBUG_PRINTLN(...) ((void)0) # define STA_DEBUG_PRINTLN(...) ((void)0)
# define STA_DEBUG_PRINTF(fmt, ...) ((void)0) # define STA_DEBUG_PRINTF(fmt, ...) ((void)0)
# define STA_DEBUG_READ(buffer, length) ((void)0)
#endif // STA_DEBUGGING_ENABLED #endif // STA_DEBUGGING_ENABLED

View File

@ -40,62 +40,70 @@ namespace sta
/** /**
* @brief Print single character. * @brief Print single character.
* *
* @param c Character to print * @param c Character to print
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(char c); void print(char c, bool newline = false);
/** /**
* @brief Print boolean value. * @brief Print boolean value.
* *
* @param b Boolean value * @param b Boolean value
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(bool b); void print(bool b, bool newline = false);
/** /**
* @brief Print floating point value. * @brief Print floating point value.
* *
* @param d Floating point value * @param d Floating point value
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(double d); void print(double d, bool newline = false);
/** /**
* @brief Print integer in selected base. * @brief Print integer in selected base.
* *
* @param num 8-bit unsigned integer * @param num 8-bit unsigned integer
* @param base Integer base * @param base Integer base
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(uint8_t num, IntegerBase base = IntegerBase::DEC); void print(uint8_t num, IntegerBase base = IntegerBase::DEC, bool newline = false);
/** /**
* @brief Print integer in selected base. * @brief Print integer in selected base.
* *
* @param num 16-bit unsigned integer * @param num 16-bit unsigned integer
* @param base Integer base * @param base Integer base
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(uint16_t num, IntegerBase base = IntegerBase::DEC); void print(uint16_t num, IntegerBase base = IntegerBase::DEC, bool newline = false);
/** /**
* @brief Print integer in selected base. * @brief Print integer in selected base.
* *
* @param num 32-bit unsigned integer * @param num 32-bit unsigned integer
* @param base Integer base * @param base Integer base
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(uint32_t num, IntegerBase base = IntegerBase::DEC); void print(uint32_t num, IntegerBase base = IntegerBase::DEC, bool newline = false);
/** /**
* @brief Print c-string. * @brief Print c-string.
* *
* @param str Null terminated string * @param str Null terminated string
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(const char * str); void print(const char * str, bool newline = false);
/** /**
* @brief Print string. * @brief Print string.
* *
* @param str String buffer * @param str String buffer
* @param length String length * @param length String length
* @param newline If true, send a \r\n to start a new line.
*/ */
virtual void print(const char * str, size_t length) = 0; virtual void print(const char * str, size_t length, bool newline = false) = 0;
/** /**
* @brief Print new-line. * @brief Print new-line.
@ -161,7 +169,38 @@ namespace sta
* @param length String length * @param length String length
*/ */
void println(const char * str, size_t length); void println(const char * str, size_t length);
public:
/**
* @brief Read bytes.
*
* @param buffer Byte buffer
* @param length Buffer length
*/
virtual void read(uint8_t * buffer, size_t length) = 0;
/**
* @brief Read string.
*
* @param str String buffer
* @param length String length
*/
void read(char * str, size_t length);
/**
* @brief Read floats.
*
* @param buffer Float buffer
* @param length Buffer length
*/
void read(float * buffer, size_t length);
/**
* @brief Read doubles.
*
* @param buffer Double buffer
* @param length Buffer length
*/
void read(double * buffer, size_t length);
private: private:
/** /**
* @brief Print unsigned integer in selected base. * @brief Print unsigned integer in selected base.
@ -170,32 +209,36 @@ namespace sta
* @param base Integer base * @param base Integer base
* @param fmt printf format string for base 10 * @param fmt printf format string for base 10
* @param size Size of value in bytes * @param size Size of value in bytes
* @param newline If true, send a \r\n to start a new line.
*/ */
void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size); void printBase(uintmax_t value, IntegerBase base, const char * fmt, size_t size, bool newline = false);
/** /**
* @brief Print unsigned integer in base 10. * @brief Print unsigned integer in base 10.
* *
* @param value Unsigned integer value * @param value Unsigned integer value
* @param fmt printf format string * @param fmt printf format string
* @param newline If true, send a \r\n to start a new line.
*/ */
void printDec(uintmax_t value, const char * fmt); void printDec(uintmax_t value, const char * fmt, bool newline = false);
/** /**
* @brief Print unsigned integer in base 2. * @brief Print unsigned integer in base 2.
* *
* @param value Unsigned integer value * @param value Unsigned integer value
* @param digits Number of digits to print * @param digits Number of digits to print
* @param newline If true, send a \r\n to start a new line.
*/ */
void printBin(uintmax_t value, size_t digits); void printBin(uintmax_t value, size_t digits, bool newline = false);
/** /**
* @brief Print unsigned integer in base 16. * @brief Print unsigned integer in base 16.
* *
* @param value Unsigned integer value * @param value Unsigned integer value
* @param digits Number of digits to print * @param digits Number of digits to print
* @param newline If true, send a \r\n to start a new line.
*/ */
void printHex(uintmax_t value, size_t digits); void printHex(uintmax_t value, size_t digits, bool newline = false);
}; };
} // namespace sta } // namespace sta

View File

@ -23,8 +23,17 @@ namespace sta
* *
* @param str String buffer * @param str String buffer
* @param length String length * @param length String length
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(const char * str, size_t length) override; void print(const char * str, size_t length, bool newline = false) override;
/**
* @brief Read bytes.
*
* @param buffer Byte buffer
* @param length Buffer length
*/
void read(uint8_t * buffer, size_t length) override;
}; };
} // namespace sta } // namespace sta

View File

@ -32,8 +32,17 @@ namespace sta
* *
* @param str String buffer * @param str String buffer
* @param length String length * @param length String length
* @param newline If true, send a \r\n to start a new line.
*/ */
void print(const char * str, size_t length) override; void print(const char * str, size_t length, bool newline = false) override;
/**
* @brief Read bytes.
*
* @param buffer Byte buffer
* @param length Buffer length
*/
void read(uint8_t * str, size_t length) override;
private: private:
UART * intf_; UART * intf_;

View File

@ -5,8 +5,8 @@
* Author: Dario * Author: Dario
*/ */
#ifndef STA_DEBUGGING_PROFILING_HPP #ifndef STA_CORE_PROFILE_HPP
#define STA_DEBUGGING_PROFILING_HPP #define STA_CORE_PROFILE_HPP
#include <sta/debug/debug.hpp> #include <sta/debug/debug.hpp>
@ -44,4 +44,4 @@ namespace sta
#endif // // STA_PROFILING_ENABLED #endif // // STA_PROFILING_ENABLED
#endif // STA_DEBUGGING_PROFILING_HPP #endif // STA_CORE_PROFILE_HPP

View File

@ -0,0 +1,66 @@
#ifndef STA_CORE_SPATZ_HPP
#define STA_CORE_SPATZ_HPP
#include <sta/mutex.hpp>
#include <sta/config.hpp>
#ifdef STA_SPATZ_ENABLED
#include <sta/debug/debug.hpp>
#ifndef STA_DEBUGGING_ENABLED
# error "Cannot use SPATZ without debugging being enabled."
#endif // STA_DEBUGGING_ENABLED
namespace sta
{
namespace spatz
{
/**
* @brief Initialize SPATZ for in-the-loop testing.
*
* @param mutex A mutex used to make SPATZ thread-safe.
*/
void init(Mutex * mutex);
/**
* @brief Request bytes for a specific sensor id via the printable.
*
* @param id The id of the sensor to request data for.
* @param buffer The byte buffer to write the data to.
* @param length The number of the bytes to request.
*/
void request(uint8_t id, uint8_t * buffer, size_t length);
/**
* @brief Request floats for a specific sensor id via the printable.
*
* @param id The id of the sensor to request data for.
* @param buffer The float buffer to write the data to.
* @param length The number of floats to request.
*/
void request(uint8_t id, float * buffer, size_t length);
/**
* @brief Request doubles for a specific sensor id via the printable.
*
* @param id The id of the sensor to request data for.
* @param buffer The double buffer to write the data to.
* @param length The number of doubles to request.
*/
void request(uint8_t id, double * buffer, size_t length);
} // namespace spatz
} // namespace sta
#else
namespace sta
{
namespace spatz
{
void init(Mutex * mutex);
} // namespace spatz
} // namespace sta
#endif // STA_SPATZ_ENABLED
#endif // STA_CORE_SPATZ_HPP

View File

@ -27,82 +27,76 @@ namespace sta
println(str); println(str);
} }
void Printable::print(char c) void Printable::print(char c, bool newline /* = false */)
{ {
print(&c, 1); print(&c, 1, newline);
} }
void Printable::print(bool b) void Printable::print(bool b, bool newline /* = false */)
{ {
print(b ? "true" : "false"); print(b ? "true" : "false", newline);
} }
void Printable::print(double d) void Printable::print(double d, bool newline /* = false */)
{ {
char buffer[64]; char buffer[64];
snprintf(buffer, sizeof(buffer), "%f", d); snprintf(buffer, sizeof(buffer), "%f", d);
print(buffer); print(buffer, newline);
} }
void Printable::print(uint8_t num, IntegerBase base) void Printable::print(uint8_t num, IntegerBase base, bool newline /* = false */)
{ {
printBase(num, base, "%" PRIu8, sizeof(num)); printBase(num, base, "%" PRIu8, sizeof(num), newline);
} }
void Printable::print(uint16_t num, IntegerBase base) void Printable::print(uint16_t num, IntegerBase base, bool newline /* = false */)
{ {
printBase(num, base, "%" PRIu16, sizeof(num)); printBase(num, base, "%" PRIu16, sizeof(num), newline);
} }
void Printable::print(uint32_t num, IntegerBase base) void Printable::print(uint32_t num, IntegerBase base, bool newline /* = false */)
{ {
printBase(num, base, "%" PRIu32, sizeof(num)); printBase(num, base, "%" PRIu32, sizeof(num), newline);
} }
void Printable::print(const char * str) void Printable::print(const char * str, bool newline /* = false */)
{ {
print(str, strlen(str)); print(str, strlen(str), newline);
} }
void Printable::println() void Printable::println()
{ {
print("\r\n", 2); print("\r\n", 2, false);
} }
void Printable::println(char c) void Printable::println(char c)
{ {
print(&c, 1); print(&c, 1, true);
println();
} }
void Printable::println(bool b) void Printable::println(bool b)
{ {
print(b); print(b, true);
println();
} }
void Printable::println(double d) void Printable::println(double d)
{ {
print(d); print(d, true);
println();
} }
void Printable::println(uint8_t num, IntegerBase base) void Printable::println(uint8_t num, IntegerBase base)
{ {
print(num, base); print(num, base, true);
println();
} }
void Printable::println(uint16_t num, IntegerBase base) void Printable::println(uint16_t num, IntegerBase base)
{ {
print(num, base); print(num, base, true);
println();
} }
void Printable::println(uint32_t num, IntegerBase base) void Printable::println(uint32_t num, IntegerBase base)
{ {
print(num, base); print(num, base, true);
println();
} }
void Printable::println(const char * str) void Printable::println(const char * str)
@ -112,26 +106,25 @@ namespace sta
void Printable::println(const char * str, size_t length) void Printable::println(const char * str, size_t length)
{ {
print(str, length); print(str, length, true);
println();
} }
void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size) void Printable::printBase(uintmax_t num, IntegerBase base, const char * fmt, size_t size, bool newline /* = false */)
{ {
switch (base) switch (base)
{ {
case IntegerBase::DEC: case IntegerBase::DEC:
printDec(num, fmt); printDec(num, fmt, newline);
break; break;
case IntegerBase::BIN: case IntegerBase::BIN:
// Digits in base 2 = size in bytes * 8 // Digits in base 2 = size in bytes * 8
printBin(num, size * 8); printBin(num, size * 8, newline);
break; break;
case IntegerBase::HEX: case IntegerBase::HEX:
// Digits in base 16 = size in bytes * 2 // Digits in base 16 = size in bytes * 2
printHex(num, size * 2); printHex(num, size * 2, newline);
break; break;
default: default:
@ -139,14 +132,14 @@ namespace sta
} }
} }
void Printable::printDec(uintmax_t num, const char * fmt) void Printable::printDec(uintmax_t num, const char * fmt, bool newline /* = false */)
{ {
char buffer[64]; char buffer[64];
snprintf(buffer, sizeof(buffer), fmt, static_cast<uint32_t>(num)); snprintf(buffer, sizeof(buffer), fmt, static_cast<uint32_t>(num));
print(buffer); print(buffer, newline);
} }
void Printable::printBin(uintmax_t value, size_t digits) void Printable::printBin(uintmax_t value, size_t digits, bool newline /* = false */)
{ {
// Need 8 digits for every byte // Need 8 digits for every byte
char buffer[sizeof(value) * 8]; char buffer[sizeof(value) * 8];
@ -168,10 +161,10 @@ namespace sta
buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1); buffer[i] = '0' + ((value >> (digits - 1 - i)) & 0x1);
} }
print(buffer, digits); print(buffer, digits, newline);
} }
void Printable::printHex(uintmax_t value, size_t digits) void Printable::printHex(uintmax_t value, size_t digits, bool newline /* = false */)
{ {
// Need 2 digits for every byte // Need 2 digits for every byte
char buffer[sizeof(value) * 2]; char buffer[sizeof(value) * 2];
@ -179,7 +172,7 @@ namespace sta
// Check bounds // Check bounds
if (digits > sizeof(buffer)) if (digits > sizeof(buffer))
{ {
print("<hex_value_too_big>"); print("<hex_value_too_big>", newline);
return; return;
} }
// Nothing to do // Nothing to do
@ -197,7 +190,22 @@ namespace sta
buffer[i] = '0' + hex; buffer[i] = '0' + hex;
} }
print(buffer, digits); print(buffer, digits, newline);
}
void Printable::read(char * str, size_t length)
{
read(reinterpret_cast<uint8_t*>(str), length * sizeof(char));
}
void Printable::read(float * buffer, size_t length)
{
read(reinterpret_cast<uint8_t*>(buffer), length * sizeof(float));
}
void Printable::read(double * buffer, size_t length)
{
read(reinterpret_cast<uint8_t*>(buffer), length * sizeof(double));
} }
} // namespace sta } // namespace sta

View File

@ -1,5 +1,6 @@
#include <sta/debug/printing/printable_printf.hpp> #include <sta/debug/printing/printable_printf.hpp>
#include <sta/debug/assert.hpp> #include <sta/debug/assert.hpp>
#include <sta/lang.hpp>
#include <cstdio> #include <cstdio>
@ -10,11 +11,22 @@ namespace sta
} }
void PrintablePrintf::print(const char * str, size_t length) void PrintablePrintf::print(const char * str, size_t length, bool newline /* = false */)
{ {
STA_ASSERT(str != nullptr); STA_ASSERT(str != nullptr);
STA_ASSERT(length > 0); STA_ASSERT(length > 0);
printf("%.*s", length, str); printf("%.*s", length, str);
if (newline)
printf("\r\n");
}
void PrintablePrintf::read(uint8_t * str, size_t length)
{
STA_ASSERT(str != nullptr);
STA_ASSERT(length > 0);
STA_NOT_IMPLEMENTED();
} }
} // namespace sta } // namespace sta

View File

@ -17,11 +17,25 @@ namespace sta
STA_ASSERT(intf->settings().mode == UARTMode::RX || intf->settings().mode == UARTMode::RX_TX); STA_ASSERT(intf->settings().mode == UARTMode::RX || intf->settings().mode == UARTMode::RX_TX);
} }
void PrintableUART::print(const char * str, size_t length) void PrintableUART::print(const char * str, size_t length, bool newline /* = false */)
{ {
intf_->acquire(); intf_->acquire();
intf_->transfer(reinterpret_cast<const uint8_t *>(str), length); intf_->transfer(reinterpret_cast<const uint8_t *>(str), length);
if (newline)
{
const char * linebreak = "\r\n";
intf_->transfer(reinterpret_cast<const uint8_t *>(linebreak), 2);
}
intf_->release(); intf_->release();
} }
void PrintableUART::read(uint8_t * buffer, size_t length)
{
intf_->acquire();
intf_->receive(buffer, length);
intf_->release();
}
} // namespace sta } // namespace sta

71
src/debug/spatz.cpp Normal file
View File

@ -0,0 +1,71 @@
#include <sta/debug/spatz.hpp>
#ifdef STA_SPATZ_ENABLED
#ifndef STA_INIT_SPATZ_ID
# error "The ID used to communicate SPATZ initialization was not defined."
#endif // STA_INIT_SPATZ_ID
namespace sta
{
namespace spatz
{
sta::Mutex * mutex_;
void init(sta::Mutex * mutex)
{
mutex_ = mutex;
uint8_t msg = 0xFF;
sta::lock_guard<sta::Mutex> lock(*mutex_);
// Wait until SPATZ sends the init byte.
while (msg != STA_INIT_SPATZ_ID)
{
Debug->read(&msg, 1);
}
}
void request(uint8_t id, uint8_t * buffer, size_t length)
{
sta::lock_guard<sta::Mutex> lock(*mutex_);
Debug->println("%d", id);
Debug->read(buffer, length);
}
void request(uint8_t id, float * buffer, size_t length)
{
sta::lock_guard<sta::Mutex> lock(*mutex_);
// Debug->println(id, IntegerBase::DEC);
Debug->printf("%d", id);
Debug->read(buffer, length);
}
void request(uint8_t id, double * buffer, size_t length)
{
sta::lock_guard<sta::Mutex> lock(*mutex_);
Debug->println("%d", id);
Debug->read(buffer, length);
}
} // namespace spatz
} // namespace sta
#else
namespace sta
{
namespace spatz
{
void init(sta::Mutex * mutex)
{
// Nothing to do here.
}
} // namespace spatz
} // namespace sta
#endif // STA_SPATZ_ENABLED