Pointer to peripheral hardware as template parameter - c++

I want to access STM32F0 peripheral register through C++ templates. A GPIO Port is defined as follows by vendor header file:
excerpt stm32f0xx.h
#define __IO volatile //!< Defines 'read / write' permissions
typedef struct
{
__IO uint32_t MODER;
__IO uint16_t OTYPER;
uint16_t RESERVED0;
__IO uint32_t OSPEEDR;
__IO uint32_t PUPDR;
__IO uint16_t IDR;
uint16_t RESERVED1;
__IO uint16_t ODR;
uint16_t RESERVED2;
__IO uint32_t BSRR;
__IO uint32_t LCKR;
__IO uint32_t AFR[2];
__IO uint16_t BRR;
uint16_t RESERVED3;
} GPIO_TypeDef;
#define PERIPH_BASE ((uint32_t)0x40000000)
#define AHB2PERIPH_BASE (PERIPH_BASE + 0x08000000)
#define GPIOA_BASE (AHB2PERIPH_BASE + 0x00000000)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
I created a template class for output handling.
main.cpp:
template <uintptr_t port, uint8_t pin>
class Output {
public:
static void set() {
GPIO_TypeDef *castedPort = reinterpret_cast<GPIO_TypeDef *>(port);
castedPort->ODR = (1 << pin);
}
};
int main(void)
{
Output<GPIOA_BASE, 5>::set();
while(1)
{
}
}
This code runs fine, if I compile it with launchpad g++ for arm. But I want to test my code
with GoogleTest, so I made a test for it and tried to compile it.
intArgument.cpp:
#include "gtest/gtest.h"
typedef struct {
/* see above definition */
} GPIO_TypeDef;
uint32_t gpioa[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
template <uintptr_t port, int pin>
class Output {
public:
static void set() {
GPIO_TypeDef * castedPort = reinterpret_cast<GPIO_TypeDef *>(port);
castedPort->ODR = (1 << pin);
}
};
TEST(OutputTest, OutputDataRegisterWritten) {
Output<gpioa, 5>::set();
GPIO_TypeDef * port = reinterpret_cast<GPIO_TypeDef *>(gpioa);
EXPECT_EQ((1 << 5), port->ODR);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
But now compile fails. A cast to a int via reinterpret_cast is not allowed, because then it is no more a constant expression.
fabian#ubuntu:~/workspace/stackOverflowQuestion$ g++ -std=c++11 intArgument.cpp -lgtest -pthread -o intptrArgument.out
intArgument.cpp: In member function ‘virtual void OutputTest_OutputDataRegisterWritten_Test::TestBody()’:
intArgument.cpp:23:18: error: conversion from ‘uint32_t* {aka unsigned int*}’ to ‘long unsigned int’ not considered for non-type template argument
Output<gpioa, 5>::set();
^
intArgument.cpp:23:18: error: could not convert template argument ‘gpioa’ to ‘long unsigned int’
intArgument.cpp:23:26: error: invalid type in declaration before ‘;’ token
Output<gpioa, 5>::set();
So i tried to change type of port to GPIO_TypeDef *.
pointerArgument.cpp:
typedef struct {
/* see above definition */
} GPIO_TypeDef;
GPIO_TypeDef gpioa;
// using GPIO_TypeDef * as template argument
template <GPIO_TypeDef * port, int pin>
class Output {
public:
static void set() {
port->ODR = (1 << pin);
}
};
TEST(OutputTest, OutputDataRegisterWritten) {
Output<&gpioa, 5>::set();
EXPECT_EQ((1 << 5), gpioa.ODR);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
It compiled and test is passed.
fabian#ubuntu:~/workspace/stackOverflowQuestion$ g++ -std=c++11 pointerArgument.cpp -lgtest -pthread -o pointerArgument.out
fabian#ubuntu:~/workspace/stackOverflowQuestion$ ./test.out
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from OutputTest
[ RUN ] OutputTest.OutputDataRegisterWritten
[ OK ] OutputTest.OutputDataRegisterWritten (0 ms)
[----------] 1 test from OutputTest (1 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
But using this approach is failing for the arm compiler:
main.cpp
template <GPIO_TypeDef * port, uint8_t pin>
class Output {
public:
static void set() {
port->ODR = (1 << pin);
}
};
int main(void)
{
Output<GPIOA, 5>::set();
while(1)
{
}
}
compiler error:
[cc] main.cpp:13:17: error: '1207959552u' is not a valid template argument for 'GPIO_TypeDef*' because it is not the address of a variable
[cc] main.cpp:13:25: error: invalid type in declaration before ';' token
I understand both errors, but is there any way to get this work? I searched for compiler flags, but did not find
any, that might change this behaviour. A #define TESTING combined with #ifdef/#ifndef might work, but I dont
like it, because then tested code differs from produced code. Perhaps there is a nicer solution?
Used Compilers:
g++ (i686-posix-dwarf-rev3, Built by MinGW-W64 project), 4.9-2014q4 by Launchpad for STM32F0XX
g++ (Ubuntu 4.9.2-0ubuntu1~14.04) 4.9.2 for Testing

With linker flag Wl,section-start you can define the start address of a specified section. So first I forced my register mocks to be in a own section:
GPIO_TypeDef gpioa __attribute__((section(".myTestRegisters")));
GPIO_TypeDef gpiob __attribute__((section(".myTestRegisters")));
Also I defined const uintptr_t address values for section start and each register.
const uintptr_t myTestRegisterSectionAddress = 0x8000000;
const uintptr_t gpioaAddress = myTestRegisterSectionAddress;
const uintptr_t gpiobAddress = myTestRegisterSectionAddress + sizeof(GPIO_TypeDef);
These values I can use as template parameter.
template <uintptr_t port, int pin>
class Output {
public:
static void set() {
GPIO_TypeDef * castedPort = reinterpret_cast<GPIO_TypeDef *>(port);
castedPort->ODR = (1 << pin);
}
};
TEST(OutputTest, OutputDataRegisterWritten) {
Output<gpioaAddress, 5>::set();
EXPECT_EQ(1 << 5, gpioa.ODR);
Output<gpiobAddress, 10>::set();
EXPECT_EQ(1 << 10, gpiob.ODR);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
To force a start address for a section you can use Wl,-section-start=.{sectionName}={startAddress}.
So in my case I use:
g++ intArgument.cpp -std=c++11 -g -o intArgument.out -lgtest -pthread -Wl,-section-start=.myTestRegisters=0x8000000
Running application results in:
fabian#ubuntu:~/workspace/stackOverflowQuestion$ ./intArgument.out
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from OutputTest
[ RUN ] OutputTest.OutputDataRegisterWritten
[ OK ] OutputTest.OutputDataRegisterWritten (0 ms)
[----------] 1 test from OutputTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
And a objdump shows following information:
fabian#ubuntu:~/workspace/stackOverflowQuestion$ objdump -S -j .myTestRegisters intArgument.out
intArgument.out: file format elf64-x86-64
Disassembly of section .myTestRegisters:
0000000008000000 <gpioa>:
...
000000000800000c <gpiob>:
This works not with optimizations because the elements can be swapped.

Related

googletest: How to skip test from an inner method

With GTEST_SKIP, we can (conditionally) skip a test. The way it is implemented is as follows:
#define GTEST_SKIP_(message) \
return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
If we are in the main test body, all is fine.
How can I skip a test from deep within my code base? This does not work:
int skip_this(int x) {
if (x == 3) GTEST_SKIP();
return x;
}
TEST(X, Y) {
skip_this(2);
skip_this(3);
throw std::runtime_error("Did not skip");
}
Error:
/Users/markus/Projekte/Opossum/Git/src/test/operators/aggregate_test.cpp:183:15: error: cannot initialize return object of type 'int' with an rvalue of type 'void'
if (x == 3) GTEST_SKIP();
^~~~~~~~~~~~
In other words: How can I modify skip_this so that the test passes or is marked as "skipped"?
This is not really nice, but works for my purpose. The idea is to unwind the stack, search for the googletest method that called the test and reset the instruction pointer to that stack frame.
Note that the stack is not properly destroyed, meaning that, e.g., resources can leak.
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <cxxabi.h>
#include <iostream>
#include <gtest/gtest.h>
void skip() {
unw_cursor_t cursor;
unw_context_t context;
unw_getcontext(&context);
unw_init_local(&cursor, &context);
while (unw_step(&cursor)) {
unw_word_t off;
char symbol[256] = {"<unknown>"};
char* name = symbol;
if (!unw_get_proc_name(&cursor, symbol, sizeof(symbol), &off)) {
int status;
if ((name = abi::__cxa_demangle(symbol, nullptr, nullptr, &status)) == nullptr) name = symbol;
}
if (std::string(name) == "testing::Test::Run()") {
::testing::internal::AssertHelper(::testing::TestPartResult::kSkip, __FILE__, __LINE__, "skipped") = ::testing::Message();
unw_resume(&cursor);
}
if (name != symbol) free(name);
}
throw std::runtime_error("Did not find test method on the stack, could not skip test");
}
Example test (can be pasted below the code above):
int foo(int x) {
if (x == 3) skip();
return 11;
}
TEST(SkipTest, ShouldNotBeSkipped) {
foo(2);
EXPECT_TRUE(false);
}
TEST(SkipTest, ShouldBeSkipped) {
foo(3);
EXPECT_TRUE(false);
}
TEST(SkipTest, TestExecutionContinues) {
EXPECT_FALSE(false);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Output:
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from SkipTest
[ RUN ] SkipTest.ShouldNotBeSkipped
skip_test.cpp:44: Failure
Value of: false
Actual: false
Expected: true
[ FAILED ] SkipTest.ShouldNotBeSkipped (0 ms)
[ RUN ] SkipTest.ShouldBeSkipped
[ SKIPPED ] SkipTest.ShouldBeSkipped (0 ms)
[ RUN ] SkipTest.TestExecutionContinues
[ OK ] SkipTest.TestExecutionContinues (0 ms)
[----------] 3 tests from SkipTest (0 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
[ SKIPPED ] 1 test, listed below:
[ SKIPPED ] SkipTest.ShouldBeSkipped
[ FAILED ] 1 test, listed below:
[ FAILED ] SkipTest.ShouldNotBeSkipped
1 FAILED TEST
You cant use GTEST_SKIP in the inner function. It will not take effect. I can only offer this solution or something similar:
#define SKIPCODE -1
int skip_this(int x)
{
if (x == 3)
return SKIPCODE;
else return x;
}
TEST(Test)
{
int n = 3;
if (skip_this(n) == SKIPCODE)
GTEST_SKIP();
ASSERT_TRUE(false);
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

How to test boost logger output in unit testing?

My application uses BOOST_LOG_TRIVIAL to log messages. I thought it's good to check in test (gtest) that correct messages are written there in given scenarios.
Is there a way to somehow access what was written there after code was called? Or does it first have to be mocked in some way?
I have googled a lot for this and haven't found any instructions, so either I am asking wrong questions or no one thinks it should be done.
In your googletest suite, you can use the boost::log facilities in
each test case to redirect the BOOST_LOG_TRIVIAL messages to a file.
After writing the BOOST_LOG_TRIVIAL message(s) you want you can then
flush the file, open it, and check that it has the contents you expect.
For example:
gtester.cpp
#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/trivial.hpp>
#include <string>
#include <fstream>
using sink_t = boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>;
struct boost_log_tester : ::testing::Test {
void SetUp() {
file_sink = boost::log::add_file_log("boost.log");
}
void TearDown() {
boost::log::core::get()->remove_sink(file_sink);
file_sink.reset();
}
protected:
boost::shared_ptr<sink_t> file_sink;
};
TEST_F(boost_log_tester,info_msg)
{
std::string msg = "An informational severity message";
BOOST_LOG_TRIVIAL(info) << msg;
file_sink->flush();
std::ifstream captured_cout("boost.log");
ASSERT_TRUE(captured_cout.good()) << "Failure executing test: Could not open `boost.log` for reading";
std::string cout_str;
std::getline(captured_cout,cout_str);
EXPECT_NE(cout_str.find(msg),std::string::npos);
}
TEST_F(boost_log_tester,error_msg)
{
std::string msg = "An error severity message";
BOOST_LOG_TRIVIAL(error) << msg;
file_sink->flush();
std::ifstream captured_cerr("boost.log");
ASSERT_TRUE(captured_cerr.good()) << "Failure executing test: Could not open `boost.log` for reading";
std::string cerr_str;
std::getline(captured_cerr,cerr_str);
EXPECT_NE(cerr_str.find(msg),std::string::npos);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Compile and link:
$ g++ -Wall -Wextra -DBOOST_LOG_DYN_LINK -c gtester.cpp
$ g++ -o gtester gtester.o -lboost_log -lboost_thread -lboost_system -lgtest -pthread
And it runs like:
$ ./gtester
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from boost_log_tester
[ RUN ] boost_log_tester.info_msg
[ OK ] boost_log_tester.info_msg (0 ms)
[ RUN ] boost_log_tester.error_msg
[ OK ] boost_log_tester.error_msg (2 ms)
[----------] 2 tests from boost_log_tester (2 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (2 ms total)
[ PASSED ] 2 tests.
Following Mike's answer, in which I think necessity of file creation is a downside, I did a bit of research and found this way of using a stringstream instead:
class boost_logger_test : public testing::Test
{
typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> sink_t;
boost::shared_ptr<sink_t> streamSink;
std::stringstream ss;
public:
virtual void SetUp()
{
streamSink = boost::log::add_console_log(ss);
}
virtual void TearDown()
{
boost::log::core::get()->remove_sink(streamSink);
streamSink.reset();
}
std::vector<std::string> getLogMessages()
{
std::vector<std::string> messages;
std::string msg;
while (std::getline(ss, msg, '\n'))
{
messages.push_back(msg);
}
return messages;
}
}
Then you could easily use messages in tests, like:
ASSERT_THAT(getLogMessages(), ElementsAre("Just some log message"));

Is it possible to mock a called function return value using gtest or gmock?

I am new to gtest and gmock please let me understand how to mock the called function. Which will also help me in code coverage.
#include <stdio.h>
#include "gtest/gtest.h"
int ret()
{
return 5;
}
class A
{
public:
A();
int a;
int func();
};
A::A()
{
printf("This is constructor\n");
}
int A::func()
{
int iRet = ret(); /* When func() is called by gtest I would like to control the return value of ret() */
int iRet1 = ret();
/* Based on these two values some operations to be done */
printf("This is func. %d, %d\n", iRet, iRet1);
return iRet;
}
TEST (abc, xyz) {
A a;
EXPECT_EQ(5, a.func()); /* Here how to get different values of iRet and iRet1 for ret() function? */
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
In case if it is not possible through gtest and/or gmock, please suggest me any other tool for the same.
Also I tried with the following thing which is not working as expected:
int ret()
{
printf("Returning 5\n");
return 5;
}
int ret1()
{
int iRet = 10;
printf("Inside ret1\n");
iRet = ret();
if (iRet == 5)
{
printf("Original ret is called\n");
}
else if (iRet == 100)
{
printf("This is mocked function call\n");
}
else
{
printf("Opps! This should not happen\n");
}
return iRet;
}
class FooMock {
public:
MOCK_METHOD0(ret, int());
MOCK_METHOD0(ret1, int());
};
TEST (abc, xyz) {
FooMock mock;
EXPECT_CALL(mock, ret()).Times(1).WillOnce(Return(100));
mock.ret1();
}
int main(int argc, char **argv)
{
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
While running giving me the following error:
$ ./a.out
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from abc
[ RUN ] abc.xyz
gtest.cpp:86: Failure
Actual function call count doesn't match EXPECT_CALL(mock, ret())...
Expected: to be called once
Actual: never called - unsatisfied and active
gtest.cpp:87: Failure
Actual function call count doesn't match EXPECT_CALL(mock, ret())...
Expected: to be called once
Actual: never called - unsatisfied and active
[ FAILED ] abc.xyz (0 ms)
[----------] 1 test from abc (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] abc.xyz
1 FAILED TEST
Please let me know if anything I am doing wrong...
So, the idea of unit-testing is that you run some of your code and that you compare the results to what you expect to be the result. Your code makes it more complicated than it has to be. E.g.
#include <stdio.h>
#include "gtest/gtest.h"
int incBy5(const int a) {
return a+5;
}
TEST (abc, xyz) {
int x=17;
EXPECT_EQ(x+5, incBy5(x));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
See the documentation of unit testing concepts in general and google-test in particular. The mocking aspect of it all comes into place with more complex things to test where you may not have everything readily available (e.g. network resources, databases, ...) and you create mock-ups that can replace these resources.
In your second snippet, you define two mock methods, ret and ret1. Later, you set up an expectation on ret but invoke ret1. At the end of the test, the expectation on ret remains unfulfilled, causing gmock to complain.

googletest SetUp Method not called

I'm using Google Test to unit test my C++ project. The getting started guide says:
If necessary, write a default constructor or SetUp() function to prepare the objects for each test. A common mistake is to spell SetUp() as Setup() with a small u - don't let that happen to you.
SetUp() is spelled correctly, but I still can't get SetUp to work. Any ideas?
#include "gtest/gtest.h"
class SampleTest : public ::testing::Test {
protected:
virtual void SetUp() { std::cout << "SetUp called." << std::endl; }
};
TEST(SampleTest, OneEqualsOne) {
int one = 1;
ASSERT_EQ(1, one);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
g++ -g -Wno-deprecated -I gtest/include SampleTest.cpp gtest/libgtest.a -o SampleTest
Output:
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from SampleTest
[ RUN ] SampleTest.OneEqualsOne
[ OK ] SampleTest.OneEqualsOne (1 ms)
[----------] 1 test from SampleTest (1 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
Change TEST to TEST_F, as SetUp methods and such are called with TEST_F, but not with TEST alone.
Change your TEST macro to TEST_F. (It's listing in the documentation right underneath the quote you provided.)

avr-g++ undefined reference to

I am trying to write code for my atmega328 in C++ using Eclipse CDT. I have two projects. One project is static library project, that produces a static library. All the files in library are compiled without errors and library is created using the following command:
avr-ar -r "libRobotMainBoard.a" ./Console.o ./Motor.o ./RingBuffer.o ./io.o ./operators.o
c:\Program Files\WINAVR\bin\avr-ar.exe: creating libRobotMainBoard.a
Then I use this library in other project that produces hex file for my atmega. But during the linking I get error:
C:\Users\Mitch\Disk Google\workspace\AVR\RobotMainBoard\Release\libRobotMainBoard.a(Console.o): In function Console::putCharToUDR()':
Console.cpp:(.text._ZN7Console12putCharToUDREv+0x2): undefined reference to Console::txBuff'
and many othert similar to this. I have tried to find the solution on the web. Most of them mentions that this error is caused by naming library and the compiled file in the wrong order. I checked that and my order should be fine. I am linking it with the command:
avr-g++ -Wl,-Map,BoardTest.map,--cref -mrelax -Wl,--gc-sections -L"C:\Users\Mitch\Disk Google\workspace\AVR\RobotMainBoard\Release" -mmcu=atmega328p -o "BoardTest.elf" ./main.o -lRobotMainBoard
The main.cpp file looks like this:
#include <util/delay.h>
#include "Console.h"
#include "Motor.h"
Motor leftMotor(9,7);
Motor rightMotor(10,8);
int main(){
leftMotor.stop();
rightMotor.stop();
Console::setup(250000);
while(1){
Console::send('a');
_delay_ms(2000);
}
}
When I comment the Console lines out, it will link OK, even with Motor lines, which source files are in the same lib.
The Console cpp file is like this:
#include <avr/interrupt.h>
#include "Console.h"
#include "operators.h"
void Console::setup(uint16_t baudrate) {
rxBuff = new RingBuffer(RX_BUFF_SIZE);
txBuff = new RingBuffer(TX_BUFF_SIZE);
uint16_t baudPrescaler= (F_CPU / (baudrate * 16)) - 1;
UCSR0A = 0x00; UCSR0B = 0x00; UCSR0C = 0x00;
//Using 8-bit, asynchronous, normal speed, 1 stop bit, no parity check
UBRR0 = baudPrescaler;
UCSR0C |= (1 << UCSZ01) | (1 << UCSZ00); //8-bit
UCSR0B |= (1 << TXEN0) | (1 << RXEN0);
sei();
}
void Console::send(char c) {
txBuff->add(c);
UCSR0B |= (1 << UDRIE0);
}
void Console::send(const char* s) {
while(*s){
send(*s++);
}
}
void Console::putCharToUDR(){
if(!txBuff->empty()){
UDR0 = txBuff->remove();
} else {
UCSR0B &= ~(1 << UDRIE0);
}
}
uint8_t Console::canReceive() {
return rxBuff->available();
}
uint8_t Console::canTransmit() {
return txBuff->available();
}
ISR(USART_RX_vect, ISR_BLOCK){
}
ISR(USART_UDRE_vect, ISR_BLOCK){
Console::putCharToUDR();
}
Do anybody of you have any idea, why I am still getting the linking error?
EDIT 1
#ifndef CONSOLE_H_
#define CONSOLE_H_
#include "RingBuffer.h"
#define RX_BUFF_SIZE 32
#define TX_BUFF_SIZE 32
class Console {
public:
static void setup(uint16_t baudrate);
static void send(char c);
static void send(const char* s);
static uint8_t canReceive();
static uint8_t canTransmit();
static void putCharToUDR();
private:
static RingBuffer *rxBuff;
static RingBuffer *txBuff;
};
#endif /* CONSOLE_H_ */
As txBuff is static, you have to provide its definition in Console.cpp, e.g.
RingBuffer * Console::txBuff = new RingBuffer(RX_BUFF_SIZE);