Hello everyone,
I recently started programming AVRs with C++. Everything was ok until I had to do some testing. It seems like most AVR platform specific testing libs don't support C++ features like templates, so I went with C++ header-only lib - Catch (https://github.com/catchorg/Catch2). Problem appeared after running it - tests with only C++ code compiled without problems, but when I tried to test AVR things it shows long list of errors.
My plan to test AVR:
-isolate setting every register to one class named Avr and create methods like set_bits, clear_bits etc
-pass this class in template like so:
template<class HW = Avr>
and use those methods in normal programming
-in testing though use other class AvrTest with mocked methods (like internal array or variable pretending to be register)
So I created stub of test scenerio and included my file which also included <avr/io.h> and compiled it with avr-g++ with c++ support. Everything failed miserably, so I concluded that it doesn't look for C++ std libs used in Catch. I added it manually and also failed. Can somebody help me with that problem? I don't know if I have to isolate AVR code more to not include <avr/io.h> at any time or what.
Here's errors log:
(command used to compile is contained in first line)
here's test suite code:
extern "C" { #include <stdint.h> } #include "lib/catch.hpp" #include "../src/adc.hpp" SCENERIO("ADC is working properly", "[ADC]") { GIVEN("A new Adc object") { WHEN("State is checked after creation") { THEN("ADC is enabled") {} THEN("ADC interrupts are enabled") {} THEN("Prescaler is correctly set") {} THEN("ADC register is adjusted to simplify usage of 8 bit data") {} } } }
Here's ADC class code:
#ifndef ADC_HPP #define ADC_HPP extern "C" { #include <avr/io.h> } #include "util/avr.hpp" template <class HW = Avr> class Adc { public: inline Adc() { // Uref = AVCC with external capacitor at AREF pin, // set let adjust of result for convienient 8bit access HW::set(ADMUX, (1 << REFS0) | (1 << ADLAR)); // ADC enable, free running mode, start first // conversion, interrupt on update, turn on // interrupts default prescaler (/2) HW::set(ADCSRA, (1 << ADEN) | (1 << ADFR) | (1 << ADSC) | (1 << ADIF) | (1 << ADIE)); } inline uint8_t get_8bit_conversion_result() const { return HW::get(ADCH); } inline void stop_ADC() const { HW::clear(ADCSRA, (1 << ADEN)); } inline void start_ADC() const { HW::update(ADCSRA, (1 << ADEN)); } }; #endif // ADC_HPP
aaand avr.hpp code:
#ifndef AVR_HPP #define AVR_HPP extern "C" { #include <avr/io.h> } class Avr { public: static inline volatile uint8_t& get(volatile uint8_t& address) { return address; } static inline void set(volatile uint8_t& address, const uint8_t value) { address = value; } static inline void clear(volatile uint8_t& address, const uint8_t value) { address &= ~value; } static inline void update(volatile uint8_t& address, const uint8_t value) { address |= value; } private: Avr() {} ~Avr() {} }; #endif // AVR_HPP
Have a good day!