├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── COPYING ├── README └── src ├── CMakeLists.txt ├── README ├── app ├── CMakeLists.txt ├── README ├── app_button │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── app_i2c0_eeprom │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── app_led_flash │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── app_spi0_flash │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── app_uart1_comms │ ├── AllMsgsDefs.h │ ├── CMakeLists.txt │ ├── Session.cpp │ ├── Session.h │ ├── System.cpp │ ├── System.h │ ├── main.cpp │ └── message │ │ ├── ButtonStateChangeMsg.h │ │ ├── HeartbeatMsg.h │ │ ├── LedState.h │ │ ├── LedStateChangeMsg.h │ │ ├── LedStateCtrlMsg.h │ │ └── MsgId.h ├── app_uart1_echo │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── app_uart1_logging │ ├── CMakeLists.txt │ ├── System.cpp │ ├── System.h │ └── main.cpp └── app_uart1_morse │ ├── CMakeLists.txt │ ├── Morse.h │ ├── System.cpp │ ├── System.h │ └── main.cpp ├── asm ├── CMakeLists.txt └── startup.s ├── component ├── Button.h ├── Eeprom.h ├── Led.h └── OnBoardLed.h ├── device ├── CMakeLists.txt ├── EventLoopDevices.h ├── Function.cpp ├── Function.h ├── Gpio.h ├── I2C0.h ├── InterruptMgr.h ├── Spi0.h ├── Timer.h └── Uart1.h ├── raspberrypi.ld ├── stdlib ├── CMakeLists.txt ├── placeholders.cpp ├── stdlib_stub.cpp └── string.cpp └── test_cpp ├── CMakeLists.txt ├── README ├── test_cpp_abstract_class ├── AbstractBase.cpp ├── AbstractBase.h ├── CMakeLists.txt ├── Derived.cpp ├── Derived.h ├── main.cpp └── stub.cpp ├── test_cpp_exceptions ├── CMakeLists.txt ├── main.cpp └── stub.cpp ├── test_cpp_rtti ├── CMakeLists.txt ├── SomeClass.cpp ├── SomeClass.h ├── main.cpp └── stub.cpp ├── test_cpp_simple ├── CMakeLists.txt ├── main.cpp └── stub.cpp ├── test_cpp_statics ├── CMakeLists.txt ├── SomeObj.cpp ├── SomeObj.h ├── SomeObj2.cpp ├── main.cpp └── stub.cpp ├── test_cpp_tag_dispatch ├── CMakeLists.txt ├── main.cpp ├── tag.cpp └── tag.h ├── test_cpp_templates ├── CMakeLists.txt ├── main.cpp ├── other.cpp └── template.h └── test_cpp_vector ├── CMakeLists.txt ├── heap.cpp ├── main.cpp └── stub.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .project 3 | .cproject 4 | 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "external/embxx"] 2 | path = external/embxx 3 | url = git://github.com/arobenko/embxx.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | 3 | if (CMAKE_TOOLCHAIN_FILE AND EXISTS ${CMAKE_TOOLCHAIN_FILE}) 4 | message("==> Loading \${CMAKE_TOOLCHAIN_FILE} == ${CMAKE_TOOLCHAIN_FILE}") 5 | if(NOT DEFINED CMAKE_CROSSCOMPILING) 6 | message(FATAL_ERROR "Toolchain file must define CMAKE_SYSTEM_NAME, typically: set (CMAKE_SYSTEM_NAME \"Generic\")") 7 | endif() 8 | else() 9 | 10 | set (CMAKE_SYSTEM_NAME "Generic") 11 | if ("${CROSS_COMPILE}" STREQUAL "") 12 | set (CROSS_COMPILE "arm-none-eabi-") 13 | endif() 14 | 15 | if (CMAKE_VERSION VERSION_LESS 3.6) 16 | include(CMakeForceCompiler) 17 | cmake_force_c_compiler( "${CROSS_COMPILE}gcc" GNU) 18 | cmake_force_cxx_compiler("${CROSS_COMPILE}g++" GNU) 19 | else() 20 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 21 | set(CMAKE_C_COMPILER "${CROSS_COMPILE}gcc") 22 | set(CMAKE_CXX_COMPILER "${CROSS_COMPILE}g++") 23 | endif() 24 | 25 | endif() 26 | 27 | ######### 28 | 29 | project ("embxx_on_rpi") 30 | 31 | set (EXTERNALS_DIR "${CMAKE_SOURCE_DIR}/external") 32 | find_package (Git REQUIRED) 33 | 34 | execute_process ( 35 | COMMAND ${GIT_EXECUTABLE} submodule update --init 36 | WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 37 | 38 | set (CMAKE_MODULE_PATH "${EXTERNALS_DIR}/embxx/cmake") 39 | include (AR_AllExtras) 40 | 41 | embxx_add_cpp11_support () 42 | embxx_set_default_compiler_options () 43 | 44 | # for libraries and headers in the target directories 45 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 46 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 47 | 48 | set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) 49 | set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) 50 | 51 | set (STARTUP_LIB_NAME "startup") 52 | set (DEVICE_LIB_NAME "device") 53 | set (STDLIB_STUB_LIB_NAME "stdlib_stub") 54 | 55 | add_subdirectory (src) 56 | 57 | message(STATUS "Found C compiler: ${CMAKE_C_COMPILER}") 58 | message(STATUS "Found C++ compiler: ${CMAKE_CXX_COMPILER}") 59 | message(STATUS "Found ar: ${CMAKE_AR}") 60 | message(STATUS "Found ranlib: ${CMAKE_RANLIB}") 61 | message(STATUS "Found objcopy: ${CMAKE_OBJCOPY}") 62 | message(STATUS "Found objdump: ${CMAKE_OBJDUMP}") 63 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Overview 2 | ------------------- 3 | This main purpose of this project is to test embxx library and demonstrate its 4 | usage on Raspberry Pi as bare metal platform. 5 | 6 | What you need 7 | ------------------- 8 | 1. Git 9 | 2. CMake 10 | 3. Cross compiling gcc v4.7 toolchain or greater 11 | 12 | How to compile 13 | ------------------- 14 | 1. Make a build directory and cd there: 15 | > mkdir /build 16 | > cd /build 17 | 2. Generate makefiles using CMake while defining CROSS_COMPILE prefix: 18 | > cmake -DCROSS_COMPILE=/opt/arm-none-eabi-2013.05/bin/arm-none-eabi- .. 19 | 20 | If CROSS_COMPILE prefix is not defined "arm-none-eabi-" is used and directory 21 | containing all the toolchain utilities must be PATH environment variable. 22 | > cmake .. 23 | 24 | Please note that default cmake build type is similar to Debug mode but 25 | without any debug simbols in produced binaries. To change the default 26 | build type please use CMAKE_BUILD_TYPE definition when using cmake utility: 27 | > cmake -DCMAKE_BUILD_TYPE=Release -DCROSS_COMPILE=/opt/arm-none-eabi-2013.05/bin/arm-none-eabi- .. 28 | 29 | Please refer to CMake documentation for details about its build types. 30 | 31 | It is also possible to provide a separate toolchain file instead of 32 | specifying CROSS_COMPILE prefix. 33 | > cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain/file .. 34 | 35 | The custom toolchain file is expected to be similiar to this example: 36 | 37 | set (CMAKE_SYSTEM_NAME "Generic") 38 | include(CMakeForceCompiler) 39 | cmake_force_c_compiler(arm-none-eabi-gcc) 40 | cmake_force_cxx_compiler(arm-none-eabi-g++) 41 | 42 | For CMake version 3.6 or newer it can look like this: 43 | 44 | set (CMAKE_SYSTEM_NAME "Generic") 45 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 46 | set(CMAKE_C_COMPILER arm-none-eabi-gcc) 47 | set(CMAKE_CXX_COMPILER arm-none-eabi-g++) 48 | 49 | 3. Build the binaries: 50 | > make 51 | 52 | For the verbose make output use VERBOSE=1 environment variable: 53 | > VERBOSE=1 make 54 | 4. The image of every compiled application will be: 55 | /image//kernel.img 56 | 57 | 58 | Applications 59 | ------------------- 60 | See the README files in "src/app" directory for details of what each 61 | application (image) does. 62 | 63 | 64 | Git branches 65 | ------------------- 66 | "master" - main branch, will always contain latest stable (released) version 67 | that uses latest stable (released) version of embxx. 68 | "develop" - current development branch that uses latest development version of 69 | embxx. 70 | 71 | Contact information 72 | ------------------- 73 | Author: Alex Robenko 74 | E-mail: arobenko@gmail.com 75 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | set (LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/raspberrypi.ld) 3 | 4 | ################################################################# 5 | 6 | function (link_app tgt) 7 | 8 | set_target_properties (${tgt} 9 | PROPERTIES LINK_FLAGS "-Wl,-Map,kernel.map -T ${LINKER_SCRIPT}") 10 | 11 | add_custom_command ( 12 | TARGET ${tgt} 13 | POST_BUILD 14 | COMMAND 15 | ${CMAKE_OBJCOPY} $ -O binary 16 | $/kernel.img 17 | COMMAND 18 | ${CMAKE_OBJDUMP} -D -S $ > 19 | $/kernel.list 20 | COMMAND 21 | ${CMAKE_OBJDUMP} -t $ > 22 | $/kernel.syms 23 | COMMAND 24 | ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/image/${tgt} 25 | COMMAND 26 | ${CMAKE_COMMAND} -E copy $/kernel.img ${CMAKE_BINARY_DIR}/image/${tgt}) 27 | 28 | endfunction () 29 | 30 | ################################################################# 31 | 32 | add_subdirectory (asm) 33 | 34 | embxx_add_c_cxx_flags ("-march=armv6z") 35 | 36 | if (NOT NO_TEST_CPP) 37 | add_subdirectory (test_cpp) 38 | endif () 39 | 40 | 41 | embxx_add_c_cxx_flags ("-fno-threadsafe-statics") 42 | 43 | include_directories ( 44 | ${EXTERNALS_DIR}/embxx 45 | ${CMAKE_CURRENT_SOURCE_DIR}) 46 | 47 | embxx_disable_exceptions () 48 | embxx_disable_rtti () 49 | embxx_disable_stdlib () 50 | 51 | add_subdirectory (device) 52 | add_subdirectory (stdlib) 53 | add_subdirectory (app) 54 | -------------------------------------------------------------------------------- /src/README: -------------------------------------------------------------------------------- 1 | This directory contains sources of this project. See README in "app" directory 2 | for details of what each application does. 3 | 4 | The existing directories are: 5 | app - directory of the various applications 6 | asm - common startup (assembler) code for all the applications 7 | device - low level device (peripheral) control classes 8 | stdlib - stub for some stdlib functions. Currently all the applications are 9 | compiled without standard library. -------------------------------------------------------------------------------- /src/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory (app_led_flash) 2 | add_subdirectory (app_uart1_echo) 3 | add_subdirectory (app_button) 4 | add_subdirectory (app_uart1_logging) 5 | add_subdirectory (app_uart1_morse) 6 | add_subdirectory (app_uart1_comms) 7 | add_subdirectory (app_i2c0_eeprom) 8 | #add_subdirectory (app_spi0_flash) 9 | -------------------------------------------------------------------------------- /src/app/README: -------------------------------------------------------------------------------- 1 | This directory contains core logic of various applications. 2 | 3 | Current applications are: 4 | 5 | app_led_flash - This application flashes on-board led using arm timer 6 | to measure time. It changes led's state every half a second. 7 | 8 | app_uart1_echo - This application configures and uses uart1 as its serial 9 | terminal. It echoes every character back. The configuration is: 10 | Baud: 115200; Parity: None; Stop bits: 1; Flow control: off. 11 | 12 | app_uart1_logging - This application configures and uses uart1 as its serial 13 | output device. It uses output stream object to log the running counter 14 | value in both decimal and hexadecimal formats. Use your serial terminal 15 | application to view the output. The uart configuration is: 16 | Baud: 115200; Parity: None; Stop bits: 1; Flow control: off. 17 | 18 | app_uart1_morse - This application configures and uses uart1 as its serial 19 | input device. It reads the incomming characters and flashes the led 20 | with Morse code specific to the character. The read characters are 21 | accumulated in internal buffer until displayed using led. 22 | The uart configuration is: 23 | Baud: 115200; Parity: None; Stop bits: 1; Flow control: off. 24 | 25 | app_button - This application responds to button presses and releases. Every 26 | button press "Button Pressed" and every button release "Button Released" 27 | strings are logged asynchronously to UART1. In addition to this, every 28 | button press will activate on-board LED which will be on for exactly 29 | 1 second after the last press. The UART1 configuration is: 30 | Baud: 9600; Parity: None; Stop bits: 1; Flow control: off. 31 | Button configuration: GPIO 23, active (pressed) low 32 | 33 | app_i2c0_eeprom - This application demonstrates parallel access to two eeproms 34 | via I2C0 interface. It also uses UART1 to log its read/write operations. 35 | The I2C0 is configured to run with 100Hz clock speed and the 36 | uart configuration is: 37 | Baud: 115200; Parity: None; Stop bits: 1; Flow control: off. 38 | 39 | app_uart1_comms - This application uses serial interface (UART1) to send and 40 | receive messages. The main purpose of this application is to test "comms" 41 | module of the embxx library. 42 | The format of every message is: 43 | | | | Message data | 44 | All the fields are in "big endian" format. 45 | The first 2 synchronisation bytes are "0x48" and "0x69" which stand for 46 | "Hi" in ascii. They are followed by one byte of size field that 47 | indicates length (in bytes) of the rest of the message including 48 | checksum. Then there is 1 byte of message ID, followed by message data 49 | and 2 bytes of checksum. The checksum is a sum of all the bytes including 50 | first 2 synchronisation characters. The application expects the 51 | following messages as an input: 52 | - Led state control message. Has ID = 3, and 1 byte of intended new led 53 | state, which is 0 for "off" and 1 for "on". 54 | The application emits the following messages as an output: 55 | - Hearbeat message. Has ID = 0, and 2 bytes of sequential number as 56 | its message data. It is emitted every 2 seconds. 57 | - Button state change message. Has ID = 1, and 1 byte of state 58 | information which is 0 for "released" and "1" for pressed. This 59 | message is emitted as a response to every button press/release 60 | - Led state change message. Has ID = 2, and 1 byte of state information 61 | which is 0 for "off" and "1" for on. This message is emitted in 62 | response to incomming "Message state control" message which controls 63 | the state of the led. 64 | To see the output of this application use the "cat" in conjunction with 65 | "hexdump" commands on your Linux host machine: 66 | > cat /dev/ttyUSB0 | hexdump -v -C 67 | To emit the led control message on your host machine use printf 68 | redirected to proper device file: 69 | Led on: printf "\x48\x69\x04\x03\x01\x00\xb9" > /dev/ttyUSB0 70 | Led off: printf "\x48\x69\x04\x03\x00\x00\xb8" > /dev/ttyUSB0 71 | Don't forget to configure your serial device with stty utility. 72 | The UART1 configuration is: 73 | Baud: 115200; Parity: None; Stop bits: 1; Flow control: off. 74 | The Button configuration: GPIO 23, active (pressed) low. 75 | -------------------------------------------------------------------------------- /src/app/app_button/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_button) 2 | set (name "app_button") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | "gcc") 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_button() -------------------------------------------------------------------------------- /src/app/app_button/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | timerDevice_(interruptMgr_), 30 | buttonDriver_(gpio_, el_), 31 | uartDriver_(uart_, el_), 32 | timerMgr_(timerDevice_, el_), 33 | led_(gpio_), 34 | button_(buttonDriver_, ButtonPin), 35 | buf_(uartDriver_), 36 | stream_(buf_), 37 | log_("\r\n", stream_) 38 | { 39 | } 40 | 41 | extern "C" 42 | void interruptHandler() 43 | { 44 | System::instance().interruptMgr().handleInterrupt(); 45 | } 46 | -------------------------------------------------------------------------------- /src/app/app_button/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/StreamLogger.h" 21 | #include "embxx/util/log/LevelStringPrefixer.h" 22 | #include "embxx/util/log/StreamableValueSuffixer.h" 23 | #include "embxx/util/log/StreamFlushSuffixer.h" 24 | #include "embxx/util/EventLoop.h" 25 | #include "embxx/driver/Character.h" 26 | #include "embxx/driver/Gpio.h" 27 | #include "embxx/driver/TimerMgr.h" 28 | #include "embxx/io/OutStreamBuf.h" 29 | #include "embxx/io/OutStream.h" 30 | 31 | 32 | #include "device/Function.h" 33 | #include "device/Gpio.h" 34 | #include "device/InterruptMgr.h" 35 | #include "device/Timer.h" 36 | #include "device/EventLoopDevices.h" 37 | #include "device/Uart1.h" 38 | 39 | #include "component/OnBoardLed.h" 40 | #include "component/Button.h" 41 | 42 | class System 43 | { 44 | public: 45 | static const std::size_t EventLoopSpaceSize = 1024; 46 | typedef embxx::util::EventLoop< 47 | EventLoopSpaceSize, 48 | device::InterruptLock, 49 | device::WaitCond> EventLoop; 50 | 51 | // Devices 52 | typedef device::InterruptMgr<> InterruptMgr; 53 | typedef device::Gpio Gpio; 54 | typedef device::Uart1 Uart; 55 | typedef device::Timer TimerDevice; 56 | 57 | // Drivers 58 | typedef embxx::driver::Gpio ButtonDriver; 59 | 60 | struct CharacterTraits 61 | { 62 | typedef std::nullptr_t ReadHandler; 63 | typedef embxx::util::StaticFunction WriteHandler; 64 | typedef std::nullptr_t ReadUntilPred; 65 | static const std::size_t ReadQueueSize = 0; 66 | static const std::size_t WriteQueueSize = 1; 67 | }; 68 | typedef embxx::driver::Character UartDriver; 69 | typedef embxx::driver::TimerMgr< 70 | TimerDevice, 71 | EventLoop, 72 | 1> TimerMgr; 73 | 74 | // Components 75 | typedef component::OnBoardLed Led; 76 | typedef component::Button Button; 77 | 78 | static const std::size_t OutStreamBufSize = 1024; 79 | typedef embxx::io::OutStreamBuf OutStreamBuf; 80 | typedef embxx::io::OutStream OutStream; 81 | typedef embxx::util::log::StreamFlushSuffixer< 82 | embxx::util::log::StreamableValueSuffixer< 83 | const OutStream::CharType*, 84 | embxx::util::StreamLogger< 85 | embxx::util::log::Info, 86 | OutStream 87 | > 88 | > 89 | > Log; 90 | 91 | 92 | static System& instance(); 93 | 94 | inline EventLoop& eventLoop(); 95 | inline InterruptMgr& interruptMgr(); 96 | inline Gpio& gpio(); 97 | inline Uart& uart(); 98 | inline TimerMgr& timerMgr(); 99 | inline Led& led(); 100 | inline Button& button(); 101 | inline Log& log(); 102 | 103 | private: 104 | System(); 105 | 106 | EventLoop el_; 107 | 108 | // Devices 109 | InterruptMgr interruptMgr_; 110 | device::Function func_; 111 | Gpio gpio_; 112 | Uart uart_; 113 | TimerDevice timerDevice_; 114 | 115 | // Drivers 116 | ButtonDriver buttonDriver_; 117 | UartDriver uartDriver_; 118 | TimerMgr timerMgr_; 119 | 120 | // Components 121 | Led led_; 122 | Button button_; 123 | OutStreamBuf buf_; 124 | OutStream stream_; 125 | Log log_; 126 | 127 | static const unsigned SysClockFreq = 250000000; // 250MHz 128 | static const device::Function::PinIdxType ButtonPin = 23; 129 | }; 130 | 131 | extern "C" 132 | void interruptHandler(); 133 | 134 | // Implementation 135 | 136 | inline 137 | System::EventLoop& System::eventLoop() 138 | { 139 | return el_; 140 | } 141 | 142 | inline System::InterruptMgr& System::interruptMgr() 143 | { 144 | return interruptMgr_; 145 | } 146 | 147 | inline 148 | System::Gpio& System::gpio() 149 | { 150 | return gpio_; 151 | } 152 | 153 | inline 154 | System::Uart& System::uart() 155 | { 156 | return uart_; 157 | } 158 | 159 | inline 160 | System::TimerMgr& System::timerMgr() 161 | { 162 | return timerMgr_; 163 | } 164 | 165 | inline 166 | System::Led& System::led() 167 | { 168 | return led_; 169 | } 170 | 171 | inline 172 | System::Button& System::button() 173 | { 174 | return button_; 175 | } 176 | 177 | inline System::Log& System::log() 178 | { 179 | return log_; 180 | } 181 | 182 | -------------------------------------------------------------------------------- /src/app/app_button/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | #include 22 | 23 | #include "embxx/util/Assert.h" 24 | 25 | namespace 26 | { 27 | 28 | class LedOnAssert : public embxx::util::Assert 29 | { 30 | public: 31 | typedef System::Led Led; 32 | LedOnAssert(Led& led) 33 | : led_(led) 34 | { 35 | } 36 | 37 | virtual void fail( 38 | const char* expr, 39 | const char* file, 40 | unsigned int line, 41 | const char* function) 42 | { 43 | static_cast(expr); 44 | static_cast(file); 45 | static_cast(line); 46 | static_cast(function); 47 | 48 | led_.on(); 49 | device::interrupt::disable(); 50 | while (true) {;} 51 | } 52 | 53 | private: 54 | Led& led_; 55 | }; 56 | 57 | void buttonPressed(System::TimerMgr::Timer& timer) 58 | { 59 | static_cast(timer); 60 | auto& system = System::instance(); 61 | auto& el = system.eventLoop(); 62 | auto& led = system.led(); 63 | auto& log = system.log(); 64 | 65 | SLOG(log, embxx::util::log::Info, "Button Pressed"); 66 | 67 | timer.cancel(); 68 | auto result = el.post( 69 | [&led]() 70 | { 71 | led.on(); 72 | }); 73 | GASSERT(result); 74 | static_cast(result); 75 | 76 | static const auto WaitTime = std::chrono::seconds(1); 77 | timer.asyncWait( 78 | WaitTime, 79 | [&led](const embxx::error::ErrorStatus& es) 80 | { 81 | if (es == embxx::error::ErrorCode::Aborted) { 82 | return; 83 | } 84 | led.off(); 85 | }); 86 | } 87 | 88 | void buttonReleased() 89 | { 90 | auto& system = System::instance(); 91 | auto& log = system.log(); 92 | 93 | SLOG(log, embxx::util::log::Info, "Button Released"); 94 | } 95 | 96 | } // namespace 97 | 98 | int main() { 99 | auto& system = System::instance(); 100 | auto& led = system.led(); 101 | 102 | // Led on on assertion failure. 103 | embxx::util::EnableAssert assertion(std::ref(led)); 104 | 105 | // Configure uart 106 | auto& uart = system.uart(); 107 | uart.configBaud(9600); 108 | uart.setWriteEnabled(true); 109 | 110 | // Allocate timer 111 | auto& timerMgr = system.timerMgr(); 112 | auto timer = timerMgr.allocTimer(); 113 | GASSERT(timer.isValid()); 114 | 115 | // Set handlers for button press / release 116 | auto& button = system.button(); 117 | button.setPressedHandler( 118 | std::bind( 119 | &buttonPressed, 120 | std::ref(timer))); 121 | 122 | button.setReleasedHandler(&buttonReleased); 123 | 124 | // Run event loop with enabled interrupts 125 | device::interrupt::enable(); 126 | auto& el = system.eventLoop(); 127 | el.run(); 128 | 129 | GASSERT(0); // Mustn't exit 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /src/app/app_i2c0_eeprom/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_i2c0_eeprom) 2 | set (name "app_i2c0_eeprom") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | "gcc") 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_i2c0_eeprom() -------------------------------------------------------------------------------- /src/app/app_i2c0_eeprom/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | i2c_(interruptMgr_, func_), 30 | i2cOpQueue_(i2c_), 31 | i2cCharAdapter1_(i2cOpQueue_, EepromAddress1), 32 | i2cCharAdapter2_(i2cOpQueue_, EepromAddress2), 33 | uartDriver_(uart_, el_), 34 | i2cDriver1_(i2cCharAdapter1_, el_), 35 | i2cDriver2_(i2cCharAdapter2_, el_), 36 | led_(gpio_), 37 | eeprom1_(i2cDriver1_), 38 | eeprom2_(i2cDriver2_), 39 | buf_(uartDriver_), 40 | stream_(buf_), 41 | log_("\r\n", stream_) 42 | { 43 | uart_.configBaud(115200); 44 | uart_.setWriteEnabled(true); 45 | i2c_.setDivider(SysClockFreq/I2cFreq); 46 | } 47 | 48 | extern "C" 49 | void interruptHandler() 50 | { 51 | System::instance().interruptMgr().handleInterrupt(); 52 | } 53 | -------------------------------------------------------------------------------- /src/app/app_i2c0_eeprom/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/util/StreamLogger.h" 22 | #include "embxx/util/log/LevelStringPrefixer.h" 23 | #include "embxx/util/log/StreamableValueSuffixer.h" 24 | #include "embxx/util/log/StreamFlushSuffixer.h" 25 | #include "embxx/driver/Character.h" 26 | #include "embxx/io/OutStreamBuf.h" 27 | #include "embxx/io/OutStream.h" 28 | #include "embxx/device/DeviceOpQueue.h" 29 | #include "embxx/device/IdDeviceCharAdapter.h" 30 | 31 | #include "device/Function.h" 32 | #include "device/Gpio.h" 33 | #include "device/InterruptMgr.h" 34 | #include "device/Timer.h" 35 | #include "device/EventLoopDevices.h" 36 | #include "device/Uart1.h" 37 | #include "device/I2C0.h" 38 | 39 | #include "component/OnBoardLed.h" 40 | #include "component/Eeprom.h" 41 | 42 | class System 43 | { 44 | public: 45 | static const std::size_t EventLoopSpaceSize = 1024; 46 | typedef embxx::util::EventLoop< 47 | EventLoopSpaceSize, 48 | device::InterruptLock, 49 | device::WaitCond> EventLoop; 50 | 51 | typedef device::InterruptMgr<> InterruptMgr; 52 | 53 | typedef device::Gpio Gpio; 54 | 55 | typedef device::Uart1 Uart; 56 | 57 | typedef device::I2C0< 58 | InterruptMgr, 59 | embxx::util::StaticFunction, 60 | embxx::util::StaticFunction > I2C; 61 | 62 | typedef embxx::device::DeviceOpQueue I2cOpQueue; 63 | 64 | typedef embxx::device::IdDeviceCharAdapter CharI2cAdapter; 65 | 66 | struct CharacterTraits 67 | { 68 | typedef std::nullptr_t ReadHandler; 69 | typedef embxx::util::StaticFunction WriteHandler; 70 | typedef std::nullptr_t ReadUntilPred; 71 | static const std::size_t ReadQueueSize = 0; 72 | static const std::size_t WriteQueueSize = 1; 73 | }; 74 | typedef embxx::driver::Character UartDriver; 75 | 76 | typedef embxx::driver::Character I2cDriver; 77 | 78 | typedef component::OnBoardLed Led; 79 | typedef component::Eeprom< 80 | I2cDriver, 81 | embxx::util::StaticFunction 82 | > Eeprom; 83 | 84 | static const std::size_t OutStreamBufSize = 1024; 85 | typedef embxx::io::OutStreamBuf OutStreamBuf; 86 | typedef embxx::io::OutStream OutStream; 87 | typedef embxx::util::log::StreamFlushSuffixer< 88 | embxx::util::log::StreamableValueSuffixer< 89 | const OutStream::CharType*, 90 | embxx::util::log::LevelStringPrefixer< 91 | embxx::util::StreamLogger< 92 | embxx::util::log::Debug, 93 | OutStream 94 | > 95 | > 96 | > 97 | > Log; 98 | 99 | static System& instance(); 100 | 101 | inline EventLoop& eventLoop(); 102 | inline InterruptMgr& interruptMgr(); 103 | 104 | inline Led& led(); 105 | inline Eeprom& eeprom1(); 106 | inline Eeprom& eeprom2(); 107 | inline Log& log(); 108 | 109 | private: 110 | System(); 111 | 112 | EventLoop el_; 113 | 114 | // Devices 115 | InterruptMgr interruptMgr_; 116 | device::Function func_; 117 | Gpio gpio_; 118 | Uart uart_; 119 | I2C i2c_; 120 | I2cOpQueue i2cOpQueue_; 121 | CharI2cAdapter i2cCharAdapter1_; 122 | CharI2cAdapter i2cCharAdapter2_; 123 | 124 | // Drivers 125 | UartDriver uartDriver_; 126 | I2cDriver i2cDriver1_; 127 | I2cDriver i2cDriver2_; 128 | 129 | // Components 130 | Led led_; 131 | Eeprom eeprom1_; 132 | Eeprom eeprom2_; 133 | OutStreamBuf buf_; 134 | OutStream stream_; 135 | Log log_; 136 | 137 | static const unsigned SysClockFreq = 250000000; // 250MHz 138 | static const unsigned I2cFreq = 100000; // 100KHz 139 | static const I2C::DeviceIdType EepromAddress1 = 0x54; 140 | static const I2C::DeviceIdType EepromAddress2 = 0x55; 141 | }; 142 | 143 | extern "C" 144 | void interruptHandler(); 145 | 146 | // Implementation 147 | 148 | inline 149 | System::EventLoop& System::eventLoop() 150 | { 151 | return el_; 152 | } 153 | 154 | inline System::InterruptMgr& System::interruptMgr() 155 | { 156 | return interruptMgr_; 157 | } 158 | 159 | inline 160 | System::Led& System::led() 161 | { 162 | return led_; 163 | } 164 | 165 | inline System::Eeprom& System::eeprom1() 166 | { 167 | return eeprom1_; 168 | } 169 | 170 | inline System::Eeprom& System::eeprom2() 171 | { 172 | return eeprom2_; 173 | } 174 | 175 | inline 176 | System::Log& System::log() 177 | { 178 | return log_; 179 | } 180 | -------------------------------------------------------------------------------- /src/app/app_i2c0_eeprom/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "embxx/util/Assert.h" 25 | #include "embxx/util/StreamLogger.h" 26 | #include "embxx/io/access.h" 27 | 28 | namespace 29 | { 30 | 31 | class LedOnAssert : public embxx::util::Assert 32 | { 33 | public: 34 | typedef System::Led Led; 35 | LedOnAssert(Led& led) 36 | : led_(led) 37 | { 38 | } 39 | 40 | virtual void fail( 41 | const char* expr, 42 | const char* file, 43 | unsigned int line, 44 | const char* function) 45 | { 46 | static_cast(expr); 47 | static_cast(file); 48 | static_cast(line); 49 | static_cast(function); 50 | 51 | led_.on(); 52 | device::interrupt::disable(); 53 | while (true) {;} 54 | } 55 | 56 | private: 57 | Led& led_; 58 | }; 59 | 60 | bool verifySeqCorrect( 61 | const System::I2C::CharType* buf, 62 | std::size_t bufSize) 63 | { 64 | int step = 1; 65 | if (buf[0] != static_cast(0)) { 66 | step = -1; 67 | } 68 | 69 | auto expValue = buf[0] + step; 70 | for (std::size_t idx = 1U; idx < bufSize; ++idx) { 71 | if (buf[idx] != expValue) { 72 | return false; 73 | } 74 | expValue += step; 75 | } 76 | 77 | return true; 78 | } 79 | 80 | void readFunc( 81 | System::Eeprom& eeprom, 82 | System::Eeprom::EepromAddressType address, 83 | System::I2C::CharType* buf, 84 | std::size_t bufSize, 85 | System::Eeprom::EepromAddressType maxAddress); 86 | 87 | 88 | void writeFunc( 89 | System::Eeprom& eeprom, 90 | System::Eeprom::EepromAddressType address, 91 | System::I2C::CharType* buf, 92 | std::size_t bufSize, 93 | System::Eeprom::EepromAddressType maxAddress) 94 | { 95 | if (maxAddress <= address) { 96 | readFunc(eeprom, 0, buf, bufSize, maxAddress); 97 | return; 98 | } 99 | 100 | auto bufIter = &buf[0]; 101 | embxx::io::writeBig(address, bufIter); 102 | std::size_t writeCount = std::min(bufSize, std::size_t(maxAddress - address) + sizeof(address)); 103 | 104 | eeprom.asyncWrite(buf, writeCount, 105 | [&eeprom, address, buf, bufSize, maxAddress, writeCount](const embxx::error::ErrorStatus& err, std::size_t bytesTransferred) 106 | { 107 | auto& log = System::instance().log(); 108 | 109 | if (err) { 110 | SLOG(log, embxx::util::log::Error, 111 | "W (0x" << embxx::io::hex << embxx::io::setw(0) << 112 | eeprom.getDeviceId() << ") : Failed with error " << 113 | err); 114 | return; 115 | } 116 | 117 | GASSERT(bytesTransferred == writeCount); 118 | static_cast(bytesTransferred); 119 | auto writtenDataCount = writeCount - sizeof(address); 120 | SLOG(log, embxx::util::log::Info, 121 | "W (0x" << embxx::io::hex << embxx::io::setw(0) << 122 | eeprom.getDeviceId() << ") : [0x" << 123 | embxx::io::setfill('0') << embxx::io::setw(sizeof(address) * 2) << 124 | address << " - 0x" << address + (writtenDataCount - 1) << 125 | "] : {0x" << embxx::io::setw(sizeof(System::I2C::CharType) * 2) << 126 | static_cast(buf[sizeof(address)]) << " .. 0x" << 127 | static_cast(buf[writeCount - 1]) << "} " << 128 | embxx::io::setw(0) << embxx::io::dec << writtenDataCount << " bytes"); 129 | 130 | writeFunc(eeprom, address + writtenDataCount, buf, bufSize, maxAddress); 131 | }); 132 | } 133 | 134 | void readFunc( 135 | System::Eeprom& eeprom, 136 | System::Eeprom::EepromAddressType address, 137 | System::I2C::CharType* buf, 138 | std::size_t bufSize, 139 | System::Eeprom::EepromAddressType maxAddress) 140 | { 141 | if (maxAddress <= address) { 142 | writeFunc(eeprom, 0, buf, bufSize, maxAddress); 143 | return; 144 | } 145 | 146 | auto bufIter = &buf[0]; 147 | embxx::io::writeBig(address, bufIter); 148 | 149 | eeprom.asyncWrite(buf, sizeof(address), 150 | [&eeprom, address, buf, bufSize, maxAddress](const embxx::error::ErrorStatus& err, std::size_t bytesWritten) 151 | { 152 | auto& log = System::instance().log(); 153 | if (err) { 154 | SLOG(log, embxx::util::log::Error, 155 | "R (0x" << embxx::io::hex << embxx::io::setw(0) << 156 | eeprom.getDeviceId() << ") : Failed to set address with error " << 157 | err); 158 | return; 159 | } 160 | 161 | static_cast(bytesWritten); 162 | GASSERT(bytesWritten == sizeof(address)); 163 | std::size_t readCount = std::min(bufSize - sizeof(address), std::size_t(maxAddress - address)); 164 | 165 | eeprom.asyncRead(&buf[sizeof(address)], readCount, 166 | [&eeprom, address, buf, bufSize, maxAddress, readCount](const embxx::error::ErrorStatus& err2, std::size_t bytesRead) 167 | { 168 | auto& log2 = System::instance().log(); 169 | 170 | if (err2) { 171 | SLOG(log2, embxx::util::log::Error, 172 | "R (0x" << embxx::io::hex << embxx::io::setw(0) << 173 | eeprom.getDeviceId() << ") : Failed to read with error " << 174 | err2); 175 | return; 176 | } 177 | 178 | static_cast(bytesRead); 179 | GASSERT(bytesRead == readCount); 180 | 181 | auto readBuf = &buf[sizeof(address)]; 182 | SLOG(log2, embxx::util::log::Info, 183 | "R (0x" << embxx::io::hex << embxx::io::setw(0) << 184 | eeprom.getDeviceId() << ") : [0x" << 185 | embxx::io::setfill('0') << embxx::io::setw(sizeof(address) * 2) << 186 | address << " - 0x" << address + (readCount - 1) << 187 | "] : {0x" << embxx::io::setw(sizeof(System::I2C::CharType) * 2) << 188 | static_cast(readBuf[0]) << " .. 0x" << 189 | static_cast(readBuf[readCount - 1]) << "} " << 190 | embxx::io::setw(0) << embxx::io::dec << readCount << " bytes"); 191 | 192 | if (!verifySeqCorrect(&readBuf[0], readCount)) { 193 | SLOG(log2, embxx::util::log::Error, 194 | "Read mismatch for 0x" << eeprom.getDeviceId() << "!!!"); 195 | return; 196 | } 197 | 198 | readFunc(eeprom, address + readCount, buf, bufSize, maxAddress); 199 | }); 200 | }); 201 | } 202 | 203 | } // namespace 204 | 205 | int main() { 206 | auto& system = System::instance(); 207 | auto& led = system.led(); 208 | 209 | // Led on on assertion failure. 210 | embxx::util::EnableAssert assertion(std::ref(led)); 211 | 212 | auto& log = system.log(); 213 | SLOG(log, embxx::util::log::Info, "Starting Write..."); 214 | 215 | static const std::size_t ChunkSize = 128; // Maximum supported by eeprom 216 | static const std::size_t BufSize = ChunkSize + sizeof(System::Eeprom::EepromAddressType); 217 | typedef std::array DataBuf; 218 | 219 | DataBuf data1; 220 | for (auto i = 0U; i < ChunkSize; ++i) { 221 | auto idx = i + sizeof(System::Eeprom::EepromAddressType); 222 | data1[idx] = static_cast(i); 223 | } 224 | 225 | DataBuf data2; 226 | for (auto i = 0U; i < ChunkSize; ++i) { 227 | auto idx = i + sizeof(System::Eeprom::EepromAddressType); 228 | data2[idx] = static_cast(ChunkSize - (i + 1)); 229 | } 230 | 231 | static const System::Eeprom::AttemtsCountType EepromAttemptCount = 20; 232 | auto& eeprom1 = system.eeprom1(); 233 | eeprom1.setAttemptsLimit(EepromAttemptCount); 234 | auto& eeprom2 = system.eeprom2(); 235 | eeprom2.setAttemptsLimit(EepromAttemptCount); 236 | 237 | static const System::Eeprom::EepromAddressType MaxAddress = 4 * 1024; // 4KB 238 | 239 | writeFunc(eeprom1, 0, &data1[0], BufSize, MaxAddress); 240 | writeFunc(eeprom2, 0, &data2[0], BufSize, MaxAddress); 241 | 242 | device::interrupt::enable(); 243 | auto& el = system.eventLoop(); 244 | el.run(); 245 | 246 | GASSERT(0); // Mustn't exit 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /src/app/app_led_flash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_led_flash) 2 | set (name "app_led_flash") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | gcc) 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_led_flash() 22 | -------------------------------------------------------------------------------- /src/app/app_led_flash/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : timerDevice_(interruptMgr_), 28 | gpio_(interruptMgr_, func_), 29 | timerMgr_(timerDevice_, el_), 30 | led_(gpio_) 31 | { 32 | } 33 | 34 | extern "C" 35 | void interruptHandler() 36 | { 37 | System::instance().interruptMgr().handleInterrupt(); 38 | } 39 | -------------------------------------------------------------------------------- /src/app/app_led_flash/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/driver/TimerMgr.h" 22 | 23 | #include "device/Function.h" 24 | #include "device/Gpio.h" 25 | #include "device/InterruptMgr.h" 26 | #include "device/Timer.h" 27 | #include "device/EventLoopDevices.h" 28 | 29 | #include "component/OnBoardLed.h" 30 | 31 | class System 32 | { 33 | public: 34 | static const std::size_t EventLoopSpaceSize = 1024; 35 | typedef embxx::util::EventLoop< 36 | EventLoopSpaceSize, 37 | device::InterruptLock, 38 | device::WaitCond> EventLoop; 39 | 40 | typedef device::InterruptMgr<> InterruptMgr; 41 | typedef device::Gpio Gpio; 42 | typedef device::Timer TimerDevice; 43 | 44 | static const std::size_t NumOfTimers = 10; 45 | typedef embxx::driver::TimerMgr< 46 | TimerDevice, 47 | EventLoop, 48 | NumOfTimers, 49 | embxx::util::StaticFunction > TimerMgr; 50 | 51 | typedef component::OnBoardLed Led; 52 | 53 | 54 | static System& instance(); 55 | 56 | inline EventLoop& eventLoop(); 57 | inline InterruptMgr& interruptMgr(); 58 | inline TimerDevice& timerDevice(); 59 | inline TimerMgr& timerMgr(); 60 | inline Led& led(); 61 | 62 | 63 | private: 64 | System(); 65 | 66 | EventLoop el_; 67 | 68 | // Devices 69 | InterruptMgr interruptMgr_; 70 | TimerDevice timerDevice_; 71 | device::Function func_; 72 | Gpio gpio_; 73 | 74 | // Drivers 75 | TimerMgr timerMgr_; 76 | 77 | // Components 78 | Led led_; 79 | }; 80 | 81 | extern "C" 82 | void interruptHandler(); 83 | 84 | // Implementation 85 | 86 | inline 87 | System::EventLoop& System::eventLoop() 88 | { 89 | return el_; 90 | } 91 | 92 | inline 93 | System::InterruptMgr& System::interruptMgr() 94 | { 95 | return interruptMgr_; 96 | } 97 | 98 | inline 99 | System::TimerDevice& System::timerDevice() 100 | { 101 | return timerDevice_; 102 | } 103 | 104 | inline 105 | System::TimerMgr& System::timerMgr() 106 | { 107 | return timerMgr_; 108 | } 109 | 110 | inline 111 | System::Led& System::led() 112 | { 113 | return led_; 114 | } 115 | -------------------------------------------------------------------------------- /src/app/app_led_flash/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | #include 22 | 23 | #include "embxx/util/Assert.h" 24 | 25 | namespace 26 | { 27 | 28 | const auto LedChangeStateTimeout = std::chrono::milliseconds(500); 29 | 30 | template 31 | void ledOff( 32 | TTimer& timer, 33 | System::Led& led); 34 | 35 | template 36 | void ledOn( 37 | TTimer& timer, 38 | System::Led& led) 39 | { 40 | led.on(); 41 | 42 | timer.asyncWait( 43 | LedChangeStateTimeout, 44 | [&timer, &led](const embxx::error::ErrorStatus& status) 45 | { 46 | static_cast(status); 47 | ledOff(timer, led); 48 | }); 49 | } 50 | 51 | template 52 | void ledOff( 53 | TTimer& timer, 54 | System::Led& led) 55 | { 56 | led.off(); 57 | 58 | timer.asyncWait( 59 | std::chrono::milliseconds(LedChangeStateTimeout), 60 | [&timer, &led](const embxx::error::ErrorStatus& status) 61 | { 62 | static_cast(status); 63 | ledOn(timer, led); 64 | }); 65 | } 66 | 67 | class LedOnAssert : public embxx::util::Assert 68 | { 69 | public: 70 | typedef System::Led Led; 71 | LedOnAssert(Led& led) 72 | : led_(led) 73 | { 74 | } 75 | 76 | virtual void fail( 77 | const char* expr, 78 | const char* file, 79 | unsigned int line, 80 | const char* function) 81 | { 82 | static_cast(expr); 83 | static_cast(file); 84 | static_cast(line); 85 | static_cast(function); 86 | 87 | led_.on(); 88 | while (true) {;} 89 | } 90 | 91 | private: 92 | Led& led_; 93 | }; 94 | 95 | } // namespace 96 | 97 | int main() { 98 | auto& system = System::instance(); 99 | auto& led = system.led(); 100 | embxx::util::EnableAssert assertion(std::ref(led)); 101 | 102 | auto& timerMgr = system.timerMgr(); 103 | auto timer = timerMgr.allocTimer(); 104 | GASSERT(timer.isValid()); 105 | device::interrupt::enable(); 106 | 107 | ledOff(timer, led); 108 | 109 | auto& el = system.eventLoop(); 110 | el.run(); 111 | GASSERT(0); // Mustn't exit 112 | return 0; 113 | } 114 | -------------------------------------------------------------------------------- /src/app/app_spi0_flash/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_spi0_flash) 2 | set (name "app_spi0_flash") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | "gcc") 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_spi0_flash() -------------------------------------------------------------------------------- /src/app/app_spi0_flash/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | spi_(interruptMgr_, func_), 30 | spiOpQueue_(spi_), 31 | spiCharAdapter_(spiOpQueue_, SpiDevIdx), 32 | uartDriver_(uart_, el_), 33 | spiDriver_(spiCharAdapter_, el_), 34 | led_(gpio_), 35 | buf_(uartDriver_), 36 | stream_(buf_), 37 | log_("\r\n", stream_), 38 | spiInBuf_(spiDriver_) 39 | { 40 | uart_.configBaud(115200); 41 | uart_.setWriteEnabled(true); 42 | spi_.setFreq(SysClockFreq, InitialSpiFreq); 43 | spi_.setMode(Spi::Mode0); 44 | } 45 | 46 | extern "C" 47 | void interruptHandler() 48 | { 49 | System::instance().interruptMgr().handleInterrupt(); 50 | } 51 | -------------------------------------------------------------------------------- /src/app/app_spi0_flash/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/util/StreamLogger.h" 22 | #include "embxx/util/log/LevelStringPrefixer.h" 23 | #include "embxx/util/log/StreamableValueSuffixer.h" 24 | #include "embxx/util/log/StreamFlushSuffixer.h" 25 | #include "embxx/driver/Character.h" 26 | #include "embxx/io/InStreamBuf.h" 27 | #include "embxx/io/OutStreamBuf.h" 28 | #include "embxx/io/OutStream.h" 29 | #include "embxx/device/DeviceOpQueue.h" 30 | #include "embxx/device/IdDeviceCharAdapter.h" 31 | 32 | #include "device/Function.h" 33 | #include "device/Gpio.h" 34 | #include "device/InterruptMgr.h" 35 | #include "device/Timer.h" 36 | #include "device/EventLoopDevices.h" 37 | #include "device/Uart1.h" 38 | #include "device/Spi0.h" 39 | 40 | #include "component/OnBoardLed.h" 41 | 42 | class System 43 | { 44 | public: 45 | static const std::size_t EventLoopSpaceSize = 1024; 46 | typedef embxx::util::EventLoop< 47 | EventLoopSpaceSize, 48 | device::InterruptLock, 49 | device::WaitCond> EventLoop; 50 | 51 | typedef device::InterruptMgr<> InterruptMgr; 52 | 53 | typedef device::Gpio Gpio; 54 | 55 | typedef device::Uart1 Uart; 56 | 57 | typedef device::Spi0< 58 | InterruptMgr, 59 | embxx::util::StaticFunction, 60 | embxx::util::StaticFunction > Spi; 61 | 62 | typedef embxx::device::DeviceOpQueue SpiOpQueue; 63 | 64 | typedef embxx::device::IdDeviceCharAdapter CharSpiAdapter; 65 | 66 | struct CharacterTraits 67 | { 68 | typedef std::nullptr_t ReadHandler; 69 | typedef embxx::util::StaticFunction WriteHandler; 70 | typedef std::nullptr_t ReadUntilPred; 71 | static const std::size_t ReadQueueSize = 0; 72 | static const std::size_t WriteQueueSize = 1; 73 | }; 74 | typedef embxx::driver::Character UartDriver; 75 | 76 | typedef embxx::driver::Character SpiDriver; 77 | 78 | typedef embxx::io::InStreamBuf SpiInStreamBuf; 79 | 80 | typedef component::OnBoardLed Led; 81 | 82 | static const std::size_t LogStreamBufSize = 4096 * 2; 83 | typedef embxx::io::OutStreamBuf LogStreamBuf; 84 | typedef embxx::io::OutStream OutStream; 85 | typedef embxx::util::log::StreamFlushSuffixer< 86 | embxx::util::log::StreamableValueSuffixer< 87 | const OutStream::CharType*, 88 | embxx::util::log::LevelStringPrefixer< 89 | embxx::util::StreamLogger< 90 | embxx::util::log::Debug, 91 | OutStream 92 | > 93 | > 94 | > 95 | > Log; 96 | 97 | static System& instance(); 98 | 99 | inline EventLoop& eventLoop(); 100 | inline InterruptMgr& interruptMgr(); 101 | 102 | inline Led& led(); 103 | inline Log& log(); 104 | 105 | SpiDriver& spi() { 106 | return spiDriver_; 107 | } 108 | 109 | SpiInStreamBuf& spiInBuf() { 110 | return spiInBuf_; 111 | } 112 | 113 | // TODO: move to private 114 | static const Spi::DeviceIdType SpiDevIdx = 0; 115 | private: 116 | System(); 117 | 118 | EventLoop el_; 119 | 120 | // Devices 121 | InterruptMgr interruptMgr_; 122 | device::Function func_; 123 | Gpio gpio_; 124 | Uart uart_; 125 | Spi spi_; 126 | SpiOpQueue spiOpQueue_; 127 | CharSpiAdapter spiCharAdapter_; 128 | 129 | // Drivers 130 | UartDriver uartDriver_; 131 | SpiDriver spiDriver_; 132 | 133 | // Components 134 | Led led_; 135 | LogStreamBuf buf_; 136 | OutStream stream_; 137 | Log log_; 138 | SpiInStreamBuf spiInBuf_; 139 | 140 | static const unsigned SysClockFreq = 250000000; // 250MHz 141 | static const unsigned InitialSpiFreq = 200000; // 200KHz 142 | 143 | }; 144 | 145 | extern "C" 146 | void interruptHandler(); 147 | 148 | // Implementation 149 | 150 | inline 151 | System::EventLoop& System::eventLoop() 152 | { 153 | return el_; 154 | } 155 | 156 | inline System::InterruptMgr& System::interruptMgr() 157 | { 158 | return interruptMgr_; 159 | } 160 | 161 | inline 162 | System::Led& System::led() 163 | { 164 | return led_; 165 | } 166 | 167 | inline 168 | System::Log& System::log() 169 | { 170 | return log_; 171 | } 172 | -------------------------------------------------------------------------------- /src/app/app_spi0_flash/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "embxx/util/Assert.h" 25 | #include "embxx/util/StreamLogger.h" 26 | #include "embxx/io/access.h" 27 | 28 | namespace 29 | { 30 | 31 | class LedOnAssert : public embxx::util::Assert 32 | { 33 | public: 34 | typedef System::Led Led; 35 | LedOnAssert(Led& led) 36 | : led_(led) 37 | { 38 | } 39 | 40 | virtual void fail( 41 | const char* expr, 42 | const char* file, 43 | unsigned int line, 44 | const char* function) 45 | { 46 | static_cast(expr); 47 | static_cast(file); 48 | static_cast(line); 49 | static_cast(function); 50 | 51 | led_.on(); 52 | // device::interrupt::disable(); 53 | // while (true) {;} 54 | 55 | auto& log = System::instance().log(); 56 | SLOG(log, embxx::util::log::Error, "Assertion `" << expr << "` in " << function << " at " << file << ":" << line); 57 | } 58 | 59 | private: 60 | Led& led_; 61 | }; 62 | 63 | void performInit(unsigned attempt) 64 | { 65 | static const std::uint8_t Cmd0[] = { 66 | 0x40, 0x0, 0x0, 0x0, 0x0, 0x95 67 | }; 68 | 69 | static const std::size_t Cmd0Size = std::extent::value; 70 | 71 | SLOG(System::instance().log(), embxx::util::log::Info, "Attempt " << attempt); 72 | 73 | auto& spi = System::instance().spi(); 74 | spi.asyncWrite( 75 | &Cmd0[0], 76 | Cmd0Size, 77 | [](const embxx::error::ErrorStatus& es, std::size_t bytesWritten) 78 | { 79 | SLOG(System::instance().log(), embxx::util::log::Info, "Write complete!"); 80 | GASSERT(!es); 81 | GASSERT(bytesWritten == Cmd0Size); 82 | }); 83 | 84 | auto& spiInBuf = System::instance().spiInBuf(); 85 | spiInBuf.start(); 86 | 87 | static const unsigned DataBufSize = 128; 88 | spiInBuf.asyncWaitDataAvailable( 89 | DataBufSize, 90 | [&spiInBuf, attempt](const embxx::error::ErrorStatus& es) 91 | { 92 | SLOG(System::instance().log(), embxx::util::log::Info, "Block"); 93 | GASSERT(!es); 94 | spiInBuf.stop(); 95 | auto iter = spiInBuf.begin(); 96 | for (auto i = 0U; i < DataBufSize; ++i) { 97 | auto byte = embxx::io::readBig(iter); 98 | if (byte != 0xff) { 99 | SLOG(System::instance().log(), embxx::util::log::Info, "Byte=0x" << embxx::io::hex << (unsigned)byte); 100 | return; 101 | } 102 | } 103 | spiInBuf.consume(); 104 | 105 | for (volatile int i = 0; i < 1000000; ++i) {} 106 | performInit(attempt + 1); 107 | }); 108 | } 109 | 110 | } // namespace 111 | 112 | int main() { 113 | device::interrupt::disable(); 114 | 115 | auto& system = System::instance(); 116 | auto& led = system.led(); 117 | 118 | // Led on on assertion failure. 119 | embxx::util::EnableAssert assertion(std::ref(led)); 120 | 121 | auto& log = system.log(); 122 | SLOG(log, embxx::util::log::Info, "Starting Write..."); 123 | 124 | led.on(); 125 | for (volatile int i = 0; i < 5000000; ++i) {} 126 | led.off(); 127 | 128 | auto& spi = system.spi(); 129 | spi.device().device().device().setFillChar(0xff); 130 | 131 | performInit(0); 132 | 133 | device::interrupt::enable(); 134 | auto& el = system.eventLoop(); 135 | el.run(); 136 | 137 | // TODO: problems: 138 | // 1. Need to wait 1ms before sending 139 | // 2. Removing CS every 16 140 | 141 | GASSERT(0); // Mustn't exit 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/AllMsgsDefs.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include "embxx/comms/Message.h" 24 | 25 | #include "message/HeartbeatMsg.h" 26 | #include "message/ButtonStateChangeMsg.h" 27 | #include "message/LedStateChangeMsg.h" 28 | #include "message/LedStateCtrlMsg.h" 29 | 30 | template 31 | struct AllMsgsDefs 32 | { 33 | typedef embxx::comms::Message MsgBase; 34 | 35 | typedef message::HeartbeatMsg HeartbeatMsg; 36 | typedef message::ButtonStateChangeMsg ButtonStateChangeMsg; 37 | typedef message::LedStateChangeMsg LedStateChangeMsg; 38 | typedef message::LedStateCtrlMsg LedStateCtrlMsg; 39 | 40 | typedef std::tuple< 41 | HeartbeatMsg, 42 | ButtonStateChangeMsg, 43 | LedStateChangeMsg, 44 | LedStateCtrlMsg 45 | > AllMsgs; 46 | }; 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_uart1_comms) 2 | set (name "app_uart1_comms") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/Session.cpp") 8 | 9 | set (link 10 | ${STARTUP_LIB_NAME} 11 | ${DEVICE_LIB_NAME} 12 | ${STDLIB_STUB_LIB_NAME} 13 | "gcc") 14 | 15 | add_executable(${name} ${src}) 16 | target_link_libraries (${name} ${link}) 17 | link_app (${name}) 18 | endfunction () 19 | 20 | ################################################################# 21 | 22 | bin_uart1_comms() -------------------------------------------------------------------------------- /src/app/app_uart1_comms/Session.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "Session.h" 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "embxx/util/Assert.h" 25 | 26 | namespace 27 | { 28 | 29 | const auto HeartbeatPeriod = std::chrono::seconds(2); 30 | 31 | } // namespace 32 | 33 | Session::Session(System& system) 34 | : system_(system), 35 | heartbeatTimer_(system_.timerMgr().allocTimer()), 36 | protStack_(SyncPrefixType(SyncPrefixValue)), 37 | heartbeatSeqNumValue_(0) 38 | { 39 | GASSERT(heartbeatTimer_.isValid()); 40 | scheduleHeartbeat(); 41 | 42 | auto& button = system_.button(); 43 | button.setPressedHandler( 44 | std::bind( 45 | &Session::buttonStateChanged, 46 | this, 47 | message::ButtonStateChangeMsgButtonState::Pressed)); 48 | 49 | button.setReleasedHandler( 50 | std::bind( 51 | &Session::buttonStateChanged, 52 | this, 53 | message::ButtonStateChangeMsgButtonState::Released)); 54 | 55 | system_.commsInStreamBuf().start(); 56 | startRead(); 57 | 58 | } 59 | 60 | void Session::handleMessage(const LedStateCtrlMsg& msg) 61 | { 62 | static const auto StateIdx = message::LedStateCtrlMsgFieldIdx_State; 63 | auto stateField = std::get(msg.getFields()); 64 | auto stateValue = stateField.getValue(); 65 | if (stateValue == message::LedStateChangeMsgLedState::Off) { 66 | system_.led().off(); 67 | ledStateChanged(message::LedStateChangeMsgLedState::Off); 68 | } 69 | else { 70 | system_.led().on(); 71 | ledStateChanged(message::LedStateChangeMsgLedState::On); 72 | } 73 | } 74 | 75 | void Session::handleMessage(const MsgBase& msg) 76 | { 77 | static_cast(msg); 78 | } 79 | 80 | void Session::buttonStateChanged(message::ButtonStateChangeMsgButtonState state) 81 | { 82 | auto fields = ButtonStateChangeMsg::Fields( 83 | ButtonStateChangeMsg::StateField(state)); 84 | ButtonStateChangeMsg msg(fields); 85 | sendMessage(msg); 86 | } 87 | 88 | void Session::ledStateChanged(message::LedStateChangeMsgLedState state) 89 | { 90 | auto fields = LedStateChangeMsg::Fields( 91 | LedStateChangeMsg::StateField(state)); 92 | LedStateChangeMsg msg(fields); 93 | sendMessage(msg); 94 | } 95 | 96 | void Session::scheduleHeartbeat() 97 | { 98 | GASSERT(heartbeatTimer_.isValid()); 99 | heartbeatTimer_.asyncWait( 100 | HeartbeatPeriod, 101 | [this](const embxx::error::ErrorStatus& err) 102 | { 103 | if (err) { 104 | return; 105 | } 106 | 107 | sendHeartbeat(); 108 | scheduleHeartbeat(); 109 | }); 110 | } 111 | 112 | void Session::sendHeartbeat() 113 | { 114 | auto fields = HeartbeatMsg::Fields( 115 | HeartbeatMsg::SeqNumField(heartbeatSeqNumValue_)); 116 | 117 | HeartbeatMsg msg(fields); 118 | sendMessage(msg); 119 | ++heartbeatSeqNumValue_; 120 | } 121 | 122 | void Session::sendMessage(const MsgBase& msg) 123 | { 124 | auto& buf = system_.commsOutStreamBuf(); 125 | GASSERT(buf.empty()); 126 | auto writeIter = std::back_inserter(buf); 127 | auto status = protStack_.write(msg, writeIter, buf.availableCapacity() - buf.size()); 128 | if (status == embxx::comms::ErrorStatus::UpdateRequired) { 129 | auto updateIter = buf.begin(); 130 | status = protStack_.update(updateIter, buf.size()); 131 | } 132 | 133 | if (status != embxx::comms::ErrorStatus::Success) { 134 | // Message dropped 135 | buf.clear(); 136 | return; 137 | } 138 | 139 | buf.flush(); 140 | } 141 | 142 | void Session::startRead() 143 | { 144 | scheduleRead(protStack_.length()); 145 | } 146 | 147 | void Session::scheduleRead(std::size_t length) 148 | { 149 | auto& buf = system_.commsInStreamBuf(); 150 | buf.asyncWaitDataAvailable( 151 | length, 152 | std::bind(&Session::readHandler, this, std::placeholders::_1)); 153 | } 154 | 155 | void Session::readHandler(const embxx::error::ErrorStatus& err) 156 | { 157 | if (err == embxx::error::ErrorCode::Aborted) { 158 | return; 159 | } 160 | 161 | if (err) { 162 | // Retry 163 | startRead(); 164 | return; 165 | } 166 | 167 | auto& buf = system_.commsInStreamBuf(); 168 | while (true) { 169 | if (buf.empty()) { 170 | startRead(); 171 | return; 172 | } 173 | 174 | std::size_t missingSize = 0; 175 | auto readIter = buf.begin(); 176 | MsgPtr msg; 177 | auto readStatus = protStack_.read(msg, readIter, buf.size(), &missingSize); 178 | if (readStatus == embxx::comms::ErrorStatus::NotEnoughData) { 179 | GASSERT(0 < missingSize); 180 | auto nextSize = std::min(buf.size() + missingSize, buf.fullCapacity()); 181 | scheduleRead(nextSize); 182 | return; 183 | } 184 | 185 | if (readStatus != embxx::comms::ErrorStatus::Success) { 186 | buf.consume(1U); 187 | continue; 188 | } 189 | 190 | GASSERT(msg); 191 | auto lengthToConsume = 192 | static_cast(std::distance(buf.begin(), readIter)); 193 | GASSERT(0 < lengthToConsume); 194 | buf.consume(lengthToConsume); 195 | msg->dispatch(*this); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/Session.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "embxx/comms/Message.h" 26 | #include "embxx/comms/protocol.h" 27 | #include "embxx/comms/protocol/checksum/BytesSum.h" 28 | #include "embxx/comms/MsgAllocators.h" 29 | 30 | #include "System.h" 31 | #include "AllMsgsDefs.h" 32 | 33 | struct CommsTraits { 34 | typedef embxx::comms::traits::endian::Big Endianness; 35 | typedef embxx::comms::traits::checksum::VerifyAfterProcessing ChecksumVerification; 36 | typedef System::CommsInStreamBuf::ConstIterator ReadIterator; 37 | typedef std::back_insert_iterator WriteIterator; 38 | static const std::size_t MsgIdLen = 1; 39 | static const std::size_t MsgSizeLen = 1; 40 | static const std::size_t ChecksumLen = 2; 41 | static const std::size_t ExtraSizeValue = ChecksumLen; 42 | static const std::size_t ChecksumBase = 0; 43 | static const std::size_t SyncPrefixLen = 2; 44 | }; 45 | 46 | 47 | class Session : public AllMsgsDefs 48 | { 49 | public: 50 | 51 | typedef System::TimerMgr::Timer Timer; 52 | 53 | Session(System& system); 54 | ~Session() = default; 55 | 56 | Session(const Session&) = delete; 57 | Session(Session&&) = delete; 58 | Session& operator=(const Session&) = delete; 59 | Session& operator=(Session&&) = delete; 60 | 61 | void handleMessage(const LedStateCtrlMsg& msg); 62 | void handleMessage(const MsgBase& msg); 63 | 64 | private: 65 | typedef System::CommsInStreamBuf CommsInStreamBuf; 66 | typedef System::CommsOutStreamBuf CommsOutStreamBuf; 67 | 68 | typedef embxx::comms::protocol::MsgDataLayer MsgDataLayer; 69 | typedef embxx::comms::protocol::MsgIdLayer< 70 | AllMsgs, 71 | embxx::comms::InPlaceMsgAllocator, 72 | CommsTraits, 73 | MsgDataLayer 74 | > MsgIdLayer; 75 | 76 | typedef embxx::comms::protocol::MsgSizeLayer< 77 | CommsTraits, 78 | MsgIdLayer 79 | > MsgSizeLayer; 80 | 81 | typedef embxx::comms::protocol::SyncPrefixLayer< 82 | CommsTraits, 83 | MsgSizeLayer 84 | > SyncPrefixLayer; 85 | 86 | typedef embxx::comms::protocol::ChecksumLayer< 87 | CommsTraits, 88 | embxx::comms::protocol::checksum::BytesSum, 89 | SyncPrefixLayer 90 | > ChecksumLayer; 91 | 92 | typedef ChecksumLayer ProtocolStack; 93 | // typedef SyncPrefixLayer ProtocolStack; 94 | typedef ProtocolStack::MsgPtr MsgPtr; 95 | 96 | void buttonStateChanged(message::ButtonStateChangeMsgButtonState state); 97 | void ledStateChanged(message::LedStateChangeMsgLedState state); 98 | void scheduleHeartbeat(); 99 | void sendHeartbeat(); 100 | void sendMessage(const MsgBase& msg); 101 | void startRead(); 102 | void scheduleRead(std::size_t lenth); 103 | void readHandler(const embxx::error::ErrorStatus& status); 104 | 105 | System& system_; 106 | Timer heartbeatTimer_; 107 | ProtocolStack protStack_; 108 | HeartbeatMsg::SeqNumField::ValueType heartbeatSeqNumValue_; 109 | 110 | typedef SyncPrefixLayer::SyncPrefixType SyncPrefixType; 111 | static const SyncPrefixType SyncPrefixValue = 0x4869; // "Hi" in ascii 112 | }; 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | timerDevice_(interruptMgr_), 30 | buttonDriver_(gpio_, el_), 31 | uartDriver_(uart_, el_), 32 | timerMgr_(timerDevice_, el_), 33 | led_(gpio_), 34 | button_(buttonDriver_, ButtonPin), 35 | commsInStreamBuf_(uartDriver_), 36 | commsOutStreamBuf_(uartDriver_) 37 | { 38 | uart_.configBaud(UartBaud); 39 | uart_.setReadEnabled(true); 40 | uart_.setWriteEnabled(true); 41 | } 42 | 43 | 44 | extern "C" 45 | void interruptHandler() 46 | { 47 | System::instance().interruptMgr().handleInterrupt(); 48 | } 49 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/driver/Character.h" 22 | #include "embxx/driver/Gpio.h" 23 | #include "embxx/driver/TimerMgr.h" 24 | #include "embxx/io/OutStreamBuf.h" 25 | #include "embxx/io/InStreamBuf.h" 26 | 27 | #include "device/Function.h" 28 | #include "device/Gpio.h" 29 | #include "device/InterruptMgr.h" 30 | #include "device/Timer.h" 31 | #include "device/EventLoopDevices.h" 32 | #include "device/Uart1.h" 33 | 34 | #include "component/OnBoardLed.h" 35 | #include "component/Button.h" 36 | 37 | class System 38 | { 39 | public: 40 | static const std::size_t EventLoopSpaceSize = 1024; 41 | typedef embxx::util::EventLoop< 42 | EventLoopSpaceSize, 43 | device::InterruptLock, 44 | device::WaitCond> EventLoop; 45 | 46 | // Devices 47 | typedef device::InterruptMgr<> InterruptMgr; 48 | typedef device::Gpio Gpio; 49 | typedef device::Uart1 Uart; 50 | typedef device::Timer TimerDevice; 51 | 52 | // Drivers 53 | typedef embxx::driver::Gpio ButtonDriver; 54 | typedef embxx::driver::Character UartDriver; 55 | typedef embxx::driver::TimerMgr< 56 | TimerDevice, 57 | EventLoop, 58 | 1> TimerMgr; 59 | 60 | // Components 61 | typedef component::OnBoardLed Led; 62 | typedef component::Button< 63 | ButtonDriver, 64 | false, 65 | embxx::util::StaticFunction > Button; 66 | typedef embxx::io::InStreamBuf CommsInStreamBuf; 67 | typedef embxx::io::OutStreamBuf CommsOutStreamBuf; 68 | 69 | static System& instance(); 70 | 71 | inline EventLoop& eventLoop(); 72 | inline InterruptMgr& interruptMgr(); 73 | inline Gpio& gpio(); 74 | inline Uart& uart(); 75 | inline Led& led(); 76 | inline Button& button(); 77 | inline TimerDevice& timerDevice(); 78 | inline TimerMgr& timerMgr(); 79 | inline CommsInStreamBuf& commsInStreamBuf(); 80 | inline CommsOutStreamBuf& commsOutStreamBuf(); 81 | 82 | private: 83 | System(); 84 | 85 | EventLoop el_; 86 | 87 | // Devices 88 | InterruptMgr interruptMgr_; 89 | device::Function func_; 90 | Gpio gpio_; 91 | Uart uart_; 92 | TimerDevice timerDevice_; 93 | 94 | // Drivers 95 | ButtonDriver buttonDriver_; 96 | UartDriver uartDriver_; 97 | TimerMgr timerMgr_; 98 | 99 | // Components 100 | Led led_; 101 | Button button_; 102 | CommsInStreamBuf commsInStreamBuf_; 103 | CommsOutStreamBuf commsOutStreamBuf_; 104 | 105 | static const unsigned SysClockFreq = 250000000; // 250MHz 106 | static const device::Function::PinIdxType ButtonPin = 23; 107 | static const unsigned UartBaud = 115200; 108 | }; 109 | 110 | extern "C" 111 | void interruptHandler(); 112 | 113 | // Implementation 114 | 115 | inline 116 | System::EventLoop& System::eventLoop() 117 | { 118 | return el_; 119 | } 120 | 121 | inline System::InterruptMgr& System::interruptMgr() 122 | { 123 | return interruptMgr_; 124 | } 125 | 126 | inline 127 | System::Gpio& System::gpio() 128 | { 129 | return gpio_; 130 | } 131 | 132 | inline 133 | System::Uart& System::uart() 134 | { 135 | return uart_; 136 | } 137 | 138 | inline 139 | System::Led& System::led() 140 | { 141 | return led_; 142 | } 143 | 144 | inline 145 | System::Button& System::button() 146 | { 147 | return button_; 148 | } 149 | 150 | 151 | inline 152 | System::TimerDevice& System::timerDevice() 153 | { 154 | return timerDevice_; 155 | } 156 | 157 | inline 158 | System::TimerMgr& System::timerMgr() 159 | { 160 | return timerMgr_; 161 | } 162 | 163 | inline 164 | System::CommsInStreamBuf& System::commsInStreamBuf() 165 | { 166 | return commsInStreamBuf_; 167 | } 168 | 169 | inline 170 | System::CommsOutStreamBuf& System::commsOutStreamBuf() 171 | { 172 | return commsOutStreamBuf_; 173 | } 174 | 175 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | 20 | #include "embxx/util/Assert.h" 21 | 22 | #include "System.h" 23 | #include "Session.h" 24 | 25 | namespace 26 | { 27 | 28 | class LedOnAssert : public embxx::util::Assert 29 | { 30 | public: 31 | typedef System::Led Led; 32 | LedOnAssert(Led& led) 33 | : led_(led) 34 | { 35 | } 36 | 37 | virtual void fail( 38 | const char* expr, 39 | const char* file, 40 | unsigned int line, 41 | const char* function) 42 | { 43 | static_cast(expr); 44 | static_cast(file); 45 | static_cast(line); 46 | static_cast(function); 47 | 48 | led_.on(); 49 | device::interrupt::disable(); 50 | while (true) {;} 51 | } 52 | 53 | private: 54 | Led& led_; 55 | }; 56 | 57 | } // namespace 58 | 59 | int main() { 60 | auto& system = System::instance(); 61 | auto& led = system.led(); 62 | auto& el = system.eventLoop(); 63 | 64 | // Led on on assertion failure. 65 | embxx::util::EnableAssert assertion(std::ref(led)); 66 | 67 | Session session(system); 68 | 69 | device::interrupt::enable(); 70 | 71 | el.run(); 72 | 73 | GASSERT(0); // Mustn't exit 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/ButtonStateChangeMsg.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "embxx/comms/Message.h" 25 | #include "embxx/comms/field/BasicEnumValue.h" 26 | 27 | #include "MsgId.h" 28 | 29 | namespace message 30 | { 31 | 32 | enum ButtonStateChangeMsgFieldIdx { 33 | ButtonStateChangeMsgFieldIdx_State 34 | }; 35 | 36 | enum class ButtonStateChangeMsgButtonState { 37 | Released, 38 | Pressed, 39 | NumOfStates 40 | }; 41 | 42 | 43 | template 44 | struct ButtonStateChangeMsgFields { 45 | typedef std::tuple< 46 | embxx::comms::field::BasicEnumValue 47 | > Type; 48 | }; 49 | 50 | template 51 | class ButtonStateChangeMsg : 52 | public embxx::comms::MetaMessageBase< 53 | MsgId_ButtonStateChange, 54 | TBase, 55 | ButtonStateChangeMsg, 56 | typename ButtonStateChangeMsgFields::Type 57 | > 58 | { 59 | typedef 60 | embxx::comms::MetaMessageBase< 61 | MsgId_ButtonStateChange, 62 | TBase, 63 | ButtonStateChangeMsg, 64 | typename ButtonStateChangeMsgFields::Type 65 | > Base; 66 | public: 67 | typedef typename Base::Traits Traits; 68 | typedef typename Base::Fields Fields; 69 | 70 | typedef typename std::tuple_element::type StateField; 71 | 72 | ButtonStateChangeMsg() = default; 73 | ButtonStateChangeMsg(const ButtonStateChangeMsg&) = default; 74 | ButtonStateChangeMsg(const Fields& fields); 75 | ~ButtonStateChangeMsg() = default; 76 | 77 | ButtonStateChangeMsg& operator=(const ButtonStateChangeMsg&) = default; 78 | }; 79 | 80 | // Implementation 81 | template 82 | ButtonStateChangeMsg::ButtonStateChangeMsg(const Fields& fields) 83 | : Base(fields) 84 | { 85 | } 86 | 87 | } // namespace message 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/HeartbeatMsg.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include "embxx/comms/Message.h" 25 | #include "embxx/comms/field/BasicIntValue.h" 26 | 27 | #include "MsgId.h" 28 | 29 | namespace message 30 | { 31 | 32 | enum HeartbeatMsgFieldIdx { 33 | HeartbeatMsgFieldIdx_SeqNum 34 | }; 35 | 36 | 37 | template 38 | struct HeartbeatMsgFields { 39 | typedef std::tuple< 40 | embxx::comms::field::BasicIntValue 41 | > Type; 42 | }; 43 | 44 | template 45 | class HeartbeatMsg : 46 | public embxx::comms::MetaMessageBase< 47 | MsgId_Heartbeat, 48 | TBase, 49 | HeartbeatMsg, 50 | typename HeartbeatMsgFields::Type 51 | > 52 | { 53 | typedef 54 | embxx::comms::MetaMessageBase< 55 | MsgId_Heartbeat, 56 | TBase, 57 | HeartbeatMsg, 58 | typename HeartbeatMsgFields::Type 59 | > Base; 60 | public: 61 | typedef typename Base::Traits Traits; 62 | typedef typename Base::Fields Fields; 63 | 64 | typedef typename std::tuple_element::type SeqNumField; 65 | 66 | HeartbeatMsg() = default; 67 | HeartbeatMsg(const HeartbeatMsg&) = default; 68 | HeartbeatMsg(const Fields& fields); 69 | ~HeartbeatMsg() = default; 70 | 71 | HeartbeatMsg& operator=(const HeartbeatMsg&) = default; 72 | }; 73 | 74 | // Implementation 75 | template 76 | HeartbeatMsg::HeartbeatMsg(const Fields& fields) 77 | : Base(fields) 78 | { 79 | } 80 | 81 | } // namespace message 82 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/LedState.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | namespace message 22 | { 23 | 24 | enum class LedState { 25 | Off, 26 | On, 27 | NumOfStates 28 | }; 29 | 30 | } // namespace message 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/LedStateChangeMsg.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | 22 | #include 23 | #include 24 | 25 | #include "embxx/comms/Message.h" 26 | #include "embxx/comms/field/BasicEnumValue.h" 27 | 28 | #include "MsgId.h" 29 | #include "LedState.h" 30 | 31 | namespace message 32 | { 33 | 34 | enum LedStateChangeMsgFieldIdx { 35 | LedStateChangeMsgFieldIdx_State 36 | }; 37 | 38 | typedef LedState LedStateChangeMsgLedState; 39 | 40 | 41 | template 42 | struct LedStateChangeMsgFields { 43 | typedef std::tuple< 44 | embxx::comms::field::BasicEnumValue 45 | > Type; 46 | }; 47 | 48 | template 49 | class LedStateChangeMsg : 50 | public embxx::comms::MetaMessageBase< 51 | MsgId_LedStateChange, 52 | TBase, 53 | LedStateChangeMsg, 54 | typename LedStateChangeMsgFields::Type 55 | > 56 | { 57 | typedef 58 | embxx::comms::MetaMessageBase< 59 | MsgId_LedStateChange, 60 | TBase, 61 | LedStateChangeMsg, 62 | typename LedStateChangeMsgFields::Type 63 | > Base; 64 | public: 65 | typedef typename Base::Traits Traits; 66 | typedef typename Base::Fields Fields; 67 | 68 | typedef typename std::tuple_element::type StateField; 69 | 70 | LedStateChangeMsg() = default; 71 | LedStateChangeMsg(const LedStateChangeMsg&) = default; 72 | LedStateChangeMsg(const Fields& fields); 73 | ~LedStateChangeMsg() = default; 74 | 75 | LedStateChangeMsg& operator=(const LedStateChangeMsg&) = default; 76 | }; 77 | 78 | // Implementation 79 | template 80 | LedStateChangeMsg::LedStateChangeMsg(const Fields& fields) 81 | : Base(fields) 82 | { 83 | } 84 | 85 | } // namespace message 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/LedStateCtrlMsg.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | 22 | #include 23 | #include 24 | 25 | #include "embxx/comms/Message.h" 26 | #include "embxx/comms/field/BasicEnumValue.h" 27 | 28 | #include "MsgId.h" 29 | #include "LedState.h" 30 | 31 | namespace message 32 | { 33 | 34 | enum LedStateCtrlMsgFieldIdx { 35 | LedStateCtrlMsgFieldIdx_State 36 | }; 37 | 38 | typedef LedState LedStateCtrlMsgLedState; 39 | 40 | 41 | template 42 | struct LedStateCtrlMsgFields { 43 | typedef std::tuple< 44 | embxx::comms::field::BasicEnumValue< 45 | LedStateCtrlMsgLedState, TTraits, 1, LedStateCtrlMsgLedState::NumOfStates> 46 | > Type; 47 | }; 48 | 49 | template 50 | class LedStateCtrlMsg : 51 | public embxx::comms::MetaMessageBase< 52 | MsgId_LedStateCtrl, 53 | TBase, 54 | LedStateCtrlMsg, 55 | typename LedStateCtrlMsgFields::Type 56 | > 57 | { 58 | typedef 59 | embxx::comms::MetaMessageBase< 60 | MsgId_LedStateCtrl, 61 | TBase, 62 | LedStateCtrlMsg, 63 | typename LedStateCtrlMsgFields::Type 64 | > Base; 65 | public: 66 | typedef typename Base::Traits Traits; 67 | typedef typename Base::Fields Fields; 68 | 69 | typedef typename std::tuple_element::type StateField; 70 | 71 | LedStateCtrlMsg() = default; 72 | LedStateCtrlMsg(const LedStateCtrlMsg&) = default; 73 | LedStateCtrlMsg(const Fields& fields); 74 | ~LedStateCtrlMsg() = default; 75 | 76 | LedStateCtrlMsg& operator=(const LedStateCtrlMsg&) = default; 77 | }; 78 | 79 | // Implementation 80 | template 81 | LedStateCtrlMsg::LedStateCtrlMsg(const Fields& fields) 82 | : Base(fields) 83 | { 84 | } 85 | 86 | } // namespace message 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/app/app_uart1_comms/message/MsgId.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | namespace message 22 | { 23 | 24 | enum MsgId { 25 | MsgId_Heartbeat, 26 | MsgId_ButtonStateChange, 27 | MsgId_LedStateChange, 28 | MsgId_LedStateCtrl 29 | }; 30 | 31 | } // namespace message 32 | -------------------------------------------------------------------------------- /src/app/app_uart1_echo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_uart1_echo) 2 | set (name "app_uart1_echo") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | "gcc") 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_uart1_echo() -------------------------------------------------------------------------------- /src/app/app_uart1_echo/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | uartSocket_(uart_, el_), 30 | led_(gpio_) 31 | { 32 | } 33 | 34 | extern "C" 35 | void interruptHandler() 36 | { 37 | System::instance().interruptMgr().handleInterrupt(); 38 | } 39 | -------------------------------------------------------------------------------- /src/app/app_uart1_echo/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/driver/Character.h" 22 | 23 | #include "device/Function.h" 24 | #include "device/Gpio.h" 25 | #include "device/InterruptMgr.h" 26 | #include "device/Timer.h" 27 | #include "device/EventLoopDevices.h" 28 | #include "device/Uart1.h" 29 | 30 | #include "component/OnBoardLed.h" 31 | 32 | class System 33 | { 34 | public: 35 | static const std::size_t EventLoopSpaceSize = 1024; 36 | typedef embxx::util::EventLoop< 37 | EventLoopSpaceSize, 38 | device::InterruptLock, 39 | device::WaitCond> EventLoop; 40 | 41 | typedef device::InterruptMgr<> InterruptMgr; 42 | 43 | typedef device::Gpio Gpio; 44 | 45 | typedef device::Uart1 Uart; 46 | 47 | typedef embxx::driver::Character UartSocket; 48 | 49 | typedef component::OnBoardLed Led; 50 | 51 | static System& instance(); 52 | 53 | inline EventLoop& eventLoop(); 54 | inline InterruptMgr& interruptMgr(); 55 | inline Uart& uart(); 56 | inline UartSocket& uartSocket(); 57 | inline Led& led(); 58 | 59 | private: 60 | System(); 61 | 62 | EventLoop el_; 63 | 64 | // Devices 65 | InterruptMgr interruptMgr_; 66 | device::Function func_; 67 | Gpio gpio_; 68 | Uart uart_; 69 | 70 | // Drivers 71 | UartSocket uartSocket_; 72 | 73 | // Components 74 | Led led_; 75 | 76 | static const unsigned SysClockFreq = 250000000; // 250MHz 77 | }; 78 | 79 | extern "C" 80 | void interruptHandler(); 81 | 82 | // Implementation 83 | 84 | inline 85 | System::EventLoop& System::eventLoop() 86 | { 87 | return el_; 88 | } 89 | 90 | inline System::InterruptMgr& System::interruptMgr() 91 | { 92 | return interruptMgr_; 93 | } 94 | 95 | inline 96 | System::Uart& System::uart() 97 | { 98 | return uart_; 99 | } 100 | 101 | inline 102 | System::UartSocket& System::uartSocket() 103 | { 104 | return uartSocket_; 105 | } 106 | 107 | inline 108 | System::Led& System::led() 109 | { 110 | return led_; 111 | } 112 | -------------------------------------------------------------------------------- /src/app/app_uart1_echo/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | 22 | #include "embxx/util/Assert.h" 23 | 24 | namespace 25 | { 26 | 27 | class LedOnAssert : public embxx::util::Assert 28 | { 29 | public: 30 | typedef System::Led Led; 31 | LedOnAssert(Led& led) 32 | : led_(led) 33 | { 34 | } 35 | 36 | virtual void fail( 37 | const char* expr, 38 | const char* file, 39 | unsigned int line, 40 | const char* function) 41 | { 42 | static_cast(expr); 43 | static_cast(file); 44 | static_cast(line); 45 | static_cast(function); 46 | 47 | led_.on(); 48 | device::interrupt::disable(); 49 | while (true) {;} 50 | } 51 | 52 | private: 53 | Led& led_; 54 | }; 55 | 56 | void writeChar(System::UartSocket& uartSocket, System::Uart::CharType& ch); 57 | 58 | void readChar(System::UartSocket& uartSocket, System::Uart::CharType& ch) 59 | { 60 | uartSocket.asyncRead(&ch, 1, 61 | [&uartSocket, &ch](const embxx::error::ErrorStatus& es, std::size_t bytesRead) 62 | { 63 | GASSERT(!es); 64 | GASSERT(bytesRead == 1); 65 | static_cast(es); 66 | static_cast(bytesRead); 67 | writeChar(uartSocket, ch); 68 | }); 69 | } 70 | 71 | void writeChar(System::UartSocket& uartSocket, System::Uart::CharType& ch) 72 | { 73 | uartSocket.asyncWrite(&ch, 1, 74 | [&uartSocket, &ch](const embxx::error::ErrorStatus& es, std::size_t bytesWritten) 75 | { 76 | GASSERT(!es); 77 | GASSERT(bytesWritten == 1); 78 | static_cast(es); 79 | static_cast(bytesWritten); 80 | readChar(uartSocket, ch); 81 | }); 82 | } 83 | 84 | } // namespace 85 | 86 | int main() { 87 | auto& system = System::instance(); 88 | auto& led = system.led(); 89 | 90 | // Led on on assertion failure. 91 | embxx::util::EnableAssert assertion(std::ref(led)); 92 | 93 | auto& uart = system.uart(); 94 | uart.configBaud(115200); 95 | uart.setReadEnabled(true); 96 | uart.setWriteEnabled(true); 97 | 98 | auto& uartSocket = system.uartSocket(); 99 | System::Uart::CharType ch = 0; 100 | readChar(uartSocket, ch); 101 | 102 | device::interrupt::enable(); 103 | auto& el = system.eventLoop(); 104 | el.run(); 105 | 106 | GASSERT(0); // Mustn't exit 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /src/app/app_uart1_logging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_uart1_logging) 2 | set (name "app_uart1_logging") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME} 10 | ${DEVICE_LIB_NAME} 11 | ${STDLIB_STUB_LIB_NAME} 12 | "gcc") 13 | 14 | add_executable(${name} ${src}) 15 | target_link_libraries (${name} ${link}) 16 | link_app (${name}) 17 | endfunction () 18 | 19 | ################################################################# 20 | 21 | bin_uart1_logging() 22 | -------------------------------------------------------------------------------- /src/app/app_uart1_logging/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | timerDevice_(interruptMgr_), 30 | uartDriver_(uart_, el_), 31 | timerMgr_(timerDevice_, el_), 32 | led_(gpio_), 33 | buf_(uartDriver_), 34 | stream_(buf_), 35 | log_("\r\n", stream_) 36 | { 37 | } 38 | 39 | extern "C" 40 | void interruptHandler() 41 | { 42 | System::instance().interruptMgr().handleInterrupt(); 43 | } 44 | -------------------------------------------------------------------------------- /src/app/app_uart1_logging/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/util/StreamLogger.h" 22 | #include "embxx/util/log/LevelStringPrefixer.h" 23 | #include "embxx/util/log/StreamableValueSuffixer.h" 24 | #include "embxx/util/log/StreamFlushSuffixer.h" 25 | #include "embxx/driver/Character.h" 26 | #include "embxx/driver/TimerMgr.h" 27 | #include "embxx/io/OutStreamBuf.h" 28 | #include "embxx/io/OutStream.h" 29 | 30 | #include "device/Function.h" 31 | #include "device/Gpio.h" 32 | #include "device/InterruptMgr.h" 33 | #include "device/Timer.h" 34 | #include "device/EventLoopDevices.h" 35 | #include "device/Uart1.h" 36 | 37 | #include "component/OnBoardLed.h" 38 | 39 | class System 40 | { 41 | public: 42 | static const std::size_t EventLoopSpaceSize = 1024; 43 | typedef embxx::util::EventLoop< 44 | EventLoopSpaceSize, 45 | device::InterruptLock, 46 | device::WaitCond> EventLoop; 47 | 48 | // Devices 49 | typedef device::InterruptMgr<> InterruptMgr; 50 | typedef device::Gpio Gpio; 51 | typedef device::Uart1 Uart; 52 | typedef device::Timer TimerDevice; 53 | 54 | // Drivers 55 | struct CharacterTraits 56 | { 57 | typedef std::nullptr_t ReadHandler; 58 | typedef embxx::util::StaticFunction WriteHandler; 59 | typedef std::nullptr_t ReadUntilPred; 60 | static const std::size_t ReadQueueSize = 0; 61 | static const std::size_t WriteQueueSize = 1; 62 | }; 63 | typedef embxx::driver::Character UartDriver; 64 | typedef embxx::driver::TimerMgr< 65 | TimerDevice, 66 | EventLoop, 67 | 1, 68 | embxx::util::StaticFunction 69 | > TimerMgr; 70 | 71 | // Components 72 | typedef component::OnBoardLed Led; 73 | static const std::size_t OutStreamBufSize = 1024; 74 | typedef embxx::io::OutStreamBuf OutStreamBuf; 75 | typedef embxx::io::OutStream OutStream; 76 | typedef embxx::util::log::StreamFlushSuffixer< 77 | embxx::util::log::StreamableValueSuffixer< 78 | const OutStream::CharType*, 79 | embxx::util::log::LevelStringPrefixer< 80 | embxx::util::StreamLogger< 81 | embxx::util::log::Debug, 82 | OutStream 83 | > 84 | > 85 | > 86 | > Log; 87 | 88 | static System& instance(); 89 | inline EventLoop& eventLoop(); 90 | 91 | // Devices 92 | inline InterruptMgr& interruptMgr(); 93 | inline Uart& uart(); 94 | 95 | // Drivers 96 | inline TimerMgr& timerMgr(); 97 | 98 | // Components 99 | inline Led& led(); 100 | inline Log& log(); 101 | 102 | private: 103 | System(); 104 | 105 | EventLoop el_; 106 | 107 | // Devices 108 | InterruptMgr interruptMgr_; 109 | device::Function func_; 110 | Gpio gpio_; 111 | Uart uart_; 112 | TimerDevice timerDevice_; 113 | 114 | // Drivers 115 | UartDriver uartDriver_; 116 | TimerMgr timerMgr_; 117 | 118 | // Components 119 | Led led_; 120 | OutStreamBuf buf_; 121 | OutStream stream_; 122 | Log log_; 123 | 124 | static const unsigned SysClockFreq = 250000000; // 250MHz 125 | }; 126 | 127 | extern "C" 128 | void interruptHandler(); 129 | 130 | // Implementation 131 | 132 | inline 133 | System::EventLoop& System::eventLoop() 134 | { 135 | return el_; 136 | } 137 | 138 | inline System::InterruptMgr& System::interruptMgr() 139 | { 140 | return interruptMgr_; 141 | } 142 | 143 | inline System::Uart& System::uart() 144 | { 145 | return uart_; 146 | } 147 | 148 | inline System::TimerMgr& System::timerMgr() 149 | { 150 | return timerMgr_; 151 | } 152 | 153 | inline 154 | System::Led& System::led() 155 | { 156 | return led_; 157 | } 158 | 159 | inline 160 | System::Log& System::log() 161 | { 162 | return log_; 163 | } 164 | 165 | -------------------------------------------------------------------------------- /src/app/app_uart1_logging/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | #include 21 | #include 22 | 23 | #include "embxx/util/Assert.h" 24 | 25 | namespace 26 | { 27 | 28 | class LedOnAssert : public embxx::util::Assert 29 | { 30 | public: 31 | typedef System::Led Led; 32 | LedOnAssert(Led& led) 33 | : led_(led) 34 | { 35 | } 36 | 37 | virtual void fail( 38 | const char* expr, 39 | const char* file, 40 | unsigned int line, 41 | const char* function) 42 | { 43 | static_cast(expr); 44 | static_cast(file); 45 | static_cast(line); 46 | static_cast(function); 47 | 48 | led_.on(); 49 | while (true) {;} 50 | } 51 | 52 | private: 53 | Led& led_; 54 | }; 55 | 56 | namespace log = embxx::util::log; 57 | template 58 | void performLog(TLog& log, TTimer& timer, std::size_t& counter) 59 | { 60 | ++counter; 61 | 62 | SLOG(log, log::Info, 63 | "Logging output: counter = " << 64 | embxx::io::dec << counter << 65 | " (0x" << embxx::io::hex << counter << ")"); 66 | 67 | // Perform next logging after a timeout 68 | static const auto LoggingWaitPeriod = std::chrono::seconds(1); 69 | timer.asyncWait( 70 | LoggingWaitPeriod, 71 | [&](const embxx::error::ErrorStatus& es) 72 | { 73 | GASSERT(!es); 74 | static_cast(es); 75 | performLog(log, timer, counter); 76 | }); 77 | } 78 | 79 | } // namespace 80 | 81 | int main() { 82 | auto& system = System::instance(); 83 | auto& led = system.led(); 84 | auto& log = system.log(); 85 | 86 | // Led on on assertion failure. 87 | embxx::util::EnableAssert assertion(std::ref(led)); 88 | 89 | // Configure UART 90 | auto& uart = system.uart(); 91 | uart.configBaud(115200); 92 | uart.setWriteEnabled(true); 93 | 94 | // Allocate Timer 95 | auto timer = system.timerMgr().allocTimer(); 96 | GASSERT(timer.isValid()); 97 | 98 | // Start logging 99 | std::size_t counter = 0; 100 | performLog(log, timer, counter); 101 | 102 | // Run event loop 103 | device::interrupt::enable(); 104 | auto& el = system.eventLoop(); 105 | el.run(); 106 | 107 | GASSERT(0); // Mustn't exit 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /src/app/app_uart1_morse/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_uart1_morse) 2 | set (name "app_uart1_morse") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/System.cpp" 7 | ) 8 | 9 | set (link 10 | ${STARTUP_LIB_NAME} 11 | ${DEVICE_LIB_NAME} 12 | ${STDLIB_STUB_LIB_NAME} 13 | "gcc") 14 | 15 | add_executable(${name} ${src}) 16 | target_link_libraries (${name} ${link}) 17 | link_app (${name}) 18 | endfunction () 19 | 20 | ################################################################# 21 | 22 | bin_uart1_morse() -------------------------------------------------------------------------------- /src/app/app_uart1_morse/Morse.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | 23 | #include "embxx/util/Assert.h" 24 | #include "embxx/error/ErrorStatus.h" 25 | 26 | template 27 | class Morse 28 | { 29 | public: 30 | typedef TLed Led; 31 | typedef TInBuf InBuf; 32 | typedef typename InBuf::CharType CharType; 33 | typedef TTimerMgr TimerMgr; 34 | typedef typename TimerMgr::Timer Timer; 35 | 36 | Morse(Led& led, InBuf& buf, TimerMgr& timerMgr) 37 | : led_(led), 38 | buf_(buf), 39 | timer_(timerMgr.allocTimer()) 40 | { 41 | GASSERT(timer_.isValid()); 42 | } 43 | 44 | ~Morse() = default; 45 | 46 | void start() 47 | { 48 | buf_.start(); 49 | nextLetter(); 50 | } 51 | 52 | private: 53 | typedef unsigned Duration; 54 | static const Duration Dot = 200; 55 | static const Duration Dash = Dot * 3; 56 | static const Duration End = 0; 57 | static const Duration Spacing = Dot; 58 | static const Duration InterSpacing = Spacing * 2; 59 | 60 | 61 | void nextLetter() 62 | { 63 | buf_.asyncWaitDataAvailable( 64 | 1U, 65 | [this](const embxx::error::ErrorStatus& es) 66 | { 67 | if (es) { 68 | GASSERT(buf_.empty()); 69 | nextLetter(); 70 | return; 71 | } 72 | 73 | GASSERT(!buf_.empty()); 74 | auto ch = buf_[0]; 75 | buf_.consume(1U); 76 | 77 | auto* seq = getLettersSeq(ch); 78 | if (seq == nullptr) { 79 | nextLetter(); 80 | return; 81 | } 82 | 83 | nextSyllable(seq); 84 | }); 85 | } 86 | 87 | void nextSyllable(const Duration* seq) 88 | { 89 | GASSERT(seq != nullptr); 90 | GASSERT(*seq != End); 91 | 92 | auto duration = *seq; 93 | ++seq; 94 | 95 | led_.on(); 96 | timer_.asyncWait( 97 | std::chrono::milliseconds(duration), 98 | [this, seq](const embxx::error::ErrorStatus& es) 99 | { 100 | static_cast(es); 101 | GASSERT(!es); 102 | 103 | led_.off(); 104 | 105 | if (*seq != End) { 106 | timer_.asyncWait( 107 | std::chrono::milliseconds(Duration(Spacing)), 108 | [this, seq](const embxx::error::ErrorStatus& es2) 109 | { 110 | static_cast(es2); 111 | GASSERT(!es2); 112 | nextSyllable(seq); 113 | }); 114 | return; 115 | } 116 | 117 | timer_.asyncWait( 118 | std::chrono::milliseconds(Duration(InterSpacing)), 119 | [this](const embxx::error::ErrorStatus& es3) 120 | { 121 | static_cast(es3); 122 | GASSERT(!es3); 123 | nextLetter(); 124 | }); 125 | }); 126 | } 127 | 128 | const Duration* getLettersSeq(CharType ch) const 129 | { 130 | static const Duration Seq_A[] = {Dot, Dash, End}; 131 | static const Duration Seq_B[] = {Dash, Dot, Dot, Dot, End}; 132 | static const Duration Seq_C[] = {Dash, Dot, Dash, Dot, End}; 133 | static const Duration Seq_D[] = {Dash, Dot, Dot, End}; 134 | static const Duration Seq_E[] = {Dot, End}; 135 | static const Duration Seq_F[] = {Dot, Dot, Dash, Dot, End}; 136 | static const Duration Seq_G[] = {Dash, Dash, Dot, End}; 137 | static const Duration Seq_H[] = {Dot, Dot, Dot, Dot, End}; 138 | static const Duration Seq_I[] = {Dot, Dot, End}; 139 | static const Duration Seq_J[] = {Dot, Dash, Dash, Dash, End}; 140 | static const Duration Seq_K[] = {Dash, Dot, Dash, End}; 141 | static const Duration Seq_L[] = {Dot, Dash, Dot, Dot, End}; 142 | static const Duration Seq_M[] = {Dash, Dash, End}; 143 | static const Duration Seq_N[] = {Dash, Dot, End}; 144 | static const Duration Seq_O[] = {Dash, Dash, Dash, End}; 145 | static const Duration Seq_P[] = {Dot, Dash, Dash, Dot, End}; 146 | static const Duration Seq_Q[] = {Dash, Dash, Dot, Dash, End}; 147 | static const Duration Seq_R[] = {Dot, Dash, Dot, End}; 148 | static const Duration Seq_S[] = {Dot, Dot, Dot, End}; 149 | static const Duration Seq_T[] = {Dash, End}; 150 | static const Duration Seq_U[] = {Dot, Dot, Dash, End}; 151 | static const Duration Seq_V[] = {Dot, Dot, Dot, Dash, End}; 152 | static const Duration Seq_W[] = {Dot, Dash, Dash, End}; 153 | static const Duration Seq_X[] = {Dash, Dot, Dot, Dash, End}; 154 | static const Duration Seq_Y[] = {Dash, Dot, Dash, Dash, End}; 155 | static const Duration Seq_Z[] = {Dash, Dash, Dot, Dot, End}; 156 | 157 | static const Duration Seq_0[] = {Dash, Dash, Dash, Dash, Dash, End}; 158 | static const Duration Seq_1[] = {Dot, Dash, Dash, Dash, Dash, End}; 159 | static const Duration Seq_2[] = {Dot, Dot, Dash, Dash, Dash, End}; 160 | static const Duration Seq_3[] = {Dot, Dot, Dot, Dash, Dash, End}; 161 | static const Duration Seq_4[] = {Dot, Dot, Dot, Dot, Dash, End}; 162 | static const Duration Seq_5[] = {Dot, Dot, Dot, Dot, Dot, End}; 163 | static const Duration Seq_6[] = {Dash, Dot, Dot, Dot, Dot, End}; 164 | static const Duration Seq_7[] = {Dash, Dash, Dot, Dot, Dot, End}; 165 | static const Duration Seq_8[] = {Dash, Dash, Dash, Dot, Dot, End}; 166 | static const Duration Seq_9[] = {Dash, Dash, Dash, Dash, Dot, End}; 167 | 168 | static const Duration* Letters[] = { 169 | Seq_A, 170 | Seq_B, 171 | Seq_C, 172 | Seq_D, 173 | Seq_E, 174 | Seq_F, 175 | Seq_G, 176 | Seq_H, 177 | Seq_I, 178 | Seq_J, 179 | Seq_K, 180 | Seq_L, 181 | Seq_M, 182 | Seq_N, 183 | Seq_O, 184 | Seq_P, 185 | Seq_Q, 186 | Seq_R, 187 | Seq_S, 188 | Seq_T, 189 | Seq_U, 190 | Seq_V, 191 | Seq_W, 192 | Seq_X, 193 | Seq_Y, 194 | Seq_Z 195 | }; 196 | 197 | static_assert(std::extent::value == (('Z' - 'A') + 1), 198 | "Incorrect alphabet."); 199 | 200 | static const Duration* Numbers[] = { 201 | Seq_0, 202 | Seq_1, 203 | Seq_2, 204 | Seq_3, 205 | Seq_4, 206 | Seq_5, 207 | Seq_6, 208 | Seq_7, 209 | Seq_8, 210 | Seq_9 211 | }; 212 | 213 | static_assert(std::extent::value == (('9' - '0') + 1), 214 | "Incorrect alphabet."); 215 | 216 | if ((static_cast('A') <= ch) && 217 | (ch <= static_cast('Z'))) { 218 | return Letters[ch - 'A']; 219 | } 220 | 221 | if ((static_cast('a') <= ch) && 222 | (ch <= static_cast('z'))) { 223 | return Letters[ch - 'a']; 224 | } 225 | 226 | if ((static_cast('0') <= ch) && 227 | (ch <= static_cast('9'))) { 228 | return Numbers[ch - '0']; 229 | } 230 | 231 | return nullptr; 232 | } 233 | 234 | Led& led_; 235 | InBuf& buf_; 236 | Timer timer_; 237 | }; 238 | 239 | -------------------------------------------------------------------------------- /src/app/app_uart1_morse/System.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "System.h" 19 | 20 | System& System::instance() 21 | { 22 | static System system; 23 | return system; 24 | } 25 | 26 | System::System() 27 | : gpio_(interruptMgr_, func_), 28 | uart_(interruptMgr_, func_, SysClockFreq), 29 | timerDevice_(interruptMgr_), 30 | uartDriver_(uart_, el_), 31 | timerMgr_(timerDevice_, el_), 32 | led_(gpio_), 33 | inBuf_(uartDriver_) 34 | { 35 | uart_.configBaud(UartBaud); 36 | uart_.setReadEnabled(true); 37 | } 38 | 39 | 40 | extern "C" 41 | void interruptHandler() 42 | { 43 | System::instance().interruptMgr().handleInterrupt(); 44 | } 45 | -------------------------------------------------------------------------------- /src/app/app_uart1_morse/System.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/EventLoop.h" 21 | #include "embxx/driver/Character.h" 22 | #include "embxx/driver/Generic.h" 23 | #include "embxx/driver/TimerMgr.h" 24 | #include "embxx/io/InStreamBuf.h" 25 | 26 | #include "device/Function.h" 27 | #include "device/Gpio.h" 28 | #include "device/InterruptMgr.h" 29 | #include "device/Timer.h" 30 | #include "device/EventLoopDevices.h" 31 | #include "device/Uart1.h" 32 | 33 | #include "component/OnBoardLed.h" 34 | 35 | class System 36 | { 37 | public: 38 | static const std::size_t EventLoopSpaceSize = 1024; 39 | typedef embxx::util::EventLoop< 40 | EventLoopSpaceSize, 41 | device::InterruptLock, 42 | device::WaitCond> EventLoop; 43 | 44 | // Devices 45 | typedef device::InterruptMgr<> InterruptMgr; 46 | typedef device::Gpio Gpio; 47 | typedef device::Uart1 Uart; 48 | typedef device::Timer TimerDevice; 49 | 50 | // Drivers 51 | struct OutCharacterTraits 52 | { 53 | typedef embxx::util::StaticFunction ReadHandler; 54 | typedef std::nullptr_t WriteHandler; 55 | typedef std::nullptr_t ReadUntilPred; // no read until 56 | static const std::size_t ReadQueueSize = 1; 57 | static const std::size_t WriteQueueSize = 0; // no write support 58 | }; 59 | typedef embxx::driver::Character UartDriver; 60 | typedef embxx::driver::TimerMgr< 61 | TimerDevice, 62 | EventLoop, 63 | 1> TimerMgr; 64 | 65 | // Components 66 | typedef component::OnBoardLed Led; 67 | typedef embxx::io::InStreamBuf InStreamBuf; 68 | 69 | static System& instance(); 70 | 71 | inline EventLoop& eventLoop(); 72 | inline InterruptMgr& interruptMgr(); 73 | inline Gpio& gpio(); 74 | inline Uart& uart(); 75 | inline Led& led(); 76 | inline TimerDevice& timerDevice(); 77 | inline TimerMgr& timerMgr(); 78 | inline InStreamBuf& inBuf(); 79 | 80 | private: 81 | System(); 82 | 83 | EventLoop el_; 84 | 85 | // Devices 86 | InterruptMgr interruptMgr_; 87 | device::Function func_; 88 | Gpio gpio_; 89 | Uart uart_; 90 | TimerDevice timerDevice_; 91 | 92 | // Drivers 93 | UartDriver uartDriver_; 94 | TimerMgr timerMgr_; 95 | 96 | // Components 97 | Led led_; 98 | InStreamBuf inBuf_; 99 | 100 | static const unsigned SysClockFreq = 250000000; // 250MHz 101 | static const unsigned UartBaud = 115200; 102 | }; 103 | 104 | extern "C" 105 | void interruptHandler(); 106 | 107 | // Implementation 108 | 109 | inline 110 | System::EventLoop& System::eventLoop() 111 | { 112 | return el_; 113 | } 114 | 115 | inline System::InterruptMgr& System::interruptMgr() 116 | { 117 | return interruptMgr_; 118 | } 119 | 120 | inline 121 | System::Gpio& System::gpio() 122 | { 123 | return gpio_; 124 | } 125 | 126 | inline 127 | System::Uart& System::uart() 128 | { 129 | return uart_; 130 | } 131 | 132 | inline 133 | System::Led& System::led() 134 | { 135 | return led_; 136 | } 137 | 138 | inline 139 | System::TimerDevice& System::timerDevice() 140 | { 141 | return timerDevice_; 142 | } 143 | 144 | inline 145 | System::TimerMgr& System::timerMgr() 146 | { 147 | return timerMgr_; 148 | } 149 | 150 | inline 151 | System::InStreamBuf& System::inBuf() 152 | { 153 | return inBuf_; 154 | } 155 | 156 | -------------------------------------------------------------------------------- /src/app/app_uart1_morse/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | 20 | #include "embxx/util/Assert.h" 21 | 22 | #include "System.h" 23 | #include "Morse.h" 24 | 25 | namespace 26 | { 27 | 28 | class LedOnAssert : public embxx::util::Assert 29 | { 30 | public: 31 | typedef System::Led Led; 32 | LedOnAssert(Led& led) 33 | : led_(led) 34 | { 35 | } 36 | 37 | virtual void fail( 38 | const char* expr, 39 | const char* file, 40 | unsigned int line, 41 | const char* function) 42 | { 43 | static_cast(expr); 44 | static_cast(file); 45 | static_cast(line); 46 | static_cast(function); 47 | 48 | led_.on(); 49 | device::interrupt::disable(); 50 | while (true) {;} 51 | } 52 | 53 | private: 54 | Led& led_; 55 | }; 56 | 57 | } // namespace 58 | 59 | int main() { 60 | auto& system = System::instance(); 61 | auto& led = system.led(); 62 | 63 | // Led on on assertion failure. 64 | embxx::util::EnableAssert assertion(std::ref(led)); 65 | 66 | typedef Morse MorseRunner; 67 | 68 | auto& buf = system.inBuf(); 69 | auto& timerMgr = system.timerMgr(); 70 | MorseRunner morse(led, buf, timerMgr); 71 | morse.start(); 72 | 73 | device::interrupt::enable(); 74 | auto& el = system.eventLoop(); 75 | el.run(); 76 | 77 | GASSERT(0); // Mustn't exit 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /src/asm/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | function (lib_startup) 3 | set (name "${STARTUP_LIB_NAME}") 4 | 5 | set (src 6 | "${CMAKE_CURRENT_SOURCE_DIR}/startup.s") 7 | 8 | 9 | add_library(${name} STATIC ${src}) 10 | 11 | endfunction () 12 | 13 | ################################################################# 14 | 15 | # Make sure there are not "-D or -O" options 16 | set (CMAKE_BUILD_TYPE "Debug") 17 | embxx_add_asm_flags ("-march=armv6z") 18 | enable_language (ASM) 19 | 20 | lib_startup () 21 | -------------------------------------------------------------------------------- /src/asm/startup.s: -------------------------------------------------------------------------------- 1 | ;@ 2 | ;@ Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | ;@ 4 | 5 | ;@ This file is free software: you can redistribute it and/or modify 6 | ;@ it under the terms of the GNU General Public License as published by 7 | ;@ the Free Software Foundation, either version 3 of the License, or 8 | ;@ (at your option) any later version. 9 | ;@ 10 | ;@ This program is distributed in the hope that it will be useful, 11 | ;@ but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | ;@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | ;@ GNU General Public License for more details. 14 | ;@ 15 | ;@ You should have received a copy of the GNU General Public License 16 | ;@ along with this program. If not, see . 17 | 18 | .extern __stack; 19 | .extern __bss_start__ 20 | .extern __bss_end__ 21 | .extern __init_array_start 22 | .extern __init_array_end 23 | .extern main 24 | .extern interruptHandler 25 | 26 | .section .init 27 | .globl _entry 28 | 29 | _entry: 30 | 31 | ldr pc,reset_handler_ptr ;@ Processor Reset handler 32 | ldr pc,undefined_handler_ptr ;@ Undefined instruction handler 33 | ldr pc,swi_handler_ptr ;@ Software interrupt 34 | ldr pc,prefetch_handler_ptr ;@ Prefetch/abort handler. 35 | ldr pc,data_handler_ptr ;@ Data abort handler/ 36 | ldr pc,unused_handler_ptr ;@ 37 | ldr pc,irq_handler_ptr ;@ IRQ handler 38 | ldr pc,fiq_handler_ptr ;@ Fast interrupt handler. 39 | 40 | ;@ Set the branch addresses 41 | reset_handler_ptr: .word reset 42 | undefined_handler_ptr: .word hang 43 | swi_handler_ptr: .word hang 44 | prefetch_handler_ptr: .word hang 45 | data_handler_ptr: .word hang 46 | unused_handler_ptr: .word hang 47 | irq_handler_ptr: .word irq_handler 48 | fiq_handler_ptr: .word hang 49 | 50 | reset: 51 | ;@ Disable interrupts 52 | cpsid if 53 | 54 | ;@ Copy interrupt vector to its place 55 | ldr r0,=_entry 56 | mov r1,#0x0000 57 | 58 | ;@ Here we copy the branching instructions 59 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 60 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 61 | 62 | ;@ Here we copy the branching addresses 63 | ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} 64 | stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} 65 | 66 | ;@ Set interrupt stacks 67 | ldr r0,=__stack; 68 | mov r1,#0x1000 ;@ interrupt stacks have 4K size 69 | 70 | ;@ FIQ mode 71 | cps 0x11 72 | mov sp,r0 73 | sub r0,r0,r1 74 | 75 | ;@ IRQ mode 76 | cps 0x12 77 | mov sp,r0 78 | sub r0,r0,r1 79 | 80 | ;@ Supervisor mode with disabled interrupts 81 | cpsid if,0x13 82 | mov sp,r0 83 | 84 | ;@ Zero bss section 85 | ldr r0, =__bss_start__ 86 | ldr r1, =__bss_end__ 87 | mov r2, #0 88 | 89 | bss_zero_loop: 90 | cmp r0,r1 91 | it lt 92 | strlt r2,[r0], #4 93 | blt bss_zero_loop 94 | 95 | ;@ Call constructors of all global objects 96 | ldr r0, =__init_array_start 97 | ldr r1, =__init_array_end 98 | 99 | globals_init_loop: 100 | cmp r0,r1 101 | it lt 102 | ldrlt r2, [r0], #4 103 | blxlt r2 104 | blt globals_init_loop 105 | 106 | ;@ Main function 107 | bl main 108 | b reset ;@ restart if main function returns 109 | 110 | .section .text 111 | 112 | hang: 113 | b hang 114 | 115 | irq_handler: 116 | push {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 117 | bl interruptHandler 118 | pop {r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} 119 | subs pc,lr,#4 120 | 121 | -------------------------------------------------------------------------------- /src/component/Button.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include "embxx/util/StaticFunction.h" 21 | 22 | namespace component 23 | { 24 | 25 | /// @brief Button definition class. 26 | /// @tparam TDriver Driver class 27 | /// @tparam TActiveState Boolean value stating the value of GPIO line when 28 | /// button is pressed. 29 | template > 32 | class Button 33 | { 34 | public: 35 | typedef TDriver Driver; 36 | typedef typename Driver::Device Gpio; 37 | typedef typename Gpio::PinIdType PinIdType; 38 | static const bool ActiveState = TActiveState; 39 | typedef THandler Handler; 40 | 41 | Button(Driver& driver, PinIdType pin) 42 | : driver_(driver), 43 | pin_(pin), 44 | state_(driver.device().readPin(pin)) 45 | { 46 | auto& gpio = driver_.device(); 47 | gpio.configDir(pin, Gpio::Dir_Input); 48 | gpio.configInputEdge(pin, Gpio::Edge_Rising, true); 49 | gpio.configInputEdge(pin, Gpio::Edge_Falling, true); 50 | 51 | driver.asyncReadCont( 52 | pin, 53 | [this](const embxx::error::ErrorStatus& es, bool state) 54 | { 55 | static_cast(es); 56 | GASSERT(!es); 57 | 58 | if (state_ != state) { 59 | state_ = state; 60 | invokeHandler(); 61 | } 62 | }); 63 | } 64 | 65 | ~Button() 66 | { 67 | driver_.cancelReadContNoCallback(pin_); 68 | } 69 | 70 | bool isPressed() const 71 | { 72 | if (TActiveState) { 73 | return state_; 74 | } 75 | return !state_; 76 | } 77 | 78 | template 79 | void setPressedHandler(TFunc&& func) 80 | { 81 | pressedHandler_ = std::forward(func); 82 | } 83 | 84 | template 85 | void setReleasedHandler(TFunc&& func) 86 | { 87 | releasedHandler_ = std::forward(func); 88 | } 89 | 90 | private: 91 | void invokeHandler() 92 | { 93 | bool pressed = isPressed(); 94 | if (pressed && pressedHandler_) { 95 | pressedHandler_(); 96 | } 97 | else if ((!pressed) && releasedHandler_) { 98 | releasedHandler_(); 99 | } 100 | } 101 | 102 | Driver& driver_; 103 | PinIdType pin_; 104 | bool state_; 105 | Handler pressedHandler_; 106 | Handler releasedHandler_; 107 | }; 108 | 109 | } // namespace component 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /src/component/Eeprom.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "embxx/util/StaticFunction.h" 26 | #include "embxx/util/Assert.h" 27 | #include "embxx/error/ErrorStatus.h" 28 | 29 | namespace component 30 | { 31 | 32 | template > 35 | class Eeprom 36 | { 37 | public: 38 | typedef TDriver Driver; 39 | typedef THandler Handler; 40 | 41 | typedef typename Driver::CharType CharType; 42 | typedef unsigned AttemtsCountType; 43 | typedef std::uint16_t EepromAddressType; 44 | typedef typename Driver::Device::DeviceIdType DeviceIdType; 45 | 46 | explicit Eeprom(Driver& driver); 47 | 48 | void setAttemptsLimit(AttemtsCountType limit); 49 | 50 | DeviceIdType getDeviceId() const; 51 | 52 | template 53 | void asyncRead(CharType* buf, std::size_t size, TFunc&& callback); 54 | 55 | template 56 | void asyncWrite(const CharType* buf, std::size_t size, TFunc&& callback); 57 | 58 | private: 59 | void startOp(); 60 | void opCompleteCallback(const embxx::error::ErrorStatus& err, std::size_t bytesTransferred); 61 | void invokeHandler(const embxx::error::ErrorStatus& err, std::size_t bytesTransferred); 62 | 63 | typedef embxx::util::StaticFunction DriverCallerFunc; 64 | 65 | Driver& driver_; 66 | DriverCallerFunc driverCaller_; 67 | Handler handler_; 68 | AttemtsCountType attemptsLimit_; 69 | AttemtsCountType attempt_; 70 | }; 71 | 72 | // Implementation 73 | 74 | template 75 | Eeprom::Eeprom(Driver& driver) 76 | : driver_(driver), 77 | attemptsLimit_(0), 78 | attempt_(0) 79 | { 80 | } 81 | 82 | template 83 | void Eeprom::setAttemptsLimit(AttemtsCountType limit) 84 | { 85 | attemptsLimit_ = limit; 86 | } 87 | 88 | template 89 | typename Eeprom::DeviceIdType 90 | Eeprom::getDeviceId() const 91 | { 92 | return driver_.device().id(); 93 | } 94 | 95 | template 96 | template 97 | void Eeprom::asyncRead( 98 | CharType* buf, 99 | std::size_t size, 100 | TFunc&& callback) 101 | { 102 | GASSERT(!handler_); 103 | GASSERT(!driverCaller_); 104 | handler_ = std::forward(callback); 105 | 106 | driverCaller_ = 107 | [this, buf, size]() 108 | { 109 | driver_.asyncRead( 110 | buf, 111 | size, 112 | std::bind( 113 | &Eeprom::opCompleteCallback, 114 | this, 115 | std::placeholders::_1, 116 | std::placeholders::_2)); 117 | }; 118 | 119 | startOp(); 120 | } 121 | 122 | template 123 | template 124 | void Eeprom::asyncWrite( 125 | const CharType* buf, 126 | std::size_t size, 127 | TFunc&& callback) 128 | { 129 | GASSERT(!handler_); 130 | GASSERT(!driverCaller_); 131 | handler_ = std::forward(callback); 132 | driverCaller_ = 133 | [this, buf, size]() 134 | { 135 | driver_.asyncWrite( 136 | buf, 137 | size, 138 | std::bind( 139 | &Eeprom::opCompleteCallback, 140 | this, 141 | std::placeholders::_1, 142 | std::placeholders::_2)); 143 | }; 144 | 145 | 146 | startOp(); 147 | } 148 | 149 | template 150 | void Eeprom::startOp() 151 | { 152 | GASSERT(driverCaller_); 153 | attempt_ = 0; 154 | driverCaller_(); 155 | } 156 | 157 | template 158 | void Eeprom::opCompleteCallback( 159 | const embxx::error::ErrorStatus& err, 160 | std::size_t bytesTransferred) 161 | { 162 | if (err == embxx::error::ErrorCode::HwProtocolError) { 163 | if (0 < attemptsLimit_) { 164 | ++attempt_; 165 | if (attemptsLimit_ <= attempt_) { 166 | invokeHandler(err, bytesTransferred); 167 | return; 168 | } 169 | } 170 | 171 | GASSERT(driverCaller_); 172 | driverCaller_(); 173 | return; 174 | } 175 | 176 | invokeHandler(err, bytesTransferred); 177 | } 178 | 179 | template 180 | void Eeprom::invokeHandler( 181 | const embxx::error::ErrorStatus& err, 182 | std::size_t bytesTransferred) 183 | { 184 | GASSERT(handler_); 185 | driverCaller_ = nullptr; 186 | decltype(handler_) handlerCpy(std::move(handler_)); 187 | handler_ = nullptr; 188 | GASSERT(!driverCaller_); 189 | GASSERT(!handler_); 190 | GASSERT(handlerCpy); 191 | handlerCpy(err, bytesTransferred); 192 | } 193 | 194 | 195 | } // namespace component 196 | 197 | 198 | -------------------------------------------------------------------------------- /src/component/Led.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | namespace component 21 | { 22 | 23 | /// @brief Led definition class. 24 | /// @tparam TGpio Gpio class 25 | /// @tparam TOnState Boolean value stating the value of GPIO line to set 26 | /// led on. 27 | template 28 | class Led 29 | { 30 | public: 31 | typedef TGpio Gpio; 32 | typedef typename Gpio::PinIdType PinIdType; 33 | static const bool OnState = TOnState; 34 | 35 | Led(Gpio& gpio, PinIdType pidIdx, bool isOn = false); 36 | 37 | void on(); 38 | void off(); 39 | bool isOn() const; 40 | 41 | private: 42 | Gpio& gpio_; 43 | PinIdType pin_; 44 | bool isOn_; 45 | }; 46 | 47 | // Implementation 48 | template 49 | Led::Led(Gpio& gpio, PinIdType pin, bool isOnVal) 50 | : gpio_(gpio), 51 | pin_(pin), 52 | isOn_(isOnVal) 53 | { 54 | gpio_.configDir(pin, Gpio::Dir_Output); 55 | } 56 | 57 | template 58 | void Led::on() 59 | { 60 | gpio_.writePin(pin_, OnState); 61 | isOn_ = true; 62 | } 63 | 64 | template 65 | void Led::off() 66 | { 67 | gpio_.writePin(pin_, !OnState); 68 | isOn_ = false; 69 | } 70 | 71 | template 72 | bool Led::isOn() const 73 | { 74 | return isOn_; 75 | } 76 | 77 | } // namespace component 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/component/OnBoardLed.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | 22 | #include "Led.h" 23 | 24 | namespace component 25 | { 26 | 27 | template 28 | class OnBoardLed : public Led 29 | { 30 | typedef Led Base; 31 | public: 32 | typedef typename Base::Gpio Gpio; 33 | typedef typename Base::PinIdType PinIdType; 34 | 35 | OnBoardLed(Gpio& gpio) 36 | : Base(gpio, OnBoardLedPinIdx, InitialyOn) 37 | { 38 | } 39 | 40 | private: 41 | static const PinIdType OnBoardLedPinIdx = 16; 42 | static const bool InitialyOn = false; 43 | }; 44 | 45 | } // namespace component 46 | -------------------------------------------------------------------------------- /src/device/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (lib_device) 2 | set (name "${DEVICE_LIB_NAME}") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/Function.cpp") 6 | 7 | add_library(${name} STATIC ${src}) 8 | endfunction () 9 | 10 | ################################################################# 11 | 12 | lib_device() -------------------------------------------------------------------------------- /src/device/EventLoopDevices.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | #include "embxx/util/Assert.h" 23 | #include "InterruptMgr.h" 24 | 25 | namespace device 26 | { 27 | 28 | class InterruptLock 29 | { 30 | public: 31 | InterruptLock() 32 | : flags_(0) 33 | #ifndef NDEBUG 34 | , locked_(0) 35 | #endif 36 | {} 37 | void lock() 38 | { 39 | GASSERT(!locked_); 40 | __asm volatile("mrs %0, cpsr" : "=r" (flags_)); 41 | device::interrupt::disable(); 42 | #ifndef NDEBUG 43 | locked_ = true; 44 | #endif 45 | } 46 | 47 | void unlock() 48 | { 49 | GASSERT(locked_); 50 | if ((flags_ & IntMask) == 0) { 51 | // Was previously enabled 52 | device::interrupt::enable(); 53 | } 54 | #ifndef NDEBUG 55 | locked_ = false; 56 | #endif 57 | } 58 | 59 | void lockInterruptCtx() 60 | { 61 | // Nothing to do 62 | } 63 | 64 | void unlockInterruptCtx() 65 | { 66 | // Nothing to do 67 | } 68 | private: 69 | volatile std::uint32_t flags_; 70 | #ifndef NDEBUG 71 | bool locked_; 72 | #endif 73 | static const std::uint32_t IntMask = 1U << 7; 74 | }; 75 | 76 | class WaitCond 77 | { 78 | public: 79 | template 80 | void wait(TLock& lock) 81 | { 82 | static_cast(lock); 83 | __asm volatile("wfi"); // probably has no effect 84 | } 85 | 86 | void notify() 87 | { 88 | // Nothing to do 89 | } 90 | }; 91 | 92 | } // namespace device 93 | -------------------------------------------------------------------------------- /src/device/Function.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "Function.h" 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | namespace device 26 | { 27 | 28 | namespace 29 | { 30 | 31 | typedef std::uint32_t SingleSelWord; 32 | const std::size_t NumOfBitsPerLine = 3; 33 | const std::size_t BitsPerLineMask = 34 | (static_cast(1) << NumOfBitsPerLine) - 1; 35 | const std::size_t NumOfLinesPerSelWord = (sizeof(SingleSelWord) * 8) / NumOfBitsPerLine; 36 | const std::size_t NumOfSelWords = ((Function::NumOfLines - 1) / NumOfLinesPerSelWord) + 1; 37 | 38 | struct SelWords 39 | { 40 | volatile SingleSelWord entries[NumOfSelWords]; 41 | }; 42 | 43 | volatile SelWords* const pSel = reinterpret_cast(0x20200000); 44 | 45 | static_assert(offsetof(SelWords, entries) == 0, 46 | "Select entry address is not as expected"); 47 | static_assert(offsetof(SelWords, entries[1]) == 4, 48 | "Select entry address is not as expected"); 49 | static_assert(offsetof(SelWords, entries[2]) == 8, 50 | "Select entry address is not as expected"); 51 | static_assert(offsetof(SelWords, entries[3]) == 12, 52 | "Select entry address is not as expected"); 53 | static_assert(offsetof(SelWords, entries[4]) == 16, 54 | "Select entry address is not as expected"); 55 | static_assert(offsetof(SelWords, entries[5]) == 20, 56 | "Select entry address is not as expected"); 57 | 58 | } // namespace 59 | 60 | void Function::configure(PinIdxType idx, FuncSel sel) 61 | { 62 | std::size_t selIdx = idx / NumOfLinesPerSelWord; 63 | GASSERT(selIdx < NumOfSelWords); 64 | SingleSelWord selValue = pSel->entries[selIdx]; 65 | 66 | GASSERT(static_cast(sel) < 67 | (static_cast(1) << NumOfBitsPerLine)); 68 | std::size_t selEntryIdx = idx % NumOfLinesPerSelWord; 69 | std::size_t selEntryShift = selEntryIdx * NumOfBitsPerLine; 70 | selValue &= ~(BitsPerLineMask << selEntryShift); 71 | selValue |= static_cast(sel) << selEntryShift; 72 | pSel->entries[selIdx] = selValue; 73 | } 74 | 75 | } // namespace device 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/device/Function.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include 21 | 22 | namespace device 23 | { 24 | 25 | class Function 26 | { 27 | public: 28 | enum class FuncSel { 29 | Input, // b000 30 | Output, // b001 31 | Alt5, // b010 32 | Alt4, // b011 33 | Alt0, // b100 34 | Alt1, // b101 35 | Alt2, // b110 36 | Alt3, // b111 37 | }; 38 | 39 | typedef unsigned PinIdxType; 40 | 41 | static const std::size_t NumOfLines = 54; 42 | 43 | void configure(PinIdxType idx, FuncSel sel); 44 | }; 45 | 46 | } // namespace device 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/device/InterruptMgr.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "embxx/util/Assert.h" 26 | #include "embxx/util/StaticFunction.h" 27 | 28 | namespace device 29 | { 30 | 31 | namespace interrupt 32 | { 33 | 34 | inline 35 | void enable() 36 | { 37 | __asm volatile("cpsie i"); 38 | } 39 | 40 | inline 41 | void disable() 42 | { 43 | __asm volatile("cpsid i"); 44 | } 45 | 46 | } // namespace interrupt 47 | 48 | template > 49 | class InterruptMgr 50 | { 51 | public: 52 | typedef THandler HandlerFunc; 53 | enum IrqId { 54 | IrqId_Timer, 55 | IrqId_AuxInt, 56 | IrqId_Gpio1, 57 | IrqId_Gpio2, 58 | IrqId_Gpio3, 59 | IrqId_Gpio4, 60 | IrqId_I2C, 61 | IrqId_SPI, 62 | IrqId_NumOfIds // Must be last 63 | }; 64 | 65 | InterruptMgr(); 66 | 67 | template 68 | void registerHandler(IrqId id, TFunc&& handler); 69 | 70 | void enableInterrupt(IrqId id); 71 | 72 | void disableInterrupt(IrqId id); 73 | 74 | void handleInterrupt(); 75 | 76 | private: 77 | 78 | typedef std::uint32_t EntryType; 79 | 80 | struct IrqInfo { 81 | IrqInfo(); 82 | 83 | HandlerFunc handler_; 84 | volatile EntryType* pendingPtr_; 85 | EntryType pendingMask_; 86 | volatile EntryType* enablePtr_; 87 | volatile EntryType* disablePtr_; 88 | EntryType enDisMask_; 89 | }; 90 | 91 | typedef std::array IrqsArray; 92 | 93 | IrqsArray irqs_; 94 | 95 | static constexpr volatile EntryType* IrqBasicPending = 96 | reinterpret_cast(0x2000B200); 97 | 98 | static constexpr volatile EntryType* IrqPending1 = 99 | reinterpret_cast(0x2000B204); 100 | 101 | static constexpr volatile EntryType* IrqPending2 = 102 | reinterpret_cast(0x2000B208); 103 | 104 | static constexpr volatile EntryType* IrqEnableBasic = 105 | reinterpret_cast(0x2000B218); 106 | 107 | static constexpr volatile EntryType* IrqEnable1 = 108 | reinterpret_cast(0x2000B210); 109 | 110 | static constexpr volatile EntryType* IrqEnable2 = 111 | reinterpret_cast(0x2000B214); 112 | 113 | static constexpr volatile EntryType* IrqDisableBasic = 114 | reinterpret_cast(0x2000B224); 115 | 116 | static constexpr volatile EntryType* IrqDisable1 = 117 | reinterpret_cast(0x2000B21C); 118 | 119 | static constexpr volatile EntryType* IrqDisable2 = 120 | reinterpret_cast(0x2000B220); 121 | 122 | static const EntryType MaskPending1 = 0x00000100; 123 | static const EntryType MaskPending2 = 0x00000200; 124 | 125 | }; 126 | 127 | // Implementation 128 | 129 | template 130 | InterruptMgr::InterruptMgr() 131 | { 132 | { 133 | auto& timerIrq = irqs_[IrqId_Timer]; 134 | timerIrq.pendingPtr_ = IrqBasicPending; 135 | timerIrq.pendingMask_ = static_cast(1) << 0; 136 | timerIrq.enablePtr_ = IrqEnableBasic; 137 | timerIrq.disablePtr_ = IrqDisableBasic; 138 | timerIrq.enDisMask_ = timerIrq.pendingMask_; 139 | static_cast(timerIrq); 140 | } 141 | 142 | { 143 | auto& auxIrq = irqs_[IrqId_AuxInt]; 144 | auxIrq.pendingPtr_ = IrqPending1; 145 | auxIrq.pendingMask_ = static_cast(1) << 29; 146 | auxIrq.enablePtr_ = IrqEnable1; 147 | auxIrq.disablePtr_ = IrqDisable1; 148 | auxIrq.enDisMask_ = auxIrq.pendingMask_; 149 | static_cast(auxIrq); 150 | } 151 | 152 | for (int i = 0; i <= (IrqId_Gpio4 - IrqId_Gpio1); ++i) { 153 | auto& gpioIrq = irqs_[IrqId_Gpio1 + i]; 154 | gpioIrq.pendingPtr_ = IrqPending2; 155 | gpioIrq.pendingMask_ = static_cast(1) << ((49 - 32) + i); 156 | gpioIrq.enablePtr_ = IrqEnable2; 157 | gpioIrq.disablePtr_ = IrqDisable2; 158 | gpioIrq.enDisMask_ = gpioIrq.pendingMask_; 159 | static_cast(gpioIrq); 160 | } 161 | 162 | { 163 | auto& i2cIrq = irqs_[IrqId_I2C]; 164 | i2cIrq.pendingPtr_ = IrqBasicPending; 165 | i2cIrq.pendingMask_ = static_cast(1) << 15; 166 | i2cIrq.enablePtr_ = IrqEnable2; 167 | i2cIrq.disablePtr_ = IrqDisable2; 168 | i2cIrq.enDisMask_ = static_cast(1) << (53 - 32); 169 | static_cast(i2cIrq); 170 | } 171 | 172 | { 173 | auto& spiIrq = irqs_[IrqId_SPI]; 174 | spiIrq.pendingPtr_ = IrqBasicPending; 175 | spiIrq.pendingMask_ = static_cast(1) << 16; 176 | spiIrq.enablePtr_ = IrqEnable2; 177 | spiIrq.disablePtr_ = IrqDisable2; 178 | spiIrq.enDisMask_ = static_cast(1) << (54 - 32); 179 | static_cast(spiIrq); 180 | } 181 | } 182 | 183 | template 184 | template 185 | void InterruptMgr::registerHandler( 186 | IrqId id, 187 | TFunc&& handler) 188 | { 189 | GASSERT(id < IrqId_NumOfIds); 190 | irqs_[id].handler_ = std::forward(handler); 191 | } 192 | 193 | template 194 | void InterruptMgr::enableInterrupt(IrqId id) 195 | { 196 | GASSERT(id < IrqId_NumOfIds); 197 | auto& info = irqs_[id]; 198 | *info.enablePtr_ = info.enDisMask_; 199 | } 200 | 201 | template 202 | void InterruptMgr::disableInterrupt(IrqId id) 203 | { 204 | GASSERT(id < IrqId_NumOfIds); 205 | auto& info = irqs_[id]; 206 | *info.disablePtr_ = info.enDisMask_; 207 | } 208 | 209 | template 210 | void InterruptMgr::handleInterrupt() 211 | { 212 | auto irqsBasic = *IrqBasicPending; 213 | auto irqsPending1 = *IrqPending1; 214 | auto irqsPending2 = *IrqPending2; 215 | 216 | std::for_each(irqs_.begin(), irqs_.end(), 217 | [this, irqsBasic, irqsPending1, irqsPending2](IrqInfo& info) 218 | { 219 | bool invoke = false; 220 | do { 221 | if (info.pendingPtr_ == IrqBasicPending) { 222 | if ((info.pendingMask_ & irqsBasic) != 0) { 223 | invoke = true; 224 | } 225 | break; 226 | } 227 | 228 | if (info.pendingPtr_ == IrqPending1) { 229 | if (((irqsBasic & MaskPending1) != 0) && 230 | ((info.pendingMask_ & irqsPending1) != 0)) { 231 | invoke = true; 232 | } 233 | break; 234 | } 235 | 236 | if (info.pendingPtr_ == IrqPending2) { 237 | if (((irqsBasic & MaskPending2) != 0) && 238 | ((info.pendingMask_ & irqsPending2) != 0)) { 239 | invoke = true; 240 | } 241 | break; 242 | } 243 | } while (false); 244 | 245 | if (invoke) { 246 | if (info.handler_) { 247 | info.handler_(); 248 | } 249 | } 250 | }); 251 | } 252 | 253 | template 254 | InterruptMgr::IrqInfo::IrqInfo() 255 | : pendingPtr_(0), 256 | pendingMask_(0), 257 | enablePtr_(0), 258 | disablePtr_(0), 259 | enDisMask_(0) 260 | { 261 | } 262 | 263 | } // namespace device 264 | 265 | 266 | -------------------------------------------------------------------------------- /src/raspberrypi.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | RESERVED (r) : ORIGIN = 0x00000000, LENGTH = 32K 4 | RAM (rwx) : ORIGIN = 0x00008000, LENGTH = 64M 5 | } 6 | 7 | ENTRY(_entry) 8 | 9 | SECTIONS { 10 | .start : { 11 | KEEP(*(.init)) 12 | KEEP(*(.fini)) 13 | } > RAM = 0 14 | 15 | /** 16 | * This is the main code section. 17 | * 18 | **/ 19 | .text : { 20 | *(.text) 21 | } > RAM 22 | 23 | .data : { 24 | *(.data) 25 | } > RAM 26 | 27 | .bss : 28 | { 29 | __bss_start__ = .; 30 | *(.bss) 31 | *(.bss.*) 32 | __bss_end__ = .; 33 | } > RAM 34 | 35 | .init.array : 36 | { 37 | __init_array_start = .; 38 | *(.init_array) 39 | *(.init_array.*) 40 | __init_array_end = .; 41 | } > RAM 42 | 43 | /* .ARM.exidx is required for exception handling. It is required only 44 | for "test_cpp" applications that link in stdlib */ 45 | .ARM.exidx : 46 | { 47 | __exidx_start = .; 48 | *(.ARM.exidx* .gnu.linkonce.armexidx.*) 49 | __exidx_end = .; 50 | } >RAM 51 | 52 | /** 53 | * Currently no heap 54 | **/ 55 | 56 | /** 57 | * Stack starts at the top of the RAM, and moves down! 58 | **/ 59 | __stack = ORIGIN(RAM) + LENGTH(RAM); 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/stdlib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (lib_stdlib_stub) 2 | set (name "${STDLIB_STUB_LIB_NAME}") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/stdlib_stub.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/placeholders.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/string.cpp") 8 | 9 | add_library(${name} STATIC ${src}) 10 | endfunction () 11 | 12 | ################################################################# 13 | 14 | lib_stdlib_stub() -------------------------------------------------------------------------------- /src/stdlib/placeholders.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | 20 | 21 | namespace std 22 | { 23 | 24 | namespace placeholders 25 | { 26 | 27 | decltype(std::placeholders::_1) _1; 28 | decltype(std::placeholders::_2) _2; 29 | decltype(std::placeholders::_3) _3; 30 | decltype(std::placeholders::_4) _4; 31 | 32 | } // namespace placeholders 33 | 34 | } // namespace std 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/stdlib/stdlib_stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2013 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | // Virtual destructors require also operator delete, in case they are 20 | // invoked using delete operator. 21 | void operator delete(void*) 22 | { 23 | while (true) {} 24 | } 25 | 26 | // Compiler requires this function when there are pure virtual functions 27 | extern "C" void __cxa_pure_virtual() 28 | { 29 | while (true) {} 30 | } 31 | 32 | // Compiler requires this function when there are static objects that 33 | // require custom destructors 34 | extern "C" int __aeabi_atexit( 35 | void *object, 36 | void (*destructor)(void *), 37 | void *dso_handle) 38 | { 39 | static_cast(object); 40 | static_cast(destructor); 41 | static_cast(dso_handle); 42 | return 0; 43 | } 44 | 45 | // Compiler requires this symbol when there are static objects that 46 | // require custom destructors 47 | void* __dso_handle = nullptr; 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/stdlib/string.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | 20 | extern "C" 21 | int memcmp( const void* lhs, const void* rhs, size_t count ) 22 | { 23 | auto lhsPtr = reinterpret_cast(lhs); 24 | auto rhsPtr = reinterpret_cast(rhs); 25 | int diffSum = 0; 26 | while (0 < count) { 27 | diffSum += static_cast(*lhsPtr) - static_cast(*rhsPtr); 28 | if (diffSum != 0) { 29 | break; 30 | } 31 | --count; 32 | ++lhsPtr; 33 | ++rhsPtr; 34 | } 35 | return diffSum; 36 | } 37 | 38 | extern "C" 39 | void* memset(void* dest, int ch, size_t count) 40 | { 41 | auto destPtr = reinterpret_cast(dest); 42 | auto castedCh = static_cast(ch); 43 | while (0 < count) { 44 | *destPtr = castedCh; 45 | ++destPtr; 46 | --count; 47 | } 48 | 49 | return dest; 50 | } 51 | -------------------------------------------------------------------------------- /src/test_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory (test_cpp_simple) 2 | add_subdirectory (test_cpp_vector) 3 | add_subdirectory (test_cpp_exceptions) 4 | add_subdirectory (test_cpp_rtti) 5 | add_subdirectory (test_cpp_statics) 6 | add_subdirectory (test_cpp_abstract_class) 7 | add_subdirectory (test_cpp_templates) 8 | add_subdirectory (test_cpp_tag_dispatch) 9 | -------------------------------------------------------------------------------- /src/test_cpp/README: -------------------------------------------------------------------------------- 1 | This directory contains test applications that are used to inspect output of 2 | the compiler. They should not be used on an actual platform. The applications 3 | are: 4 | 5 | 01_test_simple 6 | ----------------- 7 | Simple application with infinite loop in main. It's purpose is to see what 8 | stubs may be required to get the application successfully compiled, and after 9 | the successful compilation to inspect the compiler output. 10 | 11 | 02_test_vector 12 | ----------------- 13 | Application that pushes some values into std::vector. The purpose of this 14 | application is to see what stub functions may be required when dynamic memory 15 | allocation and/or C++ exceptions are used as well as inspect the differences 16 | between C and C++ heaps. 17 | 18 | 03_test_statics 19 | ----------------- 20 | This application defines two static objects, one in the global space and other 21 | inside the accessor function. It should be used to inspect the initialisation 22 | process of these static objects. 23 | 24 | 04_test_abstract_class 25 | ----------------- 26 | The purpose of this application is to analyse what code is generated and get to 27 | know what stub functions are required in case there is abstract class with 28 | virtual functions (including virtual destructors). 29 | 30 | 05_test_templates 31 | ----------------- 32 | The purpose of this application is to verify the possible code bloating when 33 | templates are used. 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/AbstractBase.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "AbstractBase.h" 19 | 20 | AbstractBase::~AbstractBase() 21 | { 22 | } 23 | 24 | void AbstractBase::nonOverridenFunc() 25 | { 26 | } 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/AbstractBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | class AbstractBase 22 | { 23 | public: 24 | virtual ~AbstractBase(); 25 | virtual void func() = 0; 26 | virtual void nonOverridenFunc() final; 27 | }; 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_abstract_class) 2 | set (name "test_cpp_abstract_class") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/AbstractBase.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/Derived.cpp" 8 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp") 9 | 10 | set (link 11 | ${STARTUP_LIB_NAME}) 12 | 13 | add_executable(${name} ${src}) 14 | target_link_libraries (${name} ${link}) 15 | link_app (${name}) 16 | endfunction () 17 | 18 | ################################################################# 19 | 20 | embxx_disable_exceptions () 21 | embxx_disable_rtti () 22 | embxx_disable_stdlib () 23 | 24 | bin_test_abstract_class() 25 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/Derived.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #include "Derived.h" 20 | 21 | Derived::~Derived() 22 | { 23 | } 24 | 25 | void Derived::func() 26 | { 27 | } 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/Derived.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include "AbstractBase.h" 22 | 23 | class Derived : public AbstractBase 24 | { 25 | public: 26 | virtual ~Derived(); 27 | virtual void func() override; 28 | }; 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "AbstractBase.h" 19 | #include "Derived.h" 20 | 21 | // This function is required by common startup code 22 | extern "C" 23 | void interruptHandler() 24 | { 25 | } 26 | 27 | int main(int argc, const char** argv) 28 | { 29 | static_cast(argc); 30 | static_cast(argv); 31 | 32 | { 33 | Derived obj; 34 | AbstractBase* basePtr = &obj; 35 | basePtr->func(); 36 | 37 | // Uncomment the following lines to generate destructor invocation code 38 | // basePtr->~AbstractBase(); 39 | // delete basePtr; 40 | } 41 | 42 | while (true) {}; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_abstract_class/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | // Required by one of variants of virtual destructor 19 | void operator delete(void *) 20 | { 21 | } 22 | 23 | // Required when there is pure virtual function 24 | extern "C" void __cxa_pure_virtual() 25 | { 26 | while (true) {} 27 | } 28 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_exceptions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_exceptions) 2 | set (name "test_cpp_exceptions") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME}) 10 | 11 | add_executable(${name} ${src}) 12 | target_link_libraries (${name} ${link}) 13 | link_app (${name}) 14 | endfunction () 15 | 16 | ################################################################# 17 | 18 | embxx_disable_exceptions () 19 | #embxx_disable_stdlib() 20 | 21 | bin_test_exceptions() 22 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_exceptions/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | #include 20 | 21 | // This function is required by common startup code 22 | extern "C" 23 | void interruptHandler() 24 | { 25 | } 26 | 27 | int main(int argc, const char** argv) 28 | { 29 | static_cast(argc); 30 | static_cast(argv); 31 | 32 | std::vector v; 33 | v.at(100) = 0; 34 | 35 | while (true) {}; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_exceptions/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #include 20 | 21 | // This stub function is required by _mainCRTSturtup 22 | extern "C" void exit(int status) 23 | { 24 | static_cast(status); 25 | while (true) {} 26 | } 27 | 28 | // This stub function is required by stdlib 29 | extern "C" void _exit() 30 | { 31 | exit(-1); 32 | } 33 | 34 | // This heap allocation stub is required by stdlib 35 | extern "C" unsigned _sbrk(int inc) 36 | { 37 | static_cast(inc); 38 | return 0; // The application is not intended to be executed, no need for actual heap. 39 | } 40 | 41 | // This stub function is required by stdlib 42 | extern "C" int _kill(int pid, int sig) 43 | { 44 | static_cast(pid); 45 | static_cast(sig); 46 | return -1; 47 | } 48 | 49 | // This stub function is required by stdlib 50 | extern "C" int _getpid(void) { 51 | return 1; 52 | } 53 | 54 | // This stub function is required by stdlib 55 | extern "C" int _write(int file, char *ptr, int len) 56 | { 57 | static_cast(file); 58 | static_cast(ptr); 59 | return len; 60 | } 61 | 62 | // This stub function is required by stdlib 63 | extern "C" int _read(int file, char *ptr, int len) 64 | { 65 | static_cast(file); 66 | static_cast(ptr); 67 | static_cast(len); 68 | return 0; 69 | } 70 | 71 | // This stub function is required by stdlib 72 | extern "C" int _close(int file) 73 | { 74 | static_cast(file); 75 | return -1; 76 | } 77 | 78 | // This stub function is required by stdlib 79 | extern "C" int _open(const char *name, int flags, int mode) 80 | { 81 | static_cast(name); 82 | static_cast(flags); 83 | static_cast(mode); 84 | return -1; 85 | } 86 | 87 | // This stub function is required by stdlib 88 | extern "C" int _fstat(int file, struct stat *st) 89 | { 90 | static_cast(file); 91 | static_cast(st); 92 | return -1; 93 | } 94 | 95 | // This stub function is required by stdlib 96 | extern "C" int _isatty(int file) 97 | { 98 | static_cast(file); 99 | return 1; 100 | } 101 | 102 | // This stub function is required by stdlib 103 | extern "C" int _lseek(int file, int ptr, int dir) 104 | { 105 | static_cast(file); 106 | static_cast(ptr); 107 | static_cast(dir); 108 | return 0; 109 | } 110 | 111 | //namespace std 112 | //{ 113 | // 114 | //void __throw_out_of_range(char const*) 115 | //{ 116 | // while (true) {} 117 | //} 118 | // 119 | //} 120 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_rtti/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_rtti) 2 | set (name "test_cpp_rtti") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/SomeClass.cpp") 8 | 9 | set (link 10 | ${STARTUP_LIB_NAME}) 11 | 12 | add_executable(${name} ${src}) 13 | target_link_libraries (${name} ${link}) 14 | link_app (${name}) 15 | endfunction () 16 | 17 | ################################################################# 18 | 19 | embxx_disable_exceptions () 20 | #embxx_disable_rtti () 21 | 22 | bin_test_rtti() 23 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_rtti/SomeClass.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "SomeClass.h" 19 | 20 | void SomeClass::someFunc() 21 | { 22 | } 23 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_rtti/SomeClass.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | struct SomeClass 22 | { 23 | virtual void someFunc(); 24 | }; 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_rtti/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | #include "SomeClass.h" 20 | 21 | // This function is required by common startup code 22 | extern "C" 23 | void interruptHandler() 24 | { 25 | } 26 | 27 | int main(int argc, const char** argv) 28 | { 29 | static_cast(argc); 30 | static_cast(argv); 31 | 32 | SomeClass someClass; 33 | someClass.someFunc(); 34 | 35 | while (true) {}; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_rtti/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #include 20 | 21 | // This stub function is required by _mainCRTSturtup 22 | extern "C" void exit(int status) 23 | { 24 | static_cast(status); 25 | while (true) {} 26 | } 27 | 28 | // This stub function is required by stdlib 29 | extern "C" void _exit() 30 | { 31 | exit(-1); 32 | } 33 | 34 | // This heap allocation stub is required by stdlib 35 | extern "C" unsigned _sbrk(int inc) 36 | { 37 | static_cast(inc); 38 | return 0; // The application is not intended to be executed, no need for actual heap. 39 | } 40 | 41 | // This stub function is required by stdlib 42 | extern "C" int _kill(int pid, int sig) 43 | { 44 | static_cast(pid); 45 | static_cast(sig); 46 | return -1; 47 | } 48 | 49 | // This stub function is required by stdlib 50 | extern "C" int _getpid(void) { 51 | return 1; 52 | } 53 | 54 | // This stub function is required by stdlib 55 | extern "C" int _write(int file, char *ptr, int len) 56 | { 57 | static_cast(file); 58 | static_cast(ptr); 59 | return len; 60 | } 61 | 62 | // This stub function is required by stdlib 63 | extern "C" int _read(int file, char *ptr, int len) 64 | { 65 | static_cast(file); 66 | static_cast(ptr); 67 | static_cast(len); 68 | return 0; 69 | } 70 | 71 | // This stub function is required by stdlib 72 | extern "C" int _close(int file) 73 | { 74 | static_cast(file); 75 | return -1; 76 | } 77 | 78 | // This stub function is required by stdlib 79 | extern "C" int _fstat(int file, struct stat *st) 80 | { 81 | static_cast(file); 82 | static_cast(st); 83 | return -1; 84 | } 85 | 86 | // This stub function is required by stdlib 87 | extern "C" int _isatty(int file) 88 | { 89 | static_cast(file); 90 | return 1; 91 | } 92 | 93 | // This stub function is required by stdlib 94 | extern "C" int _lseek(int file, int ptr, int dir) 95 | { 96 | static_cast(file); 97 | static_cast(ptr); 98 | static_cast(dir); 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_simple/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_simple) 2 | set (name "test_cpp_simple") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME}) 10 | 11 | add_executable(${name} ${src}) 12 | target_link_libraries (${name} ${link}) 13 | link_app (${name}) 14 | endfunction () 15 | 16 | ################################################################# 17 | 18 | bin_test_simple() 19 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_simple/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | // This function is required by common startup code 20 | extern "C" 21 | void interruptHandler() 22 | { 23 | } 24 | 25 | int main(int argc, const char** argv) 26 | { 27 | static_cast(argc); 28 | static_cast(argv); 29 | 30 | while (true) {}; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_simple/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | // This function may be required by _mainCRTSturtup when using a particular compiler 20 | extern "C" 21 | void exit() 22 | { 23 | while (true) {} 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_statics) 2 | set (name "test_cpp_statics") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/SomeObj.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/SomeObj2.cpp" 8 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp") 9 | 10 | set (link 11 | ${STARTUP_LIB_NAME}) 12 | 13 | add_executable(${name} ${src}) 14 | target_link_libraries (${name} ${link}) 15 | link_app (${name}) 16 | endfunction () 17 | 18 | ################################################################# 19 | 20 | embxx_disable_exceptions () 21 | embxx_disable_rtti () 22 | embxx_disable_stdlib () 23 | embxx_add_c_cxx_flags ("-fno-threadsafe-statics") 24 | 25 | bin_test_statics() 26 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/SomeObj.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "SomeObj.h" 19 | 20 | SomeObj SomeObj::globalObj(1, 2); 21 | 22 | SomeObj& SomeObj::instanceGlobal() 23 | { 24 | return globalObj; 25 | } 26 | 27 | SomeObj& SomeObj::instanceLocal() 28 | { 29 | static SomeObj localObj(3, 4); 30 | return localObj; 31 | } 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/SomeObj.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | class SomeObj 19 | { 20 | public: 21 | 22 | // ~SomeObj(); 23 | 24 | static SomeObj& instanceGlobal(); 25 | 26 | static SomeObj& instanceLocal(); 27 | 28 | private: 29 | SomeObj(int v1, int v2); 30 | int m_v1; 31 | int m_v2; 32 | 33 | static SomeObj globalObj; 34 | }; 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/SomeObj2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #include "SomeObj.h" 20 | 21 | SomeObj::SomeObj(int v1, int v2) : m_v1(v1), m_v2(v2) {} 22 | 23 | //SomeObj::~SomeObj() {} 24 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "SomeObj.h" 19 | 20 | // This function is required by common startup code 21 | extern "C" 22 | void interruptHandler() 23 | { 24 | } 25 | 26 | int main(int argc, const char** argv) 27 | { 28 | static_cast(argc); 29 | static_cast(argv); 30 | 31 | auto& glob = SomeObj::instanceGlobal(); 32 | auto& local = SomeObj::instanceLocal(); 33 | static_cast(glob); 34 | static_cast(local); 35 | 36 | while (true) {}; 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_statics/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | // This function is required to register the call for the destructor 20 | // of static object 21 | extern "C" int __aeabi_atexit( 22 | void *object, 23 | void (*destructor)(void *), 24 | void *dso_handle) 25 | { 26 | static_cast(object); 27 | static_cast(destructor); 28 | static_cast(dso_handle); 29 | return 0; 30 | } 31 | 32 | // The pointer to this variable will be passed to __aeabi_atexit 33 | void* __dso_handle = nullptr; 34 | 35 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_tag_dispatch/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_tag_dispatch) 2 | set (name "test_cpp_tag_dispatch") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/tag.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME}) 10 | 11 | add_executable(${name} ${src}) 12 | target_link_libraries (${name} ${link}) 13 | link_app (${name}) 14 | endfunction () 15 | 16 | ################################################################# 17 | 18 | embxx_disable_exceptions () 19 | embxx_disable_rtti () 20 | embxx_disable_stdlib () 21 | 22 | bin_test_tag_dispatch() 23 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_tag_dispatch/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "tag.h" 19 | 20 | // This function is required by common startup code 21 | extern "C" 22 | void interruptHandler() 23 | { 24 | } 25 | 26 | int main(int argc, const char** argv) 27 | { 28 | static_cast(argc); 29 | static_cast(argv); 30 | 31 | Dispatcher::func(); 32 | Dispatcher::func(); 33 | Dispatcher::otherFunc(); 34 | Dispatcher::otherFunc(); 35 | 36 | while (true) {}; 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_tag_dispatch/tag.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "tag.h" 19 | 20 | void Dispatcher::funcInternal(Tag1) 21 | { 22 | } 23 | 24 | void Dispatcher::funcInternal(Tag2) 25 | { 26 | } 27 | 28 | void Dispatcher::otherFuncTag1() 29 | { 30 | } 31 | 32 | void Dispatcher::otherFuncTag2() 33 | { 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_tag_dispatch/tag.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | struct Tag1 {}; 22 | struct Tag2 {}; 23 | 24 | class Dispatcher 25 | { 26 | public: 27 | 28 | template 29 | static void func() 30 | { 31 | funcInternal(TTag()); 32 | } 33 | 34 | template 35 | static void otherFunc() 36 | { 37 | otherFuncInternal(TTag()); 38 | } 39 | 40 | private: 41 | static void funcInternal(Tag1 tag); 42 | static void funcInternal(Tag2 tag); 43 | 44 | static void otherFuncInternal(Tag1 tag) 45 | { 46 | static_cast(tag); 47 | otherFuncTag1(); 48 | } 49 | 50 | static void otherFuncInternal(Tag2 tag) 51 | { 52 | static_cast(tag); 53 | otherFuncTag2(); 54 | } 55 | 56 | 57 | static void otherFuncTag1(); 58 | static void otherFuncTag2(); 59 | }; 60 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_templates/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_templates) 2 | set (name "test_cpp_templates") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/other.cpp") 7 | 8 | set (link 9 | ${STARTUP_LIB_NAME}) 10 | 11 | add_executable(${name} ${src}) 12 | target_link_libraries (${name} ${link}) 13 | link_app (${name}) 14 | endfunction () 15 | 16 | ################################################################# 17 | 18 | embxx_disable_exceptions () 19 | embxx_disable_rtti () 20 | embxx_disable_stdlib () 21 | 22 | bin_test_templates() 23 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_templates/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "template.h" 19 | 20 | // This function is required by common startup code 21 | extern "C" 22 | void interruptHandler() 23 | { 24 | } 25 | 26 | int main(int argc, const char** argv) 27 | { 28 | static_cast(argc); 29 | static_cast(argv); 30 | 31 | int start1 = 100; 32 | unsigned start2 = 200; 33 | 34 | func(start1); 35 | func(start2); 36 | 37 | SomeTemplateClass::func(500); 38 | SomeTemplateClass::func(500); 39 | 40 | while (true) {}; 41 | return 0; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_templates/other.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include "template.h" 19 | 20 | void other() 21 | { 22 | int start1 = 300; 23 | unsigned start2 = 500; 24 | 25 | func(start1); 26 | func(start2); 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_templates/template.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | template 24 | void func(T startValue) 25 | { 26 | for (volatile T i = startValue; i < startValue * 2; i += 1) {} 27 | for (volatile T i = startValue; i < startValue * 2; i += 2) {} 28 | for (volatile T i = startValue; i < startValue * 2; i += 3) {} 29 | for (volatile T i = startValue; i < startValue * 2; i += 4) {} 30 | for (volatile T i = startValue; i < startValue * 2; i += 5) {} 31 | for (volatile T i = startValue; i < startValue * 2; i += 6) {} 32 | } 33 | 34 | template 35 | struct SomeTemplateClass 36 | { 37 | static void func(T startValue) 38 | { 39 | for (volatile T i = startValue; i < startValue * 2; i += 1) {} 40 | for (volatile T i = startValue; i < startValue * 2; i += 2) {} 41 | for (volatile T i = startValue; i < startValue * 2; i += 3) {} 42 | for (volatile T i = startValue; i < startValue * 2; i += 4) {} 43 | for (volatile T i = startValue; i < startValue * 2; i += 5) {} 44 | for (volatile T i = startValue; i < startValue * 2; i += 6) {} 45 | } 46 | }; 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_vector/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function (bin_test_vector) 2 | set (name "test_cpp_vector") 3 | 4 | set (src 5 | "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" 6 | "${CMAKE_CURRENT_SOURCE_DIR}/stub.cpp" 7 | "${CMAKE_CURRENT_SOURCE_DIR}/heap.cpp") 8 | 9 | set (link 10 | ${STARTUP_LIB_NAME}) 11 | 12 | add_executable(${name} ${src}) 13 | target_link_libraries (${name} ${link}) 14 | link_app (${name}) 15 | endfunction () 16 | 17 | ################################################################# 18 | 19 | embxx_disable_exceptions () 20 | embxx_disable_rtti () 21 | 22 | bin_test_vector() 23 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_vector/heap.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | #include 20 | 21 | // Uncomment the overloading below to replace C++ heap with C one. 22 | 23 | //void* operator new(size_t size) noexcept 24 | //{ 25 | // return malloc(size); 26 | //} 27 | // 28 | //void operator delete(void *p) noexcept 29 | //{ 30 | // free(p); 31 | //} 32 | // 33 | //void* operator new[](size_t size) noexcept 34 | //{ 35 | // return operator new(size); 36 | //} 37 | // 38 | //void operator delete[](void *p) noexcept 39 | //{ 40 | // operator delete(p); 41 | //} 42 | // 43 | //void* operator new(size_t size, std::nothrow_t) noexcept 44 | //{ 45 | // return operator new(size); 46 | //} 47 | // 48 | //void operator delete(void *p, std::nothrow_t) noexcept 49 | //{ 50 | // operator delete(p); 51 | //} 52 | // 53 | //void* operator new[](size_t size, std::nothrow_t) noexcept 54 | //{ 55 | // return operator new(size); 56 | //} 57 | // 58 | //void operator delete[](void *p, std::nothrow_t) noexcept 59 | //{ 60 | // operator delete(p); 61 | //} 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_vector/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | #include 19 | #include 20 | 21 | // This function is required by common startup code 22 | extern "C" 23 | void interruptHandler() 24 | { 25 | } 26 | 27 | int main(int argc, const char** argv) 28 | { 29 | static_cast(argc); 30 | static_cast(argv); 31 | 32 | std::vector v; 33 | static const int MaxVecSize = 256; 34 | for (int i = 0; i < MaxVecSize; ++i) { 35 | v.push_back(i); 36 | } 37 | 38 | while (true) {}; 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /src/test_cpp/test_cpp_vector/stub.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2014 (C). Alex Robenko. All rights reserved. 3 | // 4 | 5 | // This file is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // You should have received a copy of the GNU General Public License 16 | // along with this program. If not, see . 17 | 18 | 19 | #include 20 | 21 | // This stub function is required by _mainCRTSturtup 22 | extern "C" void exit(int status) 23 | { 24 | static_cast(status); 25 | while (true) {} 26 | } 27 | 28 | // This stub function is required by stdlib 29 | extern "C" void _exit() 30 | { 31 | exit(-1); 32 | } 33 | 34 | // This heap allocation stub is required by stdlib 35 | extern "C" unsigned _sbrk(int inc) 36 | { 37 | static_cast(inc); 38 | return 0; // The application is not intended to be executed, no need for actual heap. 39 | } 40 | 41 | // This stub function is required by stdlib 42 | extern "C" int _kill(int pid, int sig) 43 | { 44 | static_cast(pid); 45 | static_cast(sig); 46 | return -1; 47 | } 48 | 49 | // This stub function is required by stdlib 50 | extern "C" int _getpid(void) { 51 | return 1; 52 | } 53 | 54 | // This stub function is required by stdlib 55 | extern "C" int _write(int file, char *ptr, int len) 56 | { 57 | static_cast(file); 58 | static_cast(ptr); 59 | return len; 60 | } 61 | 62 | // This stub function is required by stdlib 63 | extern "C" int _read(int file, char *ptr, int len) 64 | { 65 | static_cast(file); 66 | static_cast(ptr); 67 | static_cast(len); 68 | return 0; 69 | } 70 | 71 | // This stub function is required by stdlib 72 | extern "C" int _close(int file) 73 | { 74 | static_cast(file); 75 | return -1; 76 | } 77 | 78 | // This stub function is required by stdlib 79 | extern "C" int _fstat(int file, struct stat *st) 80 | { 81 | static_cast(file); 82 | static_cast(st); 83 | return -1; 84 | } 85 | 86 | // This stub function is required by stdlib 87 | extern "C" int _isatty(int file) 88 | { 89 | static_cast(file); 90 | return 1; 91 | } 92 | 93 | // This stub function is required by stdlib 94 | extern "C" int _open(const char *name, int flags, int mode) 95 | { 96 | static_cast(name); 97 | static_cast(flags); 98 | static_cast(mode); 99 | return -1; 100 | } 101 | 102 | // This stub function is required by stdlib 103 | extern "C" int _lseek(int file, int ptr, int dir) 104 | { 105 | static_cast(file); 106 | static_cast(ptr); 107 | static_cast(dir); 108 | return 0; 109 | } 110 | 111 | --------------------------------------------------------------------------------