online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#include <cstdint> #include <type_traits> #include <limits> #include <cstddef> #include <initializer_list> #define __IO volatile typedef struct { __IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */ __IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */ __IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */ __IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */ __IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */ __IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */ __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */ __IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */ __IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x20-0x24 */ } GPIO_TypeDef; #define PERIPH_BASE 0x40000000U //Peripheral base address in the alias region #define AHB1PERIPH_BASE (PERIPH_BASE + 0x00020000U) #define GPIOA_BASE (AHB1PERIPH_BASE + 0x0000U) #define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) using std::uint32_t ; #define __forceinline _Pragma("inline=forced") constexpr uint32_t OdrShift= 20U ; constexpr uint32_t IdrShift= 16U ; constexpr uint32_t PupdrShift = 12U ; constexpr uint32_t OspeedrShift = 8U ; constexpr uint32_t OtyperShift = 4U ; constexpr uint32_t GpioaOdrAddr = GPIOA_BASE + OdrShift ; constexpr uint32_t GpioaIdrAddr = GPIOA_BASE + IdrShift ; namespace Case3 { class Register { public: explicit Register(uint32_t addr) : ptr{ reinterpret_cast<volatile uint32_t *>(addr) } { } inline Register &operator^=(const uint32_t right) { *ptr ^= right; return *this; } private: volatile std::uint32_t *ptr; }; } namespace Case4 { template<uint32_t addr> class Register { public: Register() : raw_ptr{reinterpret_cast<volatile uint32_t *>(addr)} { } inline Register &operator^=(const uint32_t right) { *raw_ptr ^= right; return *this; } private: volatile std::uint32_t *raw_ptr; }; } namespace Case5 { template<uint32_t addr> class Register { public: __forceinline Register &operator^=(const uint32_t right) { *reinterpret_cast<volatile uint32_t *>(addr) ^= right; return *this; } }; } namespace Case6 { template<uint32_t addr> class Register { public: __forceinline static void Xor(const uint32_t mask) { *reinterpret_cast<volatile uint32_t *>(addr) ^= mask; } }; } namespace Case7 { template<uint32_t addr, uint32_t pinNum> struct Pin { using Registers = GPIO_TypeDef ; __forceinline inline static void Toggle() { Registers *GpioPort{reinterpret_cast<Registers*>(addr)}; GpioPort->ODR ^= 1 << pinNum ; } }; } namespace Case8 { struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T> class Register { public: __forceinline template <typename T1 = T, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> Register &operator^=(const uint32_t right) { *reinterpret_cast<volatile uint32_t *>(addr) ^= right; return *this; } }; } namespace Case9 { struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T> class Register { public: __forceinline template <typename T1 = T, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> inline static void Xor(const uint32_t mask) { *reinterpret_cast<volatile int*>(addr) ^= mask; } }; struct GpioBase {} ; template<uint32_t addr> struct Gpio : public GpioBase { using Moder = Register<addr, ReadWriteReg>; using Otyper = Register<addr + OtyperShift, ReadWriteReg> ; using Ospeedr = Register<addr + OspeedrShift,ReadWriteReg> ; using Pupdr = Register<addr + PupdrShift,ReadWriteReg> ; using Idr = Register<addr + IdrShift, ReadReg> ; using Odr = Register<addr + OdrShift, WriteReg> ; }; } namespace Case10 { template<uint32_t addr, typename T> class RegisterStructWrapper { public: __forceinline template<typename P> inline static void Xor(P T::*member, int mask) { reinterpret_cast<T*>(addr)->*member ^= mask ; } } ; } namespace Case11 { struct WriteReg {}; struct ReadReg {}; struct ReadWriteReg: public WriteReg, public ReadReg {}; template<uint32_t addr, typename T, volatile uint32_t T::*member, typename RegType> class Register { public: __forceinline template <typename T1 = RegType, class = typename std::enable_if_t<std::is_base_of<WriteReg, T1>::value>> inline static void Xor(const uint32_t mask) { reinterpret_cast<T*>(addr)->*member ^= mask ; } }; template<uint32_t addr, typename T> struct Gpio { using Moder = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::ODR, ReadWriteReg>; using Otyper = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::OTYPER, ReadWriteReg>; using Ospeedr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::OSPEEDR, ReadWriteReg>; using Pupdr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::PUPDR, ReadWriteReg>; using Idr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::IDR, ReadReg>; using Odr = Register<addr, GPIO_TypeDef, &GPIO_TypeDef::ODR, WriteReg>; } ; } ; struct Test { const int a; const int b; } ; template<Test* mystruct> constexpr int Geta() { return mystruct->a; } Test test{1,2}; int main() { // RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // GPIOA->MODER |= GPIO_MODER_MODE5_0; Geta<&test>() ; //Вариант 1 GPIOA->ODR ^= (1 << 5) ; GPIOA->IDR ^= (1 << 5) ; //глупенько, но можно //Вариант 2 *reinterpret_cast<volatile uint32_t *>(GpioaOdrAddr) ^= (1 <<5) ; *reinterpret_cast<volatile uint32_t *>(GpioaIdrAddr) ^= (1 <<5) ; //Вариант 3 { using namespace Case3 ; Register Odr{GpioaOdrAddr}; Odr ^= (1 << 5); Register Idr{GpioaIdrAddr}; Idr ^= (1 << 5); } //Вариант 4 { using namespace Case4 ; using GpioaOdr = Register<GpioaOdrAddr>; GpioaOdr Odr; Odr ^= (1 << 5); using GpioaIdr = Register<GpioaIdrAddr>; GpioaIdr Idr; Idr ^= (1 << 5); } //Вариант 5 { using namespace Case5 ; using GpioaOdr = Register<GpioaOdrAddr>; GpioaOdr Odr; Odr ^= (1 << 5); using GpioaIdr = Register<GpioaIdrAddr>; GpioaIdr Idr; Idr ^= (1 << 5); } //Вариант 6 { using namespace Case6 ; using Odr = Register<GpioaOdrAddr>; Odr::Xor(1 << 5); using Idr = Register<GpioaIdrAddr>; Idr::Xor(1 << 5); } //Вариант 7 { using namespace Case7 ; using Led1 = Pin<GPIOA_BASE,5> ; Led1::Toggle() ; //volatile Gpio* GpioA{reinterpret_cast<volatile Gpio*>(GPIOA_BASE)} ; //GpioA->ODR ^= (1 << 5) ; //GpioA->IDR ^= (1 << 5) ; } //вариант 8 { using namespace Case8 ; using GpioaOdr = Register<GpioaOdrAddr, WriteReg> ; GpioaOdr Odr ; Odr ^= (1 << 5) ; using GpioaIdr = Register<GpioaIdrAddr, ReadReg> ; GpioaIdr Idr ; //Idr ^= (1 << 5) ; //ошибка, регистра Idr только для чтения } //вариант 9 { using namespace Case9 ; using Odr = Register<GpioaOdrAddr, WriteReg>; Odr::Xor(1 << 5); using Idr = Register<GpioaIdrAddr, ReadReg>; //Idr::Xor(1 << 5); using Gpioa = Gpio<GPIOA_BASE> ; Gpioa::Odr::Xor(1 << 5) ; //Gpioa::Idr::Xor((1 << 5) ); //ошибка, регистр Idr только для чтения } //вариант 10 { using namespace Case10 ; using GpioaWarpper = RegisterStructWrapper<GPIOA_BASE, GPIO_TypeDef> ; GpioaWarpper::Xor(&GPIO_TypeDef::ODR, (1 << 5)) ; } //вариант 11 { using namespace Case11 ; using GpioaOdr = Register<GPIOA_BASE, GPIO_TypeDef, &GPIO_TypeDef::ODR, WriteReg> ; using GpioaIdr = Register<GPIOA_BASE, GPIO_TypeDef, &GPIO_TypeDef::IDR, ReadReg> ; GpioaOdr::Xor(1 << 5) ; //GpioaIdr::Xor(1 << 5) ; using Gpioa = Gpio<GPIOA_BASE, GPIO_TypeDef> ; Gpioa::Odr::Xor(1 << 5) ; //Gpioa::Idr::Xor((1 << 5) ); //ошибка, регистр Idr только для чтения } return 0; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue