├── .adr-dir ├── .project-history-dir ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── QUESTION.md │ ├── FEATURE.md │ └── ISSUE.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── PULL_REQUEST_TEMPLATE │ ├── pull_request_template.md │ └── ccc.md ├── docs ├── UsingTheFramework │ ├── adding_new_boot_sequence.md │ ├── memory_allocation.md │ ├── images │ │ └── libcpp_Thread_Construction.png │ ├── cross_compilation.md │ ├── creating_an_application.md │ ├── memory_tuning.md │ ├── processors.md │ ├── subsystems.md │ ├── adding_new_driver_type.md │ ├── optimization.md │ ├── interrupts.md │ ├── customizing_log_macros.md │ ├── new_project_guide.md │ ├── adding_a_new_library_target.md │ └── adding_new_driver.md ├── project-history │ ├── 2018 │ │ ├── 2018-11 │ │ │ ├── 2018-11-30T16:17:28Z_post_TfNuu8oAX22eUxCc.md │ │ │ ├── 2018-11-05T22:38:04Z_post_9yeKJ0nekJ2hDpCu.md │ │ │ ├── 2018-11-14T18:43:50Z_post_LoYsWYNygkvH2P8X.md │ │ │ ├── 2018-11-30T16:16:58Z_post_VCsWXzqd0RMQKhku.md │ │ │ └── 2018-11-09T17:07:30Z_post_kHKgGPTMjy5B2JjB.md │ │ ├── 2018-10 │ │ │ ├── 2018-10-26T17:20:11Z_post_FG1F6+5fCErK85uQ.md │ │ │ ├── 2018-10-26T17:21:19Z_post_ivQ3jB4KGLC6thu4.md │ │ │ └── 2018-10-26T17:20:16Z_post_SstpStVVdUr8lsmI.md │ │ ├── 2018-09 │ │ │ ├── 2018-09-06T13:26:20Z_post_q7FhvI1o6VxPxZdV.md │ │ │ ├── 2018-09-21T22:36:57Z_post_SlP0mN2cBf8l12y+.md │ │ │ ├── 2018-09-06T13:27:15Z_post_eq33KOikfImGeyNx.md │ │ │ ├── 2018-09-09T17:30:23Z_post_Ks6TfZLae3+6RLg8.md │ │ │ ├── 2018-09-20T16:31:47Z_post_hJfWzJhLFvYvtpD1.md │ │ │ └── 2018-09-20T16:29:49Z_post_6TSLX1gksaRVXLgZ.md │ │ ├── 2018-08 │ │ │ └── 2018-08-26T18:54:55Z_post_+1W152FPdLuhYXdq.md │ │ └── 2018-12 │ │ │ └── 2018-12-28T18:24:32Z_post_cwW20w2phQ5ZqxU2.md │ ├── 2019 │ │ ├── 2019-03 │ │ │ ├── 2019-03-06T21:03:16Z_post_2QX4f9oGaSQ94Rja.md │ │ │ ├── 2019-03-28T01:36:27Z_post_VNE7kcwA2nL9psfX.md │ │ │ ├── 2019-03-20T22:35:47Z_post_nYVmcXyajhMjfbUt.md │ │ │ └── 2019-03-23T00:58:51Z_post_8SJTHPBnv1zdbu9U.md │ │ ├── 2019-04 │ │ │ ├── 2019-04-09T23:28:04Z_post_GogFUF17Ixho6Q8N.md │ │ │ ├── 2019-04-23T18:11:50Z_post_9Lt24YuaN6VZr0cK.md │ │ │ └── 2019-04-05T19:42:05Z_post_7PcJNTW7grLioln3.md │ │ └── 2019-01 │ │ │ └── 2019-01-08T17:43:06Z_post_12FW76ag1MZxP1n9.md │ └── 2020 │ │ ├── 2020-11 │ │ └── 2020-11-06T16:42:42Z_note_jQkqMf8gkhRMoi4R.md │ │ ├── 2020-10 │ │ ├── 2020-10-22T17:11:43Z_note_X4uHsgPjnL_H3gSa.md │ │ ├── 2020-10-20T18:48:05Z_note_7jaArrAAd6vPt1Is.md │ │ └── 2020-10-28T22:43:53Z_note__skGoSW_OdHQ9cCi.md │ │ ├── 2020-09 │ │ ├── 2020-09-24T22:28:49Z_note_15T-MTa7eyLJN5P0.md │ │ ├── 2020-09-28T23:10:26Z_note_dA6sLEgHbvc2tJFJ.md │ │ ├── 2020-09-25T19:46:30Z_note_SUEUQIiOFTzbH6Lg.md │ │ └── 2020-09-24T20:59:11Z_note_7Jup8I6JMua6JgNb.md │ │ └── 2020-06 │ │ ├── 2020-06-08T18:55:41Z_note_hkVr6emShxoU_QNm.md │ │ ├── 2020-06-08T18:59:49Z_note_7314riXWpHS2Lyc2.md │ │ └── 2020-06-11T19:01:48Z_note_bYuYD7t0HItc_zpZ.md ├── business │ ├── EcosystemMap.pdf │ └── CompetitiveLandscape.pdf ├── software_inventory.xlsx ├── development │ ├── namespaces.xlsx │ ├── reference │ │ └── abi_register_cheatsheet.md │ └── developer_documentation.md ├── patterns │ ├── images │ │ └── Object_pool1.png │ ├── crtp.md │ ├── traits_class.md │ ├── iterator.md │ ├── mediator.md │ ├── monitor.md │ ├── facade.md │ ├── bridge.md │ ├── composite.md │ ├── state.md │ └── decorator.md ├── architecture │ ├── images │ │ ├── KeyActors.jpg │ │ ├── FeatureModel.png │ │ ├── HighLevelUseCases.jpg │ │ ├── DomainConceptModel.jpg │ │ └── NonFunctionalRequirementRelationships.jpg │ ├── architecture_dashboard.xlsx │ ├── views │ │ ├── layer │ │ │ ├── Context.jpg │ │ │ ├── LayerView.png │ │ │ └── LayerCommunicationMechanisms.jpg │ │ ├── system_structural │ │ │ ├── SystemStructuralView.jpg │ │ │ └── SoftwareStructuralView.jpg │ │ └── conceptual_architecture │ │ │ └── ConceptualModel.png │ ├── components │ │ ├── core │ │ │ ├── boot_sequence_diagram.png │ │ │ ├── interrupt_manager.md │ │ │ ├── event.md │ │ │ └── c_cpp_runtime.md │ │ ├── subsystems │ │ │ ├── usb_stack.md │ │ │ ├── wifi_stack.md │ │ │ ├── bt_stack.md │ │ │ ├── memory_tester.md │ │ │ ├── command_line.md │ │ │ ├── firmware_update.md │ │ │ ├── filesystem.md │ │ │ ├── configuration.md │ │ │ ├── parametric_logging.md │ │ │ ├── version.md │ │ │ ├── boot_flags.md │ │ │ └── logger.md │ │ └── utilities │ │ │ ├── fixed_point_math.md │ │ │ ├── crc.md │ │ │ ├── templated_buffer_pool.md │ │ │ ├── static_function.md │ │ │ ├── static_queue.md │ │ │ ├── transports.md │ │ │ ├── interrupt_lock.md │ │ │ ├── interrupt_queue_top_half.md │ │ │ ├── templated_buffer.md │ │ │ └── instance_list.md │ ├── decisions │ │ ├── 0001-record-architecture-decisions.md │ │ ├── 0012-switch-to-catch-for-unit-testing.md │ │ ├── 0015-use-embvm-top-level-namespace-for-core-interfaces.md │ │ ├── 0003-no-dynamic-memory-allocation-in-core.md │ │ ├── 0020-hardware-platform-options-file.md │ │ ├── 0013-use-templates-to-switch-between-dynamic-and-static-memory.md │ │ ├── 0021-eliminate-name-variables-from-core-base-classes.md │ │ ├── 0022-unified-gpio-base-class.md │ │ ├── 0011-generic-startup-library.md │ │ ├── 0005-provide-non-blocking-interfaces.md │ │ ├── 0010-dispatch-callbacks.md │ │ ├── 0009-event-driven-framework-design.md │ │ ├── 0017-virtual-destructor-usage.md │ │ ├── 0006-differentiate-drivers-and-hal.md │ │ ├── 0004-track-documentation-alongside-source.md │ │ └── 0019-virtual-platform-takes-in-thwplatform-type.md │ ├── scratchpad.md │ ├── principles │ │ ├── 0002-document_the_framework.md │ │ ├── 0007-dont_hack_refactor.md │ │ ├── 0008-honor_the_contracts.md │ │ ├── 0006-fix_the_painful_things.md │ │ ├── 0003-keep_it_simple.md │ │ ├── 0001-get_abstractions_right.md │ │ ├── 0005-defend_the_decoupling_mechanisms.md │ │ └── 0004-avoid_closing_doors.md │ └── use_cases │ │ ├── 0003-user_stories_ci_server.md │ │ └── 0010-compile_in_simulator_mode.md ├── CODE_OF_CONDUCT.md └── templates │ ├── glossary.md │ ├── architecture │ ├── user_story.md │ ├── constraints.md │ ├── architecture_decision.md │ ├── pattern.md │ └── story_bdd.md │ └── business │ └── differentiation_strategy.md ├── src ├── processors │ ├── meson.build │ └── simulator │ │ ├── meson.build │ │ ├── simulator_processor.cpp │ │ └── simulator_processor.hpp ├── utilities │ ├── tuple_array │ │ ├── meson.build │ │ ├── tuple_array_tests.cpp │ │ └── tuple_array.hpp │ ├── bits │ │ └── meson.build │ ├── time │ │ ├── meson.build │ │ └── time_tests.cpp │ ├── bounce │ │ ├── meson.build │ │ └── bounce_tests.cpp │ ├── endian │ │ ├── meson.build │ │ └── endian_tests.cpp │ ├── nop_lock │ │ ├── meson.build │ │ ├── nop_lock.cpp │ │ └── nop_lock.hpp │ ├── aligned_ptr │ │ ├── meson.build │ │ └── aligned_ptr_tests.cpp │ ├── instance_list │ │ └── meson.build │ ├── volatile │ │ ├── meson.build │ │ └── volatile_tests.cpp │ ├── active_object │ │ └── meson.build │ ├── sbrm │ │ ├── meson.build │ │ ├── csbrm_test.cpp │ │ └── scope_guard_tests.cpp │ ├── interrupt_lock │ │ ├── meson.build │ │ └── interrupt_lock_test.cpp │ ├── interrupt_condition │ │ ├── meson.build │ │ └── interrupt_condition_tests.cpp │ ├── dispatch │ │ └── meson.build │ ├── function_queue │ │ ├── function_queue.cpp │ │ └── meson.build │ ├── common.h │ ├── utilities_namespace_documentation.hpp │ ├── compiler.h │ ├── math │ │ └── rounded_div.h │ └── meson.build ├── platforms │ ├── meson.build │ └── unit_test │ │ ├── boot.cpp │ │ ├── platform_options.hpp │ │ ├── hw_platform_options.hpp │ │ ├── meson.build │ │ └── platform.hpp ├── hw_platforms │ ├── meson.build │ └── unit_test │ │ ├── meson.build │ │ └── unittest_hw_platform.hpp ├── core │ ├── register │ │ └── meson.build │ ├── boot │ │ ├── meson.build │ │ ├── boot.cpp │ │ └── boot_sequencer_tests.cpp │ ├── hw_platform │ │ └── meson.build │ ├── platform │ │ └── meson.build │ ├── driver │ │ ├── internal │ │ │ ├── spi.cpp │ │ │ ├── led.cpp │ │ │ ├── time_of_flight.cpp │ │ │ ├── basic_display.cpp │ │ │ ├── timer.cpp │ │ │ ├── system_clock.cpp │ │ │ └── i2c.cpp │ │ ├── meson.build │ │ ├── clock.hpp │ │ └── hal_driver.hpp │ ├── rtos │ │ ├── meson.build │ │ ├── rtos.cpp │ │ └── heap.hpp │ └── namespace_documentation.hpp ├── os │ ├── meson.build │ ├── posix │ │ ├── posix_semaphore.hpp │ │ ├── meson.build │ │ └── posix_os.cpp │ └── namespace_documentation.hpp ├── drivers │ ├── meson.build │ ├── simulator │ │ ├── system_clock.cpp │ │ └── meson.build │ ├── unit_test │ │ ├── meson.build │ │ ├── driver_base.cpp │ │ ├── gpio.cpp │ │ ├── driver.hpp │ │ ├── gpio.hpp │ │ └── spi.cpp │ └── namespace_documentation.hpp └── subsystems │ ├── meson.build │ ├── version │ ├── meson.build │ └── version.h │ ├── logging │ ├── meson.build │ └── log.h │ └── module_definitions.hpp ├── .gitmodules ├── subprojects ├── etl.wrap ├── catch2.wrap ├── libc.wrap ├── libcpp.wrap ├── libmemory.wrap ├── compiler-rt.wrap ├── gsl-lite.wrap ├── packagefiles │ └── gsl-lite-build │ │ └── meson.build └── cmocka.wrap ├── test ├── putchar.c └── meson.build ├── templates ├── application │ ├── main.cpp │ └── meson.build ├── driver │ ├── template_driver_tests.cpp │ ├── led.hpp │ ├── system_clock.hpp │ ├── i2c.hpp │ ├── time_of_flight.hpp │ ├── spi.hpp │ ├── meson.build │ └── driver_base.cpp ├── platform │ ├── template_platform_tests.cpp │ ├── platform_os_options.hpp │ ├── hw_platform_options.hpp │ ├── platform_logger.hpp │ └── meson.build ├── os │ ├── template_hw_platform_tests.cpp │ └── meson.build ├── processor │ ├── template_processor_tests.cpp │ ├── internal │ │ ├── processor_architecture.hpp │ │ └── processor_includes.hpp │ ├── template_processor.cpp │ └── template_processor.hpp ├── hw_platform │ ├── template_hw_platform_tests.cpp │ ├── meson.build │ ├── template_hw_platform.cpp │ └── template_hw_platform.hpp └── processor_arch │ ├── template_processor_arch_tests.cpp │ ├── template_processor_arch.cpp │ ├── template_processor_arch.hpp │ └── meson.build ├── tools ├── download_and_deploy_config_files.sh ├── WeeklyCI.jenkinsfile └── install_arm_gcc.sh ├── .gitattributes ├── .gitignore └── LICENSE.md /.adr-dir: -------------------------------------------------------------------------------- 1 | docs/architecture/decisions 2 | -------------------------------------------------------------------------------- /.project-history-dir: -------------------------------------------------------------------------------- 1 | docs/project-history 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/adding_new_boot_sequence.md: -------------------------------------------------------------------------------- 1 | # Adding a New Boot Sequence 2 | -------------------------------------------------------------------------------- /src/processors/meson.build: -------------------------------------------------------------------------------- 1 | # Processor meson.build 2 | 3 | subdir('simulator') 4 | -------------------------------------------------------------------------------- /src/utilities/tuple_array/meson.build: -------------------------------------------------------------------------------- 1 | tuple_array_test_files = files('tuple_array_tests.cpp') 2 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-11/2018-11-30T16:17:28Z_post_TfNuu8oAX22eUxCc.md: -------------------------------------------------------------------------------- 1 | Refactoring sprint day 2 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-10/2018-10-26T17:20:11Z_post_FG1F6+5fCErK85uQ.md: -------------------------------------------------------------------------------- 1 | First code cleanup sprint 2 | -------------------------------------------------------------------------------- /src/utilities/bits/meson.build: -------------------------------------------------------------------------------- 1 | # Bits Meson Build File 2 | 3 | bits_test_files = files('bits_tests.cpp') 4 | -------------------------------------------------------------------------------- /src/utilities/time/meson.build: -------------------------------------------------------------------------------- 1 | # Time Meson Build File 2 | 3 | time_test_files = files('time_tests.cpp') 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "meson"] 2 | path = meson 3 | url = https://github.com/embeddedartistry/meson-buildsystem 4 | -------------------------------------------------------------------------------- /src/platforms/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for framework internal Platform definitions 2 | 3 | subdir('unit_test') 4 | -------------------------------------------------------------------------------- /src/utilities/bounce/meson.build: -------------------------------------------------------------------------------- 1 | # bounce Meson Build File 2 | 3 | bounce_test_files = files('bounce_tests.cpp') 4 | -------------------------------------------------------------------------------- /src/utilities/endian/meson.build: -------------------------------------------------------------------------------- 1 | # Endian Meson Build File 2 | 3 | endian_test_files = files('endian_tests.cpp') 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-06T13:26:20Z_post_q7FhvI1o6VxPxZdV.md: -------------------------------------------------------------------------------- 1 | CI builds with Jenkins are now enabled 2 | -------------------------------------------------------------------------------- /src/hw_platforms/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for framework internal HW Platform definitions 2 | 3 | subdir('unit_test') 4 | -------------------------------------------------------------------------------- /subprojects/etl.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/etl 3 | revision = master 4 | depth = 1 5 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-11/2018-11-05T22:38:04Z_post_9yeKJ0nekJ2hDpCu.md: -------------------------------------------------------------------------------- 1 | Held monthly framework review meeting today 2 | -------------------------------------------------------------------------------- /src/utilities/nop_lock/meson.build: -------------------------------------------------------------------------------- 1 | # No-op lock build definition 2 | 3 | nop_lock_files = files( 4 | 'nop_lock.cpp' 5 | ) 6 | -------------------------------------------------------------------------------- /subprojects/catch2.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/Catch2 3 | revision = devel 4 | depth = 1 5 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-21T22:36:57Z_post_SlP0mN2cBf8l12y+.md: -------------------------------------------------------------------------------- 1 | Held conceptual architecture review meeting today 2 | -------------------------------------------------------------------------------- /src/core/register/meson.build: -------------------------------------------------------------------------------- 1 | # Register Meson Build File 2 | 3 | register_test_files = files( 4 | 'register_tests.cpp', 5 | ) 6 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-06T13:27:15Z_post_eq33KOikfImGeyNx.md: -------------------------------------------------------------------------------- 1 | Finished James Grenning's TDD webinar course (3 days) 2 | -------------------------------------------------------------------------------- /src/utilities/aligned_ptr/meson.build: -------------------------------------------------------------------------------- 1 | # aligned_ptr Meson Build File 2 | 3 | aligned_ptr_test_files = files('aligned_ptr_tests.cpp') 4 | -------------------------------------------------------------------------------- /src/utilities/instance_list/meson.build: -------------------------------------------------------------------------------- 1 | # Instance List Build File 2 | 3 | instance_list_test_files = files('instance_list_test.cpp') 4 | -------------------------------------------------------------------------------- /src/utilities/volatile/meson.build: -------------------------------------------------------------------------------- 1 | # Volatile Meson Build File 2 | 3 | volatile_test_files = files( 4 | 'volatile_tests.cpp' 5 | ) 6 | -------------------------------------------------------------------------------- /subprojects/libc.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/libc 3 | revision = master 4 | clone-recursive = true 5 | -------------------------------------------------------------------------------- /src/os/meson.build: -------------------------------------------------------------------------------- 1 | # TODO: really? maybe just eliminate this 2 | #framework_includes += include_directories('.') 3 | 4 | subdir('posix') 5 | -------------------------------------------------------------------------------- /subprojects/libcpp.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/libcpp 3 | revision = master 4 | clone-recursive = true 5 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-11/2020-11-06T16:42:42Z_note_jQkqMf8gkhRMoi4R.md: -------------------------------------------------------------------------------- 1 | Initial public release of Embedded VM was made on 11/4/2020. 2 | -------------------------------------------------------------------------------- /src/utilities/active_object/meson.build: -------------------------------------------------------------------------------- 1 | # Active Object Meson Build File 2 | 3 | active_object_test_files = files('active_object_tests.cpp') 4 | -------------------------------------------------------------------------------- /subprojects/libmemory.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/libmemory 3 | revision = master 4 | clone-recursive = true 5 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-11/2018-11-14T18:43:50Z_post_LoYsWYNygkvH2P8X.md: -------------------------------------------------------------------------------- 1 | Improved our cppcheck implementation with additional custom rules 2 | -------------------------------------------------------------------------------- /src/drivers/meson.build: -------------------------------------------------------------------------------- 1 | # Driver Build 2 | 3 | driver_include_root = include_directories('.') 4 | 5 | subdir('simulator') 6 | subdir('unit_test') 7 | -------------------------------------------------------------------------------- /src/utilities/sbrm/meson.build: -------------------------------------------------------------------------------- 1 | # SBRM Meson Build File 2 | 3 | sbrm_test_files = files( 4 | 'csbrm_test.cpp', 5 | 'scope_guard_tests.cpp' 6 | ) 7 | -------------------------------------------------------------------------------- /subprojects/compiler-rt.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/embeddedartistry/compiler-rt 3 | revision = master 4 | clone-recursive = true 5 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/memory_allocation.md: -------------------------------------------------------------------------------- 1 | # Memory Allocation Guide 2 | 3 | ## Selecting a memory allocator 4 | 5 | ## Static Memory Tools in the ETL 6 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-10/2020-10-22T17:11:43Z_note_X4uHsgPjnL_H3gSa.md: -------------------------------------------------------------------------------- 1 | Names were eliminated from many embvm-core base classes - not necssary. 2 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-08/2018-08-26T18:54:55Z_post_+1W152FPdLuhYXdq.md: -------------------------------------------------------------------------------- 1 | Imported notes from "EA Framework" Evernote notebook, deleted the notebook. 2 | -------------------------------------------------------------------------------- /src/utilities/interrupt_lock/meson.build: -------------------------------------------------------------------------------- 1 | # Interrupt Lock Meson Build File 2 | 3 | interrupt_lock_test_files = files( 4 | 'interrupt_lock_test.cpp', 5 | ) 6 | -------------------------------------------------------------------------------- /subprojects/gsl-lite.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/gsl-lite/gsl-lite.git 3 | patch_directory = gsl-lite-build 4 | revision = master 5 | depth=1 6 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-03/2019-03-06T21:03:16Z_post_2QX4f9oGaSQ94Rja.md: -------------------------------------------------------------------------------- 1 | Finished the first-pass documentation and namespacing of the framework with Doxygen. 2 | -------------------------------------------------------------------------------- /docs/business/EcosystemMap.pdf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:480f68e422a95e9c72f0f2af4d9a3ac025ed255ca0834d917c2c4776e3f275c6 3 | size 522915 4 | -------------------------------------------------------------------------------- /docs/software_inventory.xlsx: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:36d8790727fac027d5894c5a083385c3831fb6fc18d9f8dce609db7b4ea492c6 3 | size 12392 4 | -------------------------------------------------------------------------------- /src/subsystems/meson.build: -------------------------------------------------------------------------------- 1 | # Subsystem meson.build file 2 | 3 | subdir('logging') 4 | subdir('version') 5 | 6 | subsystem_test_files = [ 7 | logging_test_files, 8 | ] 9 | -------------------------------------------------------------------------------- /docs/development/namespaces.xlsx: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7a16aa5312bd974310cea2a6b3e02e99e728fe22cb3eeceb65d688cfd8dbc137 3 | size 11025 4 | -------------------------------------------------------------------------------- /docs/patterns/images/Object_pool1.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7644e064edd1fe340f13f8aae4b1591061b9cb4070046a783de662336b5d9704 3 | size 4514 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-10/2018-10-26T17:21:19Z_post_ivQ3jB4KGLC6thu4.md: -------------------------------------------------------------------------------- 1 | Marek Belisko is interested in collaborating on the framework driver/chip development efforts. 2 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-12/2018-12-28T18:24:32Z_post_cwW20w2phQ5ZqxU2.md: -------------------------------------------------------------------------------- 1 | Framework development paused to support BSS project. Resumed today with code cleanup sprint. 2 | -------------------------------------------------------------------------------- /docs/architecture/images/KeyActors.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0d0534c05d401f40de885ca8e4b99730bde24661ef3599f9ef363c48d2856785 3 | size 58665 4 | -------------------------------------------------------------------------------- /docs/business/CompetitiveLandscape.pdf: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aa009cb069af41fcf3a888c2831ac3a9edb7fbe517e92ca00bb985d928c45313 3 | size 737210 4 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-09/2020-09-24T22:28:49Z_note_15T-MTa7eyLJN5P0.md: -------------------------------------------------------------------------------- 1 | Initial import of files from the monolithic embedded-framework repo. Does not work at this stage. 2 | -------------------------------------------------------------------------------- /src/core/boot/meson.build: -------------------------------------------------------------------------------- 1 | # Boot Sequencer meson.build 2 | 3 | boot_platform_files = files('boot.cpp') 4 | 5 | boot_test_files = files( 6 | 'boot_sequencer_tests.cpp', 7 | ) 8 | -------------------------------------------------------------------------------- /src/utilities/interrupt_condition/meson.build: -------------------------------------------------------------------------------- 1 | # Interrupt condition Meson Build File 2 | 3 | interrupt_condition_test_files = files( 4 | 'interrupt_condition_tests.cpp', 5 | ) 6 | -------------------------------------------------------------------------------- /docs/architecture/architecture_dashboard.xlsx: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:309766e7372144f33f0caf5291fe9434624ccac6ec854dc8e0e644d6f290ab1f 3 | size 16381 4 | -------------------------------------------------------------------------------- /docs/architecture/images/FeatureModel.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e1e5350528319e8e0a13184a6d7cd0fa7c6ca176987774a51076be99dffb02f8 3 | size 779522 4 | -------------------------------------------------------------------------------- /docs/architecture/images/HighLevelUseCases.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:da9c66ee7aee2b2db433e6463b9005c702fdf09c4d8d2a84c73723ab5c4be7e6 3 | size 90528 4 | -------------------------------------------------------------------------------- /docs/architecture/views/layer/Context.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3f36ca8b1cbac7ffcf31a8b75195500d8104388e62ad136e55e690002d9b8b62 3 | size 188035 4 | -------------------------------------------------------------------------------- /docs/architecture/views/layer/LayerView.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:83f04fb12c59088f8381a4bfa64f3bff767bad25a7347b999b468efb9432111d 3 | size 556634 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-09T17:30:23Z_post_Ks6TfZLae3+6RLg8.md: -------------------------------------------------------------------------------- 1 | Converted from Doctest to Catch2 for unit testing due to XML reporting & support for -fno-exceptions 2 | -------------------------------------------------------------------------------- /src/core/hw_platform/meson.build: -------------------------------------------------------------------------------- 1 | # Core HW Platform Build Definition 2 | 3 | hw_platform_test_files = files( 4 | 'timer_manager_tests.cpp', 5 | 'virtual_hw_platform_tests.cpp' 6 | ) 7 | -------------------------------------------------------------------------------- /src/core/platform/meson.build: -------------------------------------------------------------------------------- 1 | # Core Platform Build Definition 2 | 3 | platform_files = files( 4 | ) 5 | 6 | platform_test_files = files( 7 | 'virtual_platform_tests.cpp', 8 | ) 9 | -------------------------------------------------------------------------------- /docs/architecture/images/DomainConceptModel.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e86e0ce2c3bbe30d1b2f55c2a0a26228155b14a7022298a836044e3d0dd8f747 3 | size 192346 4 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-09/2020-09-28T23:10:26Z_note_dA6sLEgHbvc2tJFJ.md: -------------------------------------------------------------------------------- 1 | First wave of build refactoring after trying to use embvm-core as a module in another emvbm project (nordic) 2 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/images/libcpp_Thread_Construction.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2e7c524861c0c9b76d8639f86799c471db71d70f56a1bf9f8ba4902f14f065cc 3 | size 356843 4 | -------------------------------------------------------------------------------- /docs/architecture/components/core/boot_sequence_diagram.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f2946d62204aab3714cbe605ba7b5e3bbf51a914d6f00386d90eb1f6a88e367f 3 | size 253077 4 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-04/2019-04-09T23:28:04Z_post_GogFUF17Ixho6Q8N.md: -------------------------------------------------------------------------------- 1 | Initial FreeRTOS support implemented. Many changes to the RTOS interfaces have been identified, some are still pending. 2 | -------------------------------------------------------------------------------- /src/core/driver/internal/spi.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | -------------------------------------------------------------------------------- /src/utilities/dispatch/meson.build: -------------------------------------------------------------------------------- 1 | # Dispatch Meson Build File 2 | 3 | dispatch_test_files = files( 4 | 'static_dispatch_test.cpp', 5 | 'dispatch_test.cpp', 6 | 'interrupt_queue_test.cpp', 7 | ) 8 | -------------------------------------------------------------------------------- /docs/architecture/views/layer/LayerCommunicationMechanisms.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:557fbed17975813259e9aad9ec215d9066c254267a3627f454bd2d6cb076bf9d 3 | size 145394 4 | -------------------------------------------------------------------------------- /docs/architecture/views/system_structural/SystemStructuralView.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4a94adbce227c19a7cbe8743799d070217dba110318d1c69964cb95e477e4aeb 3 | size 74547 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-11/2018-11-30T16:16:58Z_post_VCsWXzqd0RMQKhku.md: -------------------------------------------------------------------------------- 1 | Demo app progress - timer triggers continual ToF sensor read and display an OLED, along with LED blink. Runs for 2 hours. 2 | -------------------------------------------------------------------------------- /docs/architecture/images/NonFunctionalRequirementRelationships.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:17d7aacde28244b08d52323129d2231578bbfbaf1f5bc6f5c49dda8ea0d085f9 3 | size 120213 4 | -------------------------------------------------------------------------------- /docs/architecture/views/conceptual_architecture/ConceptualModel.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:13a7fca6e479411ae1a03fbdd593317b7252196cf05a5434faf3287edef2ebb5 3 | size 297047 4 | -------------------------------------------------------------------------------- /docs/architecture/views/system_structural/SoftwareStructuralView.jpg: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3f36ca8b1cbac7ffcf31a8b75195500d8104388e62ad136e55e690002d9b8b62 3 | size 188035 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-10/2018-10-26T17:20:16Z_post_SstpStVVdUr8lsmI.md: -------------------------------------------------------------------------------- 1 | Milestone reached: talked to an I2C ToF sensor using the generic framework interfaces from a macbook using an Aardvark sensor. 2 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-04/2019-04-23T18:11:50Z_post_9Lt24YuaN6VZr0cK.md: -------------------------------------------------------------------------------- 1 | Framework demo on embedded: major progress! 2 | 3 | We have a time of flight driver printing to the display on an nRF52 with blinking LEDs! 4 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-04/2019-04-05T19:42:05Z_post_7PcJNTW7grLioln3.md: -------------------------------------------------------------------------------- 1 | Binary size significantly reduced (60%) in release mode by removing demangling code. This code was being linked in, even though we aren't using RTTI or demangling calls. 2 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-09/2020-09-25T19:46:30Z_note_SUEUQIiOFTzbH6Lg.md: -------------------------------------------------------------------------------- 1 | Refactored build system so emvbm-core now compiles and successfully runs the unit tests. Next up, I need to make this build work in a modular way (e.g., as a subproject) 2 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-10/2020-10-20T18:48:05Z_note_7jaArrAAd6vPt1Is.md: -------------------------------------------------------------------------------- 1 | Took on redesign of driver base class and driver registry, which set in motion pretty big changes for all of the embvm projects. Better to do this now than after release! 2 | -------------------------------------------------------------------------------- /src/core/driver/internal/led.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | embvm::led::base::~base() noexcept = default; 7 | -------------------------------------------------------------------------------- /test/putchar.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Forward declare because including will cause printf conflicts 4 | int putchar(int); 5 | 6 | // TODO: move this to a better home 7 | void putchar_(char ch) 8 | { 9 | putchar(ch); 10 | } 11 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/cross_compilation.md: -------------------------------------------------------------------------------- 1 | # Cross Compilation 2 | 3 | ## Standard Machine Files 4 | 5 | ## Writing Your Own Machine Files 6 | 7 | ## Enabling a Cross-Compiled Build 8 | 9 | ## Checking Processor Architecture in your Build Rules 10 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-01/2019-01-08T17:43:06Z_post_12FW76ag1MZxP1n9.md: -------------------------------------------------------------------------------- 1 | Held framework strategy meeting & status review on 1/7/19. Planned high-level activities for embedded bringup stage, determined open architecture task, and prioritized issues. 2 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-03/2019-03-28T01:36:27Z_post_VNE7kcwA2nL9psfX.md: -------------------------------------------------------------------------------- 1 | I discovered ThreadSanitizer and AddressSantizer. Running both of those tools on the framework tests revealed quite a few problems. They've been addressed and fixed (largely). 2 | -------------------------------------------------------------------------------- /src/hw_platforms/unit_test/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for unit test HW platform 2 | 3 | unit_test_hw_platform_dep = declare_dependency( 4 | include_directories: include_directories('.'), 5 | dependencies: [unit_test_drivers_dep, simulator_driver_dep] 6 | ) 7 | -------------------------------------------------------------------------------- /src/core/rtos/meson.build: -------------------------------------------------------------------------------- 1 | # Core RTOS Build Definition 2 | 3 | rtos_files = files( 4 | 'libcpp_threading.cpp', 5 | 'rtos.cpp' 6 | ) 7 | 8 | ###################### 9 | # Supporting Tooling # 10 | ###################### 11 | clangtidy_files += rtos_files 12 | -------------------------------------------------------------------------------- /src/utilities/function_queue/function_queue.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "function_queue.hpp" 5 | 6 | embutil::FuncOp::~FuncOp() = default; 7 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-09/2020-09-24T20:59:11Z_note_7Jup8I6JMua6JgNb.md: -------------------------------------------------------------------------------- 1 | Modularization of initial monolithic embedded-framework repository into distinct modules. 2 | 3 | This is motivated by Wildlife Computers' interest in using the framework for ARM development. 4 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-06/2020-06-08T18:55:41Z_note_hkVr6emShxoU_QNm.md: -------------------------------------------------------------------------------- 1 | Updated the build system to use Meson subprojects instead of submodules directly in the source tree. This temporarily broke the project build for a while while we got everything updated once again. 2 | -------------------------------------------------------------------------------- /templates/application/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | volatile bool abort_program_ = false; 4 | 5 | int main() 6 | { 7 | auto& platform = VirtualPlatform::inst(); 8 | 9 | while(!abort_program_) 10 | { 11 | // spin 12 | } 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/core/driver/internal/time_of_flight.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | embvm::tof::sensor::~sensor() noexcept = default; 7 | -------------------------------------------------------------------------------- /src/utilities/function_queue/meson.build: -------------------------------------------------------------------------------- 1 | # Function Queue Meson Build File 2 | 3 | function_queue_files = files( 4 | 'function_queue.cpp' 5 | ) 6 | 7 | #TODO: Why do I have to duplicate this? 8 | function_queue_test_files = files( 9 | 'function_queue_tests.cpp', 10 | ) 11 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/usb_stack.md: -------------------------------------------------------------------------------- 1 | # CRC-R: USB Stack 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/wifi_stack.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Wi-FI Stack 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | -------------------------------------------------------------------------------- /src/core/driver/internal/basic_display.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | embvm::basicDisplay::~basicDisplay() noexcept = default; 7 | -------------------------------------------------------------------------------- /src/core/driver/internal/timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | using namespace embvm::timer; 7 | 8 | Timer::~Timer() noexcept = default; 9 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/bt_stack.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Bluetooth Stack 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-11/2018-11-09T17:07:30Z_post_kHKgGPTMjy5B2JjB.md: -------------------------------------------------------------------------------- 1 | Integrated C++ ring-span-lite library, which matches the proposed C++ ring-span data type. 2 | 3 | This is chosen over our example circular buffer library in order to support future compliance with the C++ standard. 4 | -------------------------------------------------------------------------------- /tools/download_and_deploy_config_files.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | INITIAL_DIR=$(pwd) 4 | cd /tmp 5 | git clone git@github.com:embeddedartistry/config-files --depth 1 6 | cd config-files 7 | bash copy_config.sh 8 | ls copy_config.sh 9 | cd ../ 10 | rm -rf config-files 11 | cd $INITIAL_DIR 12 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-06/2020-06-08T18:59:49Z_note_7314riXWpHS2Lyc2.md: -------------------------------------------------------------------------------- 1 | At this point, I've decided to refactor the current build setup to completion, and then nuke this repository. We'll go for the more ideal construct: framework in one repo / subproject, with examples contained in separate repositories. 2 | -------------------------------------------------------------------------------- /src/core/driver/internal/system_clock.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | using namespace embvm::clk; 7 | 8 | SystemClock::~SystemClock() noexcept = default; 9 | -------------------------------------------------------------------------------- /src/drivers/simulator/system_clock.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "system_clock.hpp" 5 | 6 | using namespace embdrv; 7 | 8 | SimulatorSystemClock::~SimulatorSystemClock() noexcept = default; 9 | -------------------------------------------------------------------------------- /src/os/posix/posix_semaphore.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifdef __APPLE__ 5 | #include "_semaphore/_posix_semaphore_apple.hpp" 6 | #else 7 | #include "_semaphore/_posix_semaphore_default.hpp" 8 | #endif 9 | -------------------------------------------------------------------------------- /src/utilities/interrupt_condition/interrupt_condition_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "interrupt_condition.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-20T16:31:47Z_post_hJfWzJhLFvYvtpD1.md: -------------------------------------------------------------------------------- 1 | Static analysis support has been added to the Jenkins builds. 2 | 3 | The Jenkins builds are updating statuses on GitHub. We've enabled branch protections for embedded-framework, libc, and libmemory. Before merging to master, these checks must pass. 4 | -------------------------------------------------------------------------------- /src/utilities/nop_lock/nop_lock.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "nop_lock.hpp" 5 | 6 | using namespace embutil; 7 | 8 | void nop_lock::lock() noexcept {} 9 | 10 | void nop_lock::unlock() noexcept {} 11 | -------------------------------------------------------------------------------- /subprojects/packagefiles/gsl-lite-build/meson.build: -------------------------------------------------------------------------------- 1 | project('gsl-lite', 2 | version: '0.37.1' 3 | ) 4 | 5 | gsl_lite_dep = declare_dependency( 6 | include_directories: include_directories('include'), 7 | compile_args: [ 8 | '-Dgsl_CONFIG_DEFAULTS_VERSION=1', 9 | '-Dgsl_CONFIG_NOT_NULL_EXPLICIT_CTOR=0', 10 | ] 11 | ) 12 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-06/2020-06-11T19:01:48Z_note_bYuYD7t0HItc_zpZ.md: -------------------------------------------------------------------------------- 1 | Finished initial refactor of the framework to use subprojects instead of submodules. The biggest problem that I've identified so far is controlling the link and include order for libc/libcpp/libmemory. We need some way to simplify that for users (including me!). 2 | -------------------------------------------------------------------------------- /src/processors/simulator/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for Simulator Processor 2 | 3 | simulator_processor_dep = declare_dependency( 4 | include_directories: [ 5 | include_directories('.'), 6 | ], 7 | sources: files('simulator_processor.cpp'), 8 | link_args: '-e_entry', 9 | # TODO: is an include dependnecy needed here? 10 | ) 11 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-03/2019-03-20T22:35:47Z_post_nYVmcXyajhMjfbUt.md: -------------------------------------------------------------------------------- 1 | First successful attempt to run any kind of framework C++ code on an embedded platform! 2 | 3 | nRF52840 USB Dongle + Nordic linker scripts & GCC libc -> blinky application runs! 4 | 5 | Now the full bring-up of an embedded platform running framework code begins. 6 | -------------------------------------------------------------------------------- /src/drivers/unit_test/meson.build: -------------------------------------------------------------------------------- 1 | # Unit Test Driver Build Definitions 2 | 3 | unit_test_driver_files = files( 4 | 'driver_base.cpp', 5 | 'gpio.cpp', 6 | 'i2c.cpp', 7 | 'spi.cpp' 8 | ) 9 | 10 | unit_test_drivers_dep = declare_dependency( 11 | sources: unit_test_driver_files, 12 | include_directories: driver_include_root 13 | ) 14 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/creating_an_application.md: -------------------------------------------------------------------------------- 1 | # Creating a Framework Application 2 | 3 | ## Assembling the Components 4 | 5 | * Define/select a processor 6 | * Define/select a hardware platform 7 | * Define/select a platform 8 | * Create a boot stratey 9 | 10 | ## Defining a Build 11 | 12 | ## Using the Platform to build the application 13 | -------------------------------------------------------------------------------- /templates/driver/template_driver_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "your_driver.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[driver/your_driver]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /docs/project-history/2019/2019-03/2019-03-23T00:58:51Z_post_8SJTHPBnv1zdbu9U.md: -------------------------------------------------------------------------------- 1 | Today marks the first time a full framework build - with our libc, libmemory, libcpp, framework core, framework utilities - ran on an embedded platform (nRF52 USB dongle). 2 | 3 | Next up is migrating to our own linker and processor startup code, since we are still using the vendor. 4 | -------------------------------------------------------------------------------- /docs/project-history/2018/2018-09/2018-09-20T16:29:49Z_post_6TSLX1gksaRVXLgZ.md: -------------------------------------------------------------------------------- 1 | Ben West expressed interest in our architecture services. We are creating a proposal and presentation which describes our architecture approach. 2 | 3 | This product is a potential framework target. There are 4 firmware variants, a known chip change, and each HW component will change. 4 | -------------------------------------------------------------------------------- /templates/platform/template_platform_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "platform.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[platform/template_platform]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /templates/os/template_hw_platform_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "templat_hw_platform.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[hw_platform/template_hw_platform]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /templates/processor/template_processor_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "template_processor.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[processors/template_processor]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /templates/hw_platform/template_hw_platform_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "template_hw_platform.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[hw_platform/template_hw_platform]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /templates/processor_arch/template_processor_arch_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "templat_hw_platform.hpp" 2 | #include 3 | 4 | #pragma mark - Helper Functions - 5 | 6 | #pragma mark - Test Cases - 7 | 8 | TEST_CASE("Test case", "[hw_platform/template_hw_platform]") 9 | { 10 | // CHECK() 11 | // REQUIRE() 12 | // STATIC_REQUIRE() for compile-time checks 13 | } 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/QUESTION.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Use this template to ask a question about the project 4 | title: "[QUESTION SUMMARY]" 5 | labels: question 6 | assignees: phillipjohnston 7 | --- 8 | 9 | ## Question 10 | 11 | State your question 12 | 13 | ## Sample Code 14 | 15 | Please include relevant code snippets or files that provide context for your question. 16 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/fixed_point_math.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Fixed Point Math 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | Sometimes needed - include? It will be needed for the Marble system demo 26 | -------------------------------------------------------------------------------- /src/drivers/unit_test/driver_base.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "driver.hpp" 5 | 6 | using namespace test; 7 | 8 | TestDriverBase::~TestDriverBase() noexcept {} 9 | 10 | void TestDriverBase::start_() noexcept {} 11 | 12 | void TestDriverBase::stop_() noexcept {} 13 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/memory_tester.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Memory Tester 2 | 3 | ## Responsibilities 4 | 5 | Test a region of memory and report if there are errors. 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | Clients sometimes need this - valuable to add? 26 | -------------------------------------------------------------------------------- /src/platforms/unit_test/boot.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | #include 6 | 7 | extern "C" void entry() 8 | { 9 | bootSystem(); 10 | } 11 | 12 | // Unit test platform simply calls main 13 | extern "C" void bootSystem() 14 | { 15 | main(); 16 | } 17 | -------------------------------------------------------------------------------- /src/subsystems/version/meson.build: -------------------------------------------------------------------------------- 1 | # Version Subystem Build Definition 2 | 3 | version_source = custom_target('gen-version', 4 | output: 'version.c', 5 | command: [meson.project_source_root() + '/meson/scripts/make_version.sh', '@OUTPUT@'], 6 | build_always_stale: true 7 | ) 8 | 9 | version_subsystem_dep = declare_dependency( 10 | include_directories: include_directories('.'), 11 | sources: version_source, 12 | ) 13 | -------------------------------------------------------------------------------- /src/core/driver/meson.build: -------------------------------------------------------------------------------- 1 | # Core Driver Build Definition 2 | 3 | driver_files = files( 4 | 'internal/i2c.cpp', 5 | 'internal/led.cpp', 6 | 'internal/basic_display.cpp', 7 | 'internal/spi.cpp', 8 | 'internal/system_clock.cpp', 9 | 'internal/time_of_flight.cpp', 10 | 'internal/timer.cpp' 11 | ) 12 | 13 | driver_test_files = files( 14 | 'driver_test.cpp', 15 | 'driver_registry_tests.cpp' 16 | ) 17 | -------------------------------------------------------------------------------- /src/core/boot/boot.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | #include // For boot sequencer type 6 | 7 | extern "C" __attribute__((weak)) void entry() 8 | { 9 | bootSystem(); 10 | } 11 | 12 | extern "C" void bootSystem() 13 | { 14 | PlatformBootSequencer::boot(); 15 | } 16 | -------------------------------------------------------------------------------- /docs/project-history/2020/2020-10/2020-10-28T22:43:53Z_note__skGoSW_OdHQ9cCi.md: -------------------------------------------------------------------------------- 1 | We near the initial release of the Embedded VM as a public project. Design changes are still being made, such as cleaning up the GPIO approach, as well as correcting the build problems resulting from a lack of libc/libcpp specification through cross files. Documentation is currently the biggest gate to a release, although we also want to expand the STM32 driver samples. 2 | -------------------------------------------------------------------------------- /src/subsystems/logging/meson.build: -------------------------------------------------------------------------------- 1 | # Logging Subsystem Build File 2 | 3 | logging_subsystem_dep = declare_dependency( 4 | include_directories: include_directories('.'), 5 | ) 6 | 7 | logging_test_files = files( 8 | 'logging_tests.cpp', 9 | ) 10 | 11 | ###################### 12 | # Supporting Tooling # 13 | ###################### 14 | # TODO: clangtidy_files += 15 | catch2_tests_dep += declare_dependency( 16 | sources: logging_test_files 17 | ) 18 | -------------------------------------------------------------------------------- /src/utilities/common.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef COMMON_H_ 5 | #define COMMON_H_ 6 | 7 | /// To use: 8 | /// CONSTANT(size, 5); 9 | /// char buffer[size]; 10 | #define CONSTANT(name, value) \ 11 | enum \ 12 | { \ 13 | name = value \ 14 | } 15 | 16 | #endif // COMMON_H_ 17 | -------------------------------------------------------------------------------- /docs/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | The latest version of the [Embedded Artistry Code of Conduct](https://embeddedartistry.com/fieldatlas/embedded-artistry-code-of-conduct/) is found on [our website](https://embeddedartistry.com/fieldatlas/embedded-artistry-code-of-conduct/). 4 | 5 | All contributors and community members are expected to adhere to [the Code](https://embeddedartistry.com/fieldatlas/embedded-artistry-code-of-conduct/). 6 | -------------------------------------------------------------------------------- /src/platforms/unit_test/platform_options.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef UNIT_TEST_PLATFORM_OPTIONS_HPP_ 5 | #define UNIT_TEST_PLATFORM_OPTIONS_HPP_ 6 | 7 | #include 8 | #include 9 | 10 | using PlatformDispatchQueue = embutil::DynamicDispatchQueue<>; 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /docs/patterns/crtp.md: -------------------------------------------------------------------------------- 1 | # Pattern: Curiously Recurring Template Pattern (CRTP) 2 | 3 | TBD 4 | 5 | ## Diagrams 6 | 7 | TBD 8 | 9 | ## Context 10 | 11 | TBD 12 | 13 | ## Problem 14 | 15 | TBD 16 | 17 | ## Solution 18 | 19 | TBD 20 | 21 | ## Consequences 22 | 23 | TBD 24 | 25 | ## Known Uses 26 | 27 | TBD 28 | 29 | ## Variants 30 | 31 | TBD 32 | 33 | ## Related Patterns 34 | 35 | TBD 36 | 37 | ## References 38 | 39 | TBD 40 | 41 | ## Notes 42 | 43 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/memory_tuning.md: -------------------------------------------------------------------------------- 1 | # Memory Tuning Guide 2 | 3 | Memory tuning is the most effective when all features are implemented and the program is in a "stable" state. 4 | 5 | * Review static memory allocations and ensure no additional storage is allocated for quantities that are not variable during run-time 6 | * If using a `StaticDriverRegistry`, reduce the max size so that `capacity()` == `size()` 7 | * Review ETL memory pools to ensure they are properly tuned 8 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/command_line.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Command Line 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | How can we automate every driver providing a command line interface? 26 | 27 | Can this be an aspect we insert based on the base class? 28 | 29 | AKA debug console 30 | 31 | -------------------------------------------------------------------------------- /src/subsystems/version/version.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | const char* version_str(); 9 | const char* version_str_short(); 10 | const char* build_id(); // commit 11 | const char* build_machine(); 12 | const char* build_timestamp(); 13 | const char* build_os(); 14 | 15 | #ifdef __cplusplus 16 | } 17 | #endif 18 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/crc.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Checksum 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | * [CRC in C from Barr](https://barrgroup.com/downloads/code-crc-c?utm_medium=email&utm_source=ss&sslid=MzU0NTY0tLCwNDE0AAA&sseid=MzQzM7Y0MzE0MwIA&jobid=da7e8f9b-b68f-4304-a937-3ac8fa944e8e) 26 | -------------------------------------------------------------------------------- /src/platforms/unit_test/hw_platform_options.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef UNIT_TEST_HW_PLATFORM_OPTIONS_HPP_ 5 | #define UNIT_TEST_HW_PLATFORM_OPTIONS_HPP_ 6 | 7 | #include 8 | #include 9 | 10 | using PlatformDriverRegistry = embvm::DynamicDriverRegistry; 11 | 12 | #endif // UNIT_TEST_HW_PLATFORM_OPTIONS_HPP_ 13 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/firmware_update.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Firmware Update 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | * OTA Module: 26 | * need 2-stage boot + firmware + recovery FW (or backup full firmware depending on flash size) 27 | * must meet minimal flash size requirements! 28 | -------------------------------------------------------------------------------- /src/utilities/nop_lock/nop_lock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef NOOP_LOCK_HPP_ 5 | #define NOOP_LOCK_HPP_ 6 | 7 | namespace embutil 8 | { 9 | /// Use this lock class to disable locking behavior at compile-time 10 | class nop_lock 11 | { 12 | public: 13 | void lock() noexcept; 14 | void unlock() noexcept; 15 | }; 16 | 17 | } // namespace embutil 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/processors.md: -------------------------------------------------------------------------------- 1 | 2 | Processors use multiple inheritence to compose functionality: 3 | Unfortunately, misguided usage has made this once popular feature almost completely disappear. On the other hand, sometimes you want to inherit from parents that are completely separate from each other. This is where multiple inheritance can become productive. Classes that have orthogonal behaviors are the best case scenario for multiple inheritance. 4 | 5 | Combination of arch (Cortex-A5) + chip (SAMA5D3) 6 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/filesystem.md: -------------------------------------------------------------------------------- 1 | # CRC-R: File System 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | We need a basic filesystem abstraction. The interface should work for simple flash devices as well as OSes, if possible. Our initial implementation can be a simulator filesystem and a simple EEPROM/flash without directory support. 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | -------------------------------------------------------------------------------- /src/platforms/unit_test/meson.build: -------------------------------------------------------------------------------- 1 | # Unit testing platform definition 2 | 3 | # The unit test platform does not rely on our libc or libc++ because we want it to 4 | # always compile for the native machine. Disabling exceptions or STDIO would mean 5 | # that the tests fail to compile. 6 | unit_test_platform_dep = declare_dependency( 7 | include_directories: include_directories('.'), 8 | sources: files('boot.cpp'), 9 | dependencies: [ 10 | unit_test_hw_platform_dep, 11 | posix_os_dep, 12 | ] 13 | ) 14 | -------------------------------------------------------------------------------- /src/subsystems/module_definitions.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | /** @defgroup FrameworkSubsystems Framework Subsystems 5 | * 6 | * Re0usable subsystms which can be added to an application to provide a specific feature. 7 | */ 8 | 9 | /** @defgroup LoggingSubsystem Logging Subsystem 10 | * 11 | * Subsystem which provides logging support. 12 | * 13 | * @ingroup FrameworkSubsystems 14 | */ 15 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/subsystems.md: -------------------------------------------------------------------------------- 1 | # Subsystems 2 | 3 | Subsystems are modular feature sets that can be provided by the `embvm-core` project in a portable manner. These include general strategies such as logging, system power management, parametric data collection, key-value stores, and more. 4 | 5 | ## Available Subsystems 6 | 7 | - Logging module is currently the main one 8 | 9 | Demonstrate dependency; strategy selection 10 | 11 | 12 | ## Planned Subsystems 13 | 14 | - System power management 15 | - 16 | -------------------------------------------------------------------------------- /src/utilities/utilities_namespace_documentation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | /// Embedded framework utility functions and classes. 5 | /// Framework utilites are not tied to a platform implementation. They can be used in any 6 | /// framework layer. 7 | namespace embutil 8 | { 9 | /** @defgroup FrameworkUtils Framework Utilities 10 | * 11 | * Embedded Framework utility classes and functions 12 | */ 13 | }; 14 | -------------------------------------------------------------------------------- /src/utilities/compiler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef COMPILER_DEFS_H_ 5 | #define COMPILER_DEFS_H_ 6 | 7 | // TODO: move this somewhere safe to do a system header include to squash warnings 8 | 9 | #define __printf_check(istr, iarg) __attribute__((format(printf, istr, iarg))) 10 | #define __printf_check_cpp(istr, iarg) __attribute__((format(printf, istr + 1, iarg + 1))) 11 | 12 | #endif // COMPILER_DEFS_H_ 13 | -------------------------------------------------------------------------------- /subprojects/cmocka.wrap: -------------------------------------------------------------------------------- 1 | [wrap-file] 2 | directory = cmocka-1.1.5 3 | source_url = https://cmocka.org/files/1.1/cmocka-1.1.5.tar.xz 4 | source_filename = cmocka-1.1.5.tar.xz 5 | source_hash = f0ccd8242d55e2fd74b16ba518359151f6f8383ff8aef4976e48393f77bba8b6 6 | patch_filename = cmocka_1.1.5-5_patch.zip 7 | patch_url = https://wrapdb.mesonbuild.com/v2/cmocka_1.1.5-5/get_patch 8 | patch_hash = e380083690849bb1abf231c42c684ec39a2dd1180c42d348b672ae6924b188d0 9 | wrapdb_version = 1.1.5-5 10 | 11 | [provide] 12 | cmocka = cmocka_dep 13 | -------------------------------------------------------------------------------- /src/core/rtos/rtos.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "rtos.hpp" 5 | 6 | using namespace embvm; 7 | 8 | VirtualThread::~VirtualThread() noexcept = default; 9 | 10 | VirtualSemaphore::~VirtualSemaphore() noexcept = default; 11 | 12 | VirtualMutex::~VirtualMutex() noexcept = default; 13 | 14 | VirtualEventFlag::~VirtualEventFlag() noexcept = default; 15 | 16 | VirtualConditionVariable::~VirtualConditionVariable() noexcept = default; 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pdf filter=lfs diff=lfs merge=lfs -text 2 | *.jpg filter=lfs diff=lfs merge=lfs -text 3 | *.png filter=lfs diff=lfs merge=lfs -text 4 | *.xlsx filter=lfs diff=lfs merge=lfs -text 5 | *.docx filter=lfs diff=lfs merge=lfs -text 6 | *.zip filter=lfs diff=lfs merge=lfs -text 7 | *.tar filter=lfs diff=lfs merge=lfs -text 8 | *.tgz filter=lfs diff=lfs merge=lfs -text 9 | *.bz2 filter=lfs diff=lfs merge=lfs -text 10 | *.out filter=lfs diff=lfs merge=lfs -text 11 | *.hex filter=lfs diff=lfs merge=lfs -text 12 | *.bin filter=lfs diff=lfs merge=lfs -text 13 | -------------------------------------------------------------------------------- /src/utilities/math/rounded_div.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef ROUNDED_DIV_H_ 5 | #define ROUNDED_DIV_H_ 6 | 7 | /**@brief Macro for performing rounded integer division (as opposed to truncating the result). 8 | * 9 | * @param[in] A Numerator. 10 | * @param[in] B Denominator. 11 | * 12 | * @return Rounded (integer) result of dividing A by B. 13 | */ 14 | #define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) 15 | 16 | #endif // ROUNDED_DIV_H_ 17 | -------------------------------------------------------------------------------- /templates/hw_platform/meson.build: -------------------------------------------------------------------------------- 1 | # Template Hardware Platform Build Definition 2 | 3 | # This dependency is meant to be used by platforms built using this HW 4 | template_hw_platform_dep = declare_dependency( 5 | include_directories: include_directories('.'), 6 | sources: [ 7 | files('template_hw_platform.cpp') 8 | ], 9 | dependencies: [ 10 | # Put build dependencies for your processor and drivers here 11 | ] 12 | ) 13 | 14 | catch2_tests_dep += declare_dependency( 15 | sources: files('template_hw_platform_tests.cpp'), 16 | dependencies: template_hw_platform_dep 17 | ) 18 | -------------------------------------------------------------------------------- /templates/platform/platform_os_options.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_PLATFORM_OS_OPTIONS_HPP_ 2 | #define TEMPLATE_PLATFORM_OS_OPTIONS_HPP_ 3 | 4 | // This file can be left blank if you are not using an OS. 5 | 6 | /** Checklist for new platforms: 7 | * - [ ] Rename TEMPLATE_PLATFORM_OS_OPTIONS_HPP_ to something different 8 | * - [ ] Update pool size definitions for your platform 9 | */ 10 | 11 | #define OS_THREAD_POOL_SIZE 4 12 | #define OS_MUTEX_POOL_SIZE 4 13 | #define OS_SEMAPHORE_POOL_SIZE 4 14 | #define OS_EVENT_FLAG_POOL_SIZE 4 15 | 16 | #endif // TEMPLATE_PLATFORM_OS_OPTIONS_HPP_ 17 | -------------------------------------------------------------------------------- /src/drivers/simulator/meson.build: -------------------------------------------------------------------------------- 1 | # Simulator Driver Build Definitions 2 | 3 | simulator_driver_files = files( 4 | 'system_clock.cpp', 5 | 'timer.cpp' 6 | ) 7 | 8 | simulator_driver_dep = declare_dependency( 9 | sources: simulator_driver_files, 10 | include_directories: driver_include_root 11 | ) 12 | 13 | simulator_driver_test_files = files( 14 | 'timer_tests.cpp', 15 | ) 16 | 17 | ###################### 18 | # Supporting Tooling # 19 | ###################### 20 | clangtidy_files += files('system_clock.cpp', 'timer.cpp') 21 | catch2_tests_dep += declare_dependency( 22 | sources: simulator_driver_test_files 23 | ) 24 | -------------------------------------------------------------------------------- /templates/processor_arch/template_processor_arch.cpp: -------------------------------------------------------------------------------- 1 | #include "template_processor_arch.hpp" 2 | // Possiblly include: 3 | // #include // Processor-specific include that contains headers/defines 4 | 5 | void TemplateProcessorArch::interruptsEnable_() noexcept {} 6 | 7 | void TemplateProcessorArch::interruptsDisable_() noexcept {} 8 | 9 | void TemplateProcessorArch::memoryBarrier_() noexcept {} 10 | 11 | void TemplateProcessorArch::instructionBarrier_() noexcept {} 12 | 13 | void TemplateProcessorArch::systemReset() noexcept {} 14 | 15 | void TemplateProcessorArch::sysTickConfig(uint32_t ticks) noexcept {} 16 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0001-record-architecture-decisions.md: -------------------------------------------------------------------------------- 1 | # 1. Record architecture decisions 2 | 3 | Date: 2018-06-19 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We need to record the architectural decisions made on this project. 12 | 13 | ## Decision 14 | 15 | We will use Architecture Decision Records, as described by Michael Nygard in this article: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions 16 | 17 | ## Consequences 18 | 19 | See Michael Nygard's article, linked above. For a lightweight ADR toolset, see Nat Pryce's [_adr-tools_](https://github.com/npryce/adr-tools). 20 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/configuration.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Configuration Subsystem 2 | 3 | AKA KV-Store 4 | 5 | ## Responsibilities 6 | 7 | TBD 8 | 9 | ## Requirements 10 | 11 | TBD 12 | 13 | ## Collaborators 14 | 15 | TBD 16 | 17 | ## Rationale 18 | 19 | TBD 20 | 21 | ## Source Links 22 | 23 | TBD 24 | 25 | ## Notes 26 | 27 | Two models: 28 | 29 | * RAM-Based KV store 30 | * Resets every boot, but you can change default parameters for testing 31 | * Flash-based KV store 32 | * Permanent changes until re-flashed 33 | 34 | Something most projects need: 35 | * persistent KV storage with nvram/flash 36 | * definitely an add-on module 37 | -------------------------------------------------------------------------------- /docs/patterns/traits_class.md: -------------------------------------------------------------------------------- 1 | # Pattern: Traits Class 2 | 3 | TBD 4 | 5 | ## Diagrams 6 | 7 | TBD 8 | 9 | ## Context 10 | 11 | TBD 12 | 13 | ## Problem 14 | 15 | TBD 16 | 17 | ## Solution 18 | 19 | TBD 20 | 21 | ## Consequences 22 | 23 | TBD 24 | 25 | ## Known Uses 26 | 27 | TBD 28 | 29 | ## Variants 30 | 31 | TBD 32 | 33 | ## Related Patterns 34 | 35 | TBD 36 | 37 | ## References 38 | 39 | TBD 40 | 41 | ## Notes 42 | 43 | In C++ one has a limited ability to make decisions or generate code at compile time at no run-time cost using so called templates. A traits class is a design pattern which allows the injection of a zero cost customization point 44 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/adding_new_driver_type.md: -------------------------------------------------------------------------------- 1 | # Adding a New Driver Type 2 | 3 | * Inherit from embvm::DriverBase 4 | * Define a new driver type (in your own type enum, or in the base framework enum) 5 | * Create constructors which pass that type to base 6 | * Define pure virtual interfaces, types, and non-virtual interfaces which your category will support 7 | * Create a static constexpr type() functionw hich returns your new embvm::DriverType ID 8 | 9 | ``` 10 | static constexpr embvm::DriverType type() 11 | { 12 | return embvm::DriverType::SPI; 13 | } 14 | ``` 15 | 16 | * Create a unit test driver for your virtual base 17 | * Write unit tests for your virtual base 18 | -------------------------------------------------------------------------------- /src/subsystems/logging/log.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef LOG_LIB_H_ 5 | #define LOG_LIB_H_ 6 | 7 | #include "_log_common_defs.h" 8 | 9 | /** C log buffer container 10 | * 11 | * This is the definition of a circular log buffer for C programs. 12 | * 13 | * @ingroup FrameworkLogging 14 | */ 15 | typedef struct 16 | { 17 | /// The pointer to the buffer representing the log. 18 | char* buf; 19 | /// The insertion index of the next log statement. 20 | uint32_t head; 21 | /// Size of the log buffer. 22 | uint32_t size; 23 | } log_buffer_t; 24 | 25 | #endif // LOG_LIB_H_ 26 | -------------------------------------------------------------------------------- /templates/os/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for Template HW platform 2 | 3 | # To get this into the build, go up one level in the directory tree and add 4 | # a `subdir(your_hw_platform_dir)` command to the subdir group 5 | 6 | # This dependency is meant to be used by platforms built using this HW 7 | template_hw_platform_dep = declare_dependency( 8 | include_directories: include_directories('.'), 9 | sources: [files('template_hw_platform.cpp')], 10 | dependencies: [ 11 | # Put build dependencies for your processor and drivers here 12 | ] 13 | ) 14 | 15 | # This should be added to the containing build file's test file list 16 | template_hw_platform_test_files = files('template_hw_platform_tests.cpp') 17 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0012-switch-to-catch-for-unit-testing.md: -------------------------------------------------------------------------------- 1 | # 12. Switch to Catch for Unit Testing 2 | 3 | Date: 2018-09-08 4 | 5 | ## Status 6 | 7 | Proposed 8 | 9 | ## Context 10 | 11 | We started unit testing with doctest. However, when trying to compile with exceptions disabled, it seems to be a problem. 12 | 13 | Catch provides support for compiling with -fno-exceptions, and even lets us configure the termination handler. 14 | 15 | ## Decision 16 | 17 | We're proposing to use Catch for unit testing. But we need to actually try it out firs.t 18 | 19 | ## Consequences 20 | 21 | Tests cannot be written in headers when using Catch. This is minor - we'll keep tests in a separate file anyway. 22 | -------------------------------------------------------------------------------- /docs/templates/glossary.md: -------------------------------------------------------------------------------- 1 | # Project Glossary 2 | 3 | [0-9](#0-9) | [A](#a) | [B](#b) | [C](#c) | [D](#d) | [E](#e) | [F](#f) | [G](#g) | [H](#h) | [I](#i) | [J](#j) | [K](#k) | [L](#l) | [M](#m) | [N](#n) | [O](#o) | [P](#p) | [Q](#q) | [R](#r) | [S](#s) | [T](#t) | [U](#u) | [V](#v) | [W](#w) | [X](#x) | [Y](#y) | [Z](#z) 4 | 5 | # 0-9 6 | 7 | # A 8 | 9 | # B 10 | 11 | # C 12 | 13 | # D 14 | 15 | # E 16 | 17 | # F 18 | 19 | # G 20 | 21 | # H 22 | 23 | # I 24 | 25 | # J 26 | 27 | # K 28 | 29 | # L 30 | 31 | # M 32 | 33 | # N 34 | 35 | # O 36 | 37 | # P 38 | 39 | # Q 40 | 41 | # R 42 | 43 | # S 44 | 45 | # T 46 | 47 | # U 48 | 49 | # V 50 | 51 | # W 52 | 53 | # X 54 | 55 | # Y 56 | 57 | # Z 58 | -------------------------------------------------------------------------------- /src/utilities/volatile/volatile_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "volatile.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | 9 | TEST_CASE("Load/store non-volatile", "[utilities/volatile]") 10 | { 11 | uint8_t t = 0; 12 | auto x = volatile_load(&t); 13 | CHECK(x == t); 14 | x++; 15 | volatile_store(&t, x); 16 | CHECK(t == 1); 17 | } 18 | 19 | TEST_CASE("Load/store volatile", "[utilities/volatile]") 20 | { 21 | volatile uint8_t t = 0; 22 | auto x = volatile_load(&t); 23 | CHECK(x == t); 24 | x++; 25 | volatile_store(&t, x); 26 | CHECK(t == 1); 27 | } 28 | -------------------------------------------------------------------------------- /templates/platform/hw_platform_options.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_HW_PLATFORM_OPTIONS_HPP 2 | #define TEMPLATE_HW_PLATFORM_OPTIONS_HPP 3 | 4 | #include 5 | 6 | /** Checklist for new platforms: 7 | * - [ ] Rename TEMPLATE_HW_PLATFORM_OPTIONS_HPP to something different 8 | * - [ ] Supply the proper driver registry definition 9 | * - [ ] Specify any other hardware platform configuration options in this file 10 | */ 11 | 12 | // Select a driver registry type. Keep the PlatformDriverRegistry name the same. 13 | // using PlatformDriverRegistry = embvm::DynamicDriverRegistry; 14 | // using PlatformDriverRegistry = embvm::StaticDriverRegistry<8>; 15 | 16 | #endif // TEMPLATE_HW_PLATFORM_OPTIONS_HPP 17 | -------------------------------------------------------------------------------- /templates/processor/internal/processor_architecture.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_PROCESSOR_ARCH_DEF_HPP_ 2 | #define TEMPLATE_PROCESSOR_ARCH_DEF_HPP_ 3 | 4 | /** Checklist for new processor bringup: 5 | * 6 | * - [ ] Rename TEMPLATE_PROCESSOR_ARCH_DEF_HPP_ to something different 7 | * - If your processor will leverage functionality from an arch class: 8 | * - [ ] Include the proper header 9 | * - [ ] Specify the class name in the using statement 10 | */ 11 | 12 | // Include the proper arch for this processor: 13 | // #include 14 | 15 | // And add the class definition here. Don't change the ProcessorArch name. 16 | // using ProcessorArch = ARMCortexMArch; 17 | 18 | #endif // TEMPLATE_PROCESSOR_ARCH_DEF_HPP_ 19 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/optimization.md: -------------------------------------------------------------------------------- 1 | # Framework Application Optimization 2 | 3 | **Table of Contents:** 4 | 1. [Configuration Options](#configuration-options) 5 | 2. [Reducing Binary Size](#reducing-binary-size) 6 | 7 | ## Configuration Options 8 | 9 | ## Reducing Binary Size 10 | 11 | * Disable RTTI (disabled by default for framework applications) 12 | 13 | ### Debugging Options 14 | 15 | If `printf` is not needed, you can eliminate it from your application for significant savings. Other tips to remove `printf`: 16 | 17 | * Disable `always-enable-assert` (meson configuration option), because that will force `printf` usage with `assert()` calls. 18 | * Eliminate all logging (`printf` usage) 19 | * Eliminate all other `printf` calls 20 | -------------------------------------------------------------------------------- /templates/driver/led.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_LED_DRIVER_HPP_ 2 | #define TEMPLATE_LED_DRIVER_HPP_ 3 | 4 | #include 5 | 6 | namespace embdrv 7 | { 8 | /** document class here 9 | */ 10 | class TemplateLEDDriver final : public embvm::led::base 11 | { 12 | public: 13 | TemplateLEDDriver() noexcept : embvm::led::base("Template LED") {} 14 | 15 | explicit TemplateLEDDriver(const char* name) noexcept : embvm::led::base(name) {} 16 | 17 | ~TemplateLEDDriver() noexcept final; 18 | 19 | void on() noexcept final; 20 | void off() noexcept final; 21 | void toggle() noexcept final; 22 | 23 | private: 24 | void start_() noexcept final; 25 | void stop_() noexcept final; 26 | }; 27 | } // namespace embdrv 28 | 29 | #endif // TEMPLATE_LED_DRIVER_HPP_ 30 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/parametric_logging.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Parametric Logging 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | Saket said this was something they skipped up front. When they finally implemented it, there was a significant time delay. 26 | 27 | Logging from the beginning: 28 | 29 | * log sensor / function calls 30 | * Make available to external service somehow (API to get data) 31 | * Would be nice if this was sync'd together with a data parsing service 32 | * E.g. define events, add "update" points. The framework then handles counts & frequencies & averages. 33 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0015-use-embvm-top-level-namespace-for-core-interfaces.md: -------------------------------------------------------------------------------- 1 | # 15. Use embvm top level namespace for core interfaces 2 | 3 | Date: 2019-02-20 4 | 5 | ## Status 6 | 7 | Proposed 8 | 9 | ## Context 10 | 11 | All of the framework code was placed into the global namespace. We need to find a home to group our code in. 12 | 13 | ## Decision 14 | 15 | The `embvm` (Embedded Virtual Machine) namespace will be used for framework constructs. 16 | 17 | ## Consequences 18 | 19 | Framework core will need to be updated so they are grouped in the `embvm` top-level namespace. This includes everything in the `src/core/` directory. 20 | 21 | There are likely second-level namespaces used, so developers will be burdened with remembering these details. 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/interrupts.md: -------------------------------------------------------------------------------- 1 | # Interrupt Guidelines 2 | 3 | Most bare-metal embedded products require two modes of operation: 4 | 5 | * Interrupt (or service) mode 6 | * Non-interrupt (or user) mode. 7 | 8 | The job of the code executed in interrupt mode is to respond to hardware events (interrupts) by performing minimal job of updating various status registers and schedule proper handling of event (if applicable) to be executed in non-interrupt mode. 9 | 10 | In most projects the interrupt handlers are not prioritised, and the next hardware event (interrupt) won't be handled until the previously called interrupt handler returns, i.e., CPU is ready to return to non-interrupt mode. 11 | 12 | To reduce latency, it is important for the interrupt handler is as minimal as possible. 13 | -------------------------------------------------------------------------------- /src/core/driver/clock.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef CLOCK_HPP_ 5 | #define CLOCK_HPP_ 6 | 7 | #include 8 | 9 | namespace embvm 10 | { 11 | /// @addtogroup FrameworkDriver 12 | /// @{ 13 | 14 | /// Definitions, functions, and classes related to clock devices. 15 | namespace clk 16 | { 17 | /// Represents the frequency of the clock, in Hz. 18 | using freq_hz_t = std::chrono::duration>; 19 | 20 | /// Represents the period of the clock, in nanoseconds. 21 | using clock_period_t = std::chrono::duration; 22 | } // namespace clk 23 | 24 | /// @} 25 | // End group 26 | 27 | } // namespace embvm 28 | 29 | #endif // CLOCK_HPP_ 30 | -------------------------------------------------------------------------------- /src/os/posix/meson.build: -------------------------------------------------------------------------------- 1 | # Posix OS Build Files 2 | 3 | posix_os_files = files( 4 | 'posix_os.cpp', 5 | 'libcpp_threading.cpp', 6 | ) 7 | 8 | posix_test_files = files( 9 | 'posix_tests.cpp', 10 | ) 11 | 12 | posix_dep = dependency('threads') 13 | posix_os_link_args = [] 14 | 15 | if (build_machine.system() == 'linux') 16 | posix_os_link_args += ['-lrt', '-lpthread'] 17 | endif 18 | 19 | posix_os_dep = declare_dependency( 20 | include_directories: include_directories('.'), 21 | sources: posix_os_files, 22 | link_args: posix_os_link_args, 23 | dependencies:[ 24 | posix_dep, 25 | framework_include_dep 26 | ] 27 | ) 28 | 29 | ###################### 30 | # Supporting Tooling # 31 | ###################### 32 | 33 | catch2_tests_dep += declare_dependency( 34 | sources: posix_test_files 35 | ) 36 | -------------------------------------------------------------------------------- /templates/processor/internal/processor_includes.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_PROCESSOR_INCLUDES_HPP_ 2 | #define TEMPLATE_PROCESSOR_INCLUDES_HPP_ 3 | 4 | /* Purpose: 5 | * This processor header can be used by internal-facing files to include all relevant processor 6 | * headers supplied by a processor vendor, SDK, etc. The idea is that the headers in this file 7 | * should not be exposed to the rest of the framework. Keep them contained and use this header 8 | * within processor .cpp files. 9 | */ 10 | 11 | /** Checklist for new processor bring up: 12 | * 13 | * - [ ] Rename TEMPLATE_PROCESSOR_INCLUDES_HPP_ to something else 14 | * - [ ] Add any processor-specific includes here that may be needed for internal modules (drivers, 15 | * etc.) 16 | */ 17 | 18 | #endif // TEMPLATE_PROCESSOR_INCLUDES_HPP_ 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/FEATURE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Use this template for requesting new features 4 | title: "[FEATURE NAME]" 5 | labels: enhancement 6 | assignees: phillipjohnston 7 | --- 8 | 9 | ## Expected Behavior 10 | 11 | Please describe the behavior you are expecting 12 | 13 | ## Current Behavior 14 | 15 | What is the current behavior? 16 | 17 | ## Sample Code 18 | 19 | If applicable, provide a sample code snippet that demonstrates the gist of feature you're proposing. This can be either from a usage standpoint, or an implementation standpoint. 20 | 21 | ## Context 22 | 23 | Please provide any relevant information about your setup, which will help us ensure the requested support will work for you. 24 | 25 | * Project Version: 26 | * Operating System: 27 | * Toolchain version: 28 | -------------------------------------------------------------------------------- /templates/driver/system_clock.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_SYSTEM_CLOCK_HPP_ 2 | #define TEMPLATE_SYSTEM_CLOCK_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace embdrv 9 | { 10 | /** Document class here 11 | */ 12 | class TemplateSystemClock final : public embvm::clk::SystemClock 13 | { 14 | public: 15 | TemplateSystemClock() noexcept; 16 | 17 | ~TemplateSystemClock() noexcept final; 18 | 19 | embvm::clk::freq_hz_t::rep frequency() const noexcept final; 20 | 21 | tick_duration_t::rep ticks() const noexcept final; 22 | 23 | void spin(spin_duration_t::rep count) noexcept final; 24 | 25 | protected: 26 | void start_() noexcept final; 27 | void stop_() noexcept final; 28 | }; 29 | 30 | } // namespace embdrv 31 | 32 | #endif // TEMPLATE_SYSTEM_CLOCK_HPP_ 33 | -------------------------------------------------------------------------------- /test/meson.build: -------------------------------------------------------------------------------- 1 | # Specify Settings for Embedded VM Core Test Build 2 | embvm_test_dep = declare_dependency( 3 | compile_args: [ 4 | #'-DCATCH_CONFIG_DISABLE', 5 | '-DCATCH_CONFIG_FAST_COMPILE', 6 | '-DCATCH_CONFIG_NO_WCHAR', 7 | '-DCATCH_CONFIG_NO_POSIX_SIGNALS', 8 | '-DCATCH_CONFIG_DISABLE_MATCHERS', 9 | '-DMSE_DISABLE_IOSTREAM', 10 | '-DMSE_SCOPEPOINTER_DEBUG_RUNTIME_CHECKS_DISABLED', 11 | '-fexceptions', 12 | '-funwind-tables', 13 | ], 14 | sources: files('putchar.c'), 15 | # TODO: use dependencies to simplify all of this linker stuff 16 | link_with: [ 17 | libcore_hosted_native, 18 | libutil_native 19 | ], 20 | dependencies: [ 21 | unit_test_platform_dep, 22 | printf_dep, 23 | libmemory_hosted_native_dep, 24 | framework_include_dep 25 | ], 26 | ) 27 | 28 | catch2_tests_dep += embvm_test_dep 29 | -------------------------------------------------------------------------------- /src/drivers/unit_test/gpio.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "gpio.hpp" 5 | 6 | using namespace test; 7 | 8 | void UnitTestGPIO::start_() noexcept {} 9 | 10 | void UnitTestGPIO::stop_() noexcept {} 11 | 12 | #pragma mark - GPIO With Pullup - 13 | 14 | bool UnitTestGPIO::get() noexcept 15 | { 16 | return value_; // This is only really valid for testing 17 | } 18 | 19 | void UnitTestGPIO::set(bool v) noexcept 20 | { 21 | value_ = v; 22 | } 23 | 24 | void UnitTestGPIO::toggle() noexcept 25 | { 26 | value_ = !value_; 27 | } 28 | 29 | void UnitTestGPIO::setMode(embvm::gpio::mode mode) noexcept 30 | { 31 | mode_ = mode; 32 | } 33 | 34 | embvm::gpio::mode UnitTestGPIO::mode() noexcept 35 | { 36 | return mode_; 37 | } 38 | -------------------------------------------------------------------------------- /templates/processor_arch/template_processor_arch.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_ARCHITECTURE_HPP_ 2 | #define TEMPLATE_ARCHITECTURE_HPP_ 3 | 4 | #include 5 | 6 | /** TODO for new arch: 7 | * 8 | * - Rename class 9 | * - Rename TEMPLATE_ARCHITECTURE_HPP_ to something else 10 | * - Rename class in template_processor_arch.cpp 11 | */ 12 | 13 | class TemplateProcessorArch : public embvm::VirtualProcessorArchBase 14 | { 15 | public: 16 | #pragma mark - Specific Arch Functions - 17 | 18 | #pragma mark - Common Arch Functions - 19 | static void interruptsEnable_() noexcept; 20 | 21 | static void interruptsDisable_() noexcept; 22 | 23 | static void memoryBarrier_() noexcept; 24 | 25 | static void instructionBarrier_() noexcept; 26 | }; 27 | 28 | #endif // TEMPLATE_ARCHITECTURE_HPP_ 29 | -------------------------------------------------------------------------------- /src/processors/simulator/simulator_processor.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "simulator_processor.hpp" 5 | #include 6 | 7 | #pragma mark - Definitions - 8 | 9 | extern volatile bool abort_program_; 10 | 11 | #pragma mark - Helpers - 12 | 13 | // This enables graceful termination of our program using CTRL+C 14 | // We put it in this file because only the sim platform variant supports std::signal 15 | namespace 16 | { 17 | void signal_handler(int signal) 18 | { 19 | (void)signal; 20 | abort_program_ = true; 21 | } 22 | } // namespace 23 | 24 | #pragma mark - Class Functions - 25 | 26 | void SimulatorProcessor::init_() 27 | { 28 | std::signal(SIGINT, signal_handler); 29 | std::signal(SIGTERM, signal_handler); 30 | } 31 | -------------------------------------------------------------------------------- /src/utilities/bounce/bounce_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "bounce.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | 9 | namespace 10 | { 11 | using func_t = void (*)(void*); 12 | 13 | void call_bounce(func_t b, void* priv) 14 | { 15 | b(priv); 16 | } 17 | 18 | class test 19 | { 20 | public: 21 | void callback() 22 | { 23 | callback_called_ = true; 24 | } 25 | 26 | bool called() 27 | { 28 | return callback_called_; 29 | } 30 | 31 | private: 32 | bool callback_called_ = false; 33 | }; 34 | 35 | } // namespace 36 | 37 | TEST_CASE("Bounce", "[utilities/bounce]") 38 | { 39 | test inst; 40 | call_bounce(BOUNCE(test, callback), &inst); 41 | CHECK(inst.called()); 42 | } 43 | -------------------------------------------------------------------------------- /docs/templates/architecture/user_story.md: -------------------------------------------------------------------------------- 1 | # User Story: Template 2 | 3 | * Name: Story, epic, or group name (replace template) 4 | * Category: Story | Epic | Group 5 | * Reference Number: Optional ID 6 | 7 | **Table of Contents:** 8 | * [Story List](#story-list) 9 | * [Acceptance Criteria](#acceptance-criteria) 10 | * [Associated Mechanisms](#associated-mechanisms) 11 | * [Comments](#comments) 12 | 13 | ## Story List 14 | 15 | You can have a list of stories or epics: 16 | 17 | * As a , I want so that 18 | * As a bank customer, I want to draw case so that I have cash on hand (for tips, etc.) 19 | * As a user, I can backup my entire hard drive. 20 | 21 | ## Acceptance Criteria 22 | 23 | ## Associated Mechanisms 24 | 25 | * What architectural mechanisms are associated with these user stories? 26 | 27 | ## Comments 28 | -------------------------------------------------------------------------------- /src/processors/simulator/simulator_processor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef SIMULATOR_PROCESSOR_HPP_ 5 | #define SIMULATOR_PROCESSOR_HPP_ 6 | 7 | #include 8 | 9 | class SimulatorProcessor : public embvm::VirtualProcessorBase 10 | { 11 | using ProcessorBase = embvm::VirtualProcessorBase; 12 | 13 | public: 14 | /// @brief Default constructor. 15 | SimulatorProcessor() noexcept = default; 16 | 17 | /// @brief Default destructor. 18 | ~SimulatorProcessor() noexcept = default; 19 | 20 | #pragma mark - Inherited Functions - 21 | 22 | static void earlyInitHook_() {} 23 | 24 | void init_(); 25 | 26 | void reset_() {} 27 | }; 28 | 29 | #endif // SIMULATOR_PROCESSOR_HPP_ 30 | -------------------------------------------------------------------------------- /templates/processor_arch/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for Template Processor Architecture 2 | 3 | # To get this into the build, go up one level in the directory tree and add 4 | # a `subdir(your_hw_platform_dir)` command to the subdir group 5 | 6 | # Architectures should be typically build as dependencies and added into the processor dependency 7 | # list. Because the processor is compiled as a library, it's ok to pollute include paths if needed 8 | # to compile the .cpp file. 9 | 10 | # This dependency is meant to be added to the processor 11 | template_arch_dep = declare_dependency( 12 | include_directories: include_directories('.'), 13 | sources: files( 14 | 'template_processor_arch.cpp', 15 | ) 16 | ) 17 | 18 | # This should be added to the containing build file's test file list 19 | template_arch_test_files = files('template_processor_arch_tests.cpp') 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Expected Behavior 2 | 3 | Please describe the behavior you are expecting 4 | 5 | # Current Behavior 6 | 7 | What is the current behavior? 8 | 9 | # Failure Information (for bugs) 10 | 11 | Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template. 12 | 13 | ## Steps to Reproduce 14 | 15 | Please provide detailed steps for reproducing the issue. 16 | 17 | 1. step 1 18 | 2. step 2 19 | 3. you get it... 20 | 21 | ## Context 22 | 23 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions. 24 | 25 | * Firmware Version: 26 | * Operating System: 27 | * SDK version: 28 | * Toolchain version: 29 | 30 | ## Failure Logs 31 | 32 | Please include any relevant log snippets or files here. 33 | -------------------------------------------------------------------------------- /templates/platform/platform_logger.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_PLATFORM_LOGGER_HPP_ 2 | #define TEMPLATE_PLATFORM_LOGGER_HPP_ 3 | 4 | /** New Platform bring-up checklist: 5 | * - [ ] Select a logger declaration, or leave this empty for no logging 6 | * - [ ] Add a lock if needed 7 | * - [ ] Rename TEMPLATE_PLATFORM_LOGGER_HPP_ to something else 8 | */ 9 | 10 | // Include the logger header for your desired strategy 11 | // #include 12 | // Include the proper if you need a lock, for e.g.: 13 | // #include 14 | 15 | // Keep the name "PlatformLogger" the same but fill in the desired strategy for your logger 16 | // In this example, we set up a 4 kB circular log buffer. 17 | // using PlatformLogger = 18 | // embvm::PlatformLogger_t>; 19 | 20 | #endif // TEMPLATE_PLATFORM_LOGGER_HPP_ 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. 4 | 5 | Fixes # (issue) 6 | 7 | # How Has This Been Tested? 8 | 9 | Please describe the tests that you ran to verify your changes. Please also note any relevant details for your test configuration. 10 | 11 | - [ ] Test A 12 | - [ ] Test B 13 | 14 | # Checklist: 15 | 16 | - [ ] My code follows the style guidelines of this project 17 | - [ ] I have performed a self-review of my own code 18 | - [ ] I have commented my code, particularly in hard-to-understand areas 19 | - [ ] I have made corresponding changes to the documentation 20 | - [ ] My changes generate no new warnings 21 | - [ ] Any dependent changes have been merged and published in downstream modules 22 | -------------------------------------------------------------------------------- /src/drivers/unit_test/driver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef UNIT_TEST_DRIVER_H_ 5 | #define UNIT_TEST_DRIVER_H_ 6 | 7 | #include 8 | 9 | namespace test 10 | { 11 | /** Test driver that enables testing DriverBase 12 | * 13 | * @ingroup TestDrivers 14 | */ 15 | class TestDriverBase final : public embvm::DriverBase 16 | { 17 | public: 18 | /** Create a driver base 19 | * 20 | * @param c The type of the driver base 21 | */ 22 | TestDriverBase(uint32_t c = embvm::DriverType::Undefined) noexcept : DriverBase(c) {} 23 | 24 | /// Default destructor 25 | ~TestDriverBase() noexcept; 26 | 27 | private: 28 | void start_() noexcept final; 29 | void stop_() noexcept final; 30 | }; 31 | 32 | } // namespace test 33 | 34 | #endif // UNIT_TEST_DRIVER_H_ 35 | -------------------------------------------------------------------------------- /templates/platform/meson.build: -------------------------------------------------------------------------------- 1 | # Template Platform Build Defintion 2 | 3 | template_platform_inc = include_directories('.') 4 | 5 | template_platform_dep = declare_dependency( 6 | sources: files('platform.cpp'), 7 | include_directories: template_platform_inc, 8 | dependencies: [ 9 | template_hw_platform_dep, 10 | # Add any OS-related dependencies here 11 | framework_dep 12 | # Alternatives: 13 | # framework_threadless_dep 14 | # framework_native_dep 15 | # framework_threadless_native_dep 16 | ], 17 | link_args: [ 18 | # Linker script placeholder: 19 | #'-L' + meson.current_source_dir(), 20 | #'-Tskeleton_linker_script.ld', 21 | ], 22 | ) 23 | 24 | catch2_tests_dep += declare_dependency( 25 | sources: files('platform_tests.cpp'), 26 | dependencies: template_platform_dep 27 | ) 28 | -------------------------------------------------------------------------------- /templates/processor/template_processor.cpp: -------------------------------------------------------------------------------- 1 | #include "template_processor.hpp" 2 | #include 3 | #include 4 | 5 | #pragma mark - Definitions - 6 | 7 | #pragma mark - Helpers - 8 | 9 | #pragma mark - Interface Functions - 10 | 11 | TemplateProcessor::~TemplateProcessor() {} 12 | 13 | void TemplateProcessor::init_() noexcept 14 | { 15 | // What needs to be happen to configure and initialize the processor? 16 | // This should be common to all uses of the processor across all HW platforms 17 | } 18 | 19 | void TemplateProcessor::reset_() noexcept 20 | { 21 | // Example for ARM: defer to the arch 22 | // ProcessorArch::systemReset(); 23 | } 24 | 25 | void TemplateProcessor::earlyInitHook_() noexcept 26 | { 27 | // Should anything happen for this processor before we initialize the 28 | // system? 29 | // For example, configuring the MMU 30 | } 31 | -------------------------------------------------------------------------------- /src/os/namespace_documentation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | /// Operating system types and definitions 5 | namespace os 6 | { 7 | /** @defgroup FrameworkOSImpl Supported Framework Operating Systems 8 | * 9 | * Operating system impelmentations designed to work with the framework virtual machine. 10 | */ 11 | 12 | /// POSIX types and definitions for OSX and Linux 13 | namespace posix 14 | { 15 | /** @defgroup POSIXOS POSIX OS Types 16 | * 17 | * Virtual OS implementation for POSIX systems. 18 | * 19 | * @ingroup FrameworkOSImpl 20 | */ 21 | }; 22 | 23 | /// Unit test operating system 24 | namespace test 25 | { 26 | /** @defgroup UnitTestOS Unit Test OS types 27 | * 28 | * OS types used for unit testing. 29 | * 30 | * @ingroup FrameworkOSImpl 31 | */ 32 | }; 33 | 34 | } // namespace os 35 | -------------------------------------------------------------------------------- /templates/application/meson.build: -------------------------------------------------------------------------------- 1 | skeleton_application = executable('skeleton_application', 2 | files('main.cpp'), 3 | dependencies: [ 4 | skeleton_platform_dep, 5 | ], 6 | install: false, 7 | link_args: host_map_file.format(meson.current_build_dir() / 'skeleton_application'), 8 | build_by_default: meson.is_subproject() == false 9 | ) 10 | 11 | ############################# 12 | # Output Conversion Targets # 13 | ############################# 14 | 15 | blinky_hex = custom_target('skeleton_application.hex', 16 | input: skeleton_application, 17 | output: 'skeleton_application.hex', 18 | command: host_hex_conversion, 19 | build_by_default: meson.is_subproject() == false 20 | ) 21 | 22 | blinky_hex = custom_target('skeleton_application.bin', 23 | input: skeleton_application, 24 | output: 'skeleton_application.bin', 25 | command: host_bin_conversion, 26 | build_by_default: meson.is_subproject() == false 27 | ) 28 | 29 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0003-no-dynamic-memory-allocation-in-core.md: -------------------------------------------------------------------------------- 1 | # 3. No Dynamic Memory Allocation in Core 2 | 3 | Date: 2018-07-06 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | Many systems, teams, and designs require that the system will not utilize dynamic memory allocation. We should maintain a flexible design by allowing users to use dynamic memory allocation if they desire. However, we should be able to support the strictest operating model for maximum flexibility and potential use of the framework. 12 | 13 | ## Decision 14 | 15 | No dynamic memory allocation will be utilized by framework core components 16 | 17 | ## Consequences 18 | 19 | * Framework remains open for use by teams who will not allow dynamic memory allocation 20 | * Constructs which are provided by C/C++ but require dynamic memory allocation will need to be re-written with a static option (e.g., static_function, static_queue) 21 | -------------------------------------------------------------------------------- /src/drivers/namespace_documentation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | /// Embedded framework drivers 5 | namespace embdrv 6 | { 7 | /** @defgroup FrameworkDrivers Framework Drivers 8 | * 9 | * Drivers provided by the framework. 10 | */ 11 | 12 | /** @defgroup TestDrivers Unit Test Drivers 13 | * 14 | * Drivers intended for use with unit test code 15 | * 16 | * @ingroup FrameworkDrivers 17 | */ 18 | 19 | /** @defgroup SimulatorDrivers Simulator Drivers 20 | * 21 | * Drivers intended for use with simulator applications (run on host machine) 22 | * 23 | * @ingroup FrameworkDrivers 24 | */ 25 | 26 | /** @defgroup AardvarkDrivers Aardvark Adapter Drivers 27 | * 28 | * Aardvark Adapter drivers, usable for Simulator applications. 29 | * 30 | * @ingroup SimulatorDrivers 31 | */ 32 | 33 | } // namespace embdrv 34 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0020-hardware-platform-options-file.md: -------------------------------------------------------------------------------- 1 | # 20. Hardware Platform Options File 2 | 3 | Date: 2020-10-20 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | Caused by [18. Driver Registration in HW Platform](0018-driver-registration-in-hw-platform.md) 10 | 11 | ## Context 12 | 13 | The issue motivating this decision, and any context that influences or constrains the decision. 14 | 15 | ## Decision 16 | 17 | We will create a new required `hw_platform_options.hpp` file. This file is defined in the platform level, and can be used to configure any necessary compile-time parameters without the use of templates. 18 | 19 | ## Consequences 20 | 21 | - We cannot (easily) build the hardware platform into a library independently of the platform, so any includes that are used in the hardware platform can still be used at the platform level (but not the application level) 22 | + This may be solvable with some build magic. 23 | -------------------------------------------------------------------------------- /docs/architecture/scratchpad.md: -------------------------------------------------------------------------------- 1 | # Architecture Scratchpad 2 | 3 | These are collected notes and musings that are related to the framework architecture but don't have a proper home (yet). 4 | 5 | ## To Process 6 | 7 | * Most users aren't interested in customizing software they buy from a vendor. 8 | * Extensibility won't make up for a weak product. 9 | * You may think that you can design and implement a better component. That may be true, but unless your needs are extremely simple, your development cost will be much higher than the licensing cost. 10 | * A third-party component will usually be better designed and have fewer bugs than the one you develop. The component vendor is usually a specialist who has a long head-start on you. Other organizations are likely using the components it's likely that many of the bugs have already been fixed. Also, the vendor, not you, is responsible for fixing any bugs, saving you even more time and effort 11 | -------------------------------------------------------------------------------- /src/utilities/aligned_ptr/aligned_ptr_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "aligned_ptr.hpp" 5 | #include 6 | #include 7 | 8 | using namespace embutil; 9 | 10 | TEST_CASE("Unique aligned ptr", "[utilities/aligned_ptr]") 11 | { 12 | auto ptr = aligned_uptr(8, 1); 13 | auto ptr_raw = ptr.get(); 14 | CHECK(is_aligned(ptr_raw, 8)); 15 | 16 | auto ptr2 = aligned_uptr(16, 1); 17 | auto ptr2_raw = ptr2.get(); 18 | CHECK(is_aligned(ptr2_raw, 16)); 19 | } 20 | 21 | TEST_CASE("Shared aligned ptr", "[utilities/aligned_ptr]") 22 | { 23 | auto ptr = aligned_sptr(8, 1); 24 | auto ptr_raw = ptr.get(); 25 | CHECK(is_aligned(ptr_raw, 8)); 26 | 27 | auto ptr2 = aligned_sptr(16, 1); 28 | auto ptr2_raw = ptr2.get(); 29 | CHECK(is_aligned(ptr2_raw, 16)); 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated Files 2 | **/buildresults/** 3 | 4 | # Sublime-generated Files 5 | *.sublime-workspace 6 | 7 | # Meson subprojects 8 | subprojects/** 9 | !subprojects/*.wrap 10 | !subprojects/packagefiles/ 11 | !subprojects/packagefiles/*.tgz 12 | !subprojects/packagefiles/*.zip 13 | !subprojects/packagefiles/**/ 14 | !subprojects/packagefiles/**/meson.build 15 | 16 | # Ignore promoted wrap files 17 | subprojects/c-linked-list.wrap 18 | 19 | ######################## 20 | # C / C++ Ignore Rules # 21 | ######################## 22 | 23 | # Prerequisites 24 | *.d 25 | 26 | # Compiled Object files 27 | *.slo 28 | *.lo 29 | *.o 30 | *.obj 31 | 32 | # Precompiled Headers 33 | *.gch 34 | *.pch 35 | 36 | # Compiled Dynamic libraries 37 | *.so 38 | *.dylib 39 | *.dll 40 | 41 | # Fortran module files 42 | *.mod 43 | *.smod 44 | 45 | # Compiled Static libraries 46 | *.lai 47 | *.la 48 | *.a 49 | *.lib 50 | 51 | # Executables 52 | *.exe 53 | *.out 54 | *.app 55 | -------------------------------------------------------------------------------- /src/core/boot/boot_sequencer_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "boot_sequencer.hpp" 5 | #include 6 | #include 7 | 8 | /// Useful for things like Catch where we want to test things but we don't want 9 | /// to invoke the main() function twice 10 | template 11 | void DoNotCallMainBootStrategy() 12 | { 13 | TPlatform::earlyInitHook(); 14 | 15 | // Now that the runtime has been initialized + constructors called, we can 16 | // create our platform instance and initialize it 17 | TPlatform& platform = TPlatform::inst(); 18 | 19 | platform.initProcessor(); 20 | 21 | platform.initHWPlatform(); 22 | 23 | platform.init(); 24 | } 25 | 26 | TEST_CASE("Create Boot Sequencer", "[core/boot]") 27 | { 28 | embvm::BootSequencer>::boot(); 29 | } 30 | -------------------------------------------------------------------------------- /tools/WeeklyCI.jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | @Library('jenkins-pipeline-lib') _ 3 | 4 | pipeline 5 | { 6 | agent any 7 | triggers 8 | { 9 | //At 04:00 on Saturday 10 | pollSCM('H 4 * * 6') 11 | } 12 | stages 13 | { 14 | stage('Setup') 15 | { 16 | steps 17 | { 18 | echo 'Removing existing build results' 19 | sh 'make distclean' 20 | echo 'Updating subprojects' 21 | sh 'meson subprojects download' 22 | sh 'meson subprojects update --reset' 23 | } 24 | } 25 | stage('Coverage') 26 | { 27 | steps 28 | { 29 | sh 'make coverage' 30 | } 31 | post 32 | { 33 | success 34 | { 35 | cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: 'buildresults-coverage/meson-logs/coverage.xml', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /templates/processor/template_processor.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_PROCESSOR_HPP_ 2 | #define TEMPLATE_PROCESSOR_HPP_ 3 | 4 | #include 5 | 6 | /** TODO For new processors: 7 | * 8 | * - Rename the class in this file and the .cpp file 9 | * - Rename TEMPLATE_PROCESSOR_HPP_ to something else 10 | */ 11 | 12 | class TemplateProcessor : public embvm::VirtualProcessorBase 13 | { 14 | using ProcessorBase = embvm::VirtualProcessorBase; 15 | 16 | public: 17 | /// @brief Default constructor. 18 | TemplateProcessor() noexcept : ProcessorBase("Template Processor") {} 19 | 20 | /// @brief Default destructor. 21 | ~TemplateProcessor(); 22 | 23 | #pragma mark - Inherited Functions - 24 | 25 | static void earlyInitHook_() noexcept; 26 | 27 | void init_() noexcept; 28 | 29 | void reset_() noexcept; 30 | 31 | #pragma mark - Custom Functions - 32 | 33 | private: 34 | }; 35 | 36 | #endif // TEMPLATE_PROCESSOR_HPP_ 37 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0013-use-templates-to-switch-between-dynamic-and-static-memory.md: -------------------------------------------------------------------------------- 1 | # 13. Use Templates to Switch Between Dynamic & Static Constructs 2 | 3 | Date: 2018-11-30 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | We want to build the framework components to work with both dynamic and static memory allocation schemes. 12 | 13 | ## Decision 14 | 15 | Rather than duplicating implementations, we will use Template Metaprogramming to use a single structure which supports both static and dynamic memory allocation. Classes can be templated with a size parameter. This size is evaluated to determine the underlying data structure that will be used. If the size is equal to 0, dynamic memory is assumed. Otherwise, static memory allocation will be used. 16 | 17 | ## Consequences 18 | 19 | These modules become much more complicated to understand, as they rely on template metaprogramming. Many developers are leery of templates and have a hard time understanding the code. 20 | -------------------------------------------------------------------------------- /src/core/rtos/heap.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef RTOS_HEAP_HPP_ 5 | #define RTOS_HEAP_HPP_ 6 | 7 | #include 8 | #include 9 | 10 | namespace embvm 11 | { 12 | /// @addtogroup FrameworkOS 13 | /// @{ 14 | 15 | template 16 | class VirtualHeap 17 | { 18 | public: 19 | static void addBlock(void* addr, size_t size) noexcept 20 | { 21 | assert(addr && size); 22 | 23 | THeapImpl::addBlock(addr, size); 24 | } 25 | 26 | static void init() noexcept 27 | { 28 | THeapImpl::init(); 29 | } 30 | 31 | static void* alloc(size_t size) noexcept 32 | { 33 | return THeapImpl::alloc(size); 34 | } 35 | 36 | static void free(void* addr) noexcept 37 | { 38 | assert(addr); 39 | 40 | return THeapImpl::free(addr); 41 | } 42 | }; 43 | 44 | /// @} 45 | // End Group 46 | 47 | } // namespace embvm 48 | 49 | #endif // RTOS_HEAP_HPP_ 50 | -------------------------------------------------------------------------------- /docs/architecture/principles/0002-document_the_framework.md: -------------------------------------------------------------------------------- 1 | # Principle: Document the Framework 2 | 3 | **Name:** Document the Framework 4 | 5 | Document and show examples 6 | 7 | ## Description 8 | 9 | * Statement of the principle 10 | * Clearly state the chosen direction 11 | 12 | ## Rationale/Benefits 13 | 14 | * Describe the reasoning behind the principle 15 | * Where appicable, provide traceability to business or architectural objectives 16 | 17 | ## Implications 18 | 19 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 20 | 21 | ## Counterforces 22 | 23 | What forces will push against this principle? 24 | 25 | * Speed 26 | * schedule pressure 27 | * avoiding extreme changes 28 | * convenience 29 | * abstractions are not obvious or easy to find 30 | 31 | ## Counterarguments 32 | 33 | * Describe the reasonable counter to this principle 34 | 35 | ## Scope 36 | 37 | * (Optional) 38 | * Indicate teh scope where this principle needs ot be applied 39 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/version.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Version 2 | 3 | **Table of Contents:** 4 | 5 | 1. [Responsibilities](#responsibilities) 6 | 2. [Requirements](#requirements) 7 | 3. [Collaborators](#collaborators) 8 | 4. [Rationale](#rationale) 9 | 5. [Source Links](#source-links) 10 | 6. [Related Documents](#related-documents) 11 | 7. [Notes](#notes) 12 | 13 | ## Responsibilities 14 | 15 | * Report software version and build machine 16 | 17 | ## Requirements 18 | 19 | TBD 20 | 21 | ## Collaborators 22 | 23 | TBD 24 | 25 | ## Rationale 26 | 27 | Every software build needs a version for traceability purposes. Versions also help developers debug issues. 28 | 29 | ## Source Links 30 | 31 | TBD 32 | 33 | ## Related Documents 34 | 35 | TBD 36 | 37 | ## Notes 38 | 39 | Library? module? how does this fit in? 40 | 41 | Use git information, but generate version info at link-time: 42 | 43 | https://gitlab.com/wolframroesler/version 44 | https://embeddedartistry.com/blog/2016/10/27/giving-you-build-a-version 45 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/customizing_log_macros.md: -------------------------------------------------------------------------------- 1 | # Customizing Logging Macros 2 | 3 | The framework provides default log macro definitions in [log.hpp](../../../../src/subsystems/logging/log.hpp). 4 | 5 | The log macros can be overridden by defining them in your platform's `platform_logger.hpp` file. Any macros defined from the following list will override the framework default definition: 6 | 7 | * `logverbose` 8 | * `logdebug` 9 | * `loginfo` 10 | * `logwarn` 11 | * `logerror` 12 | * `logcritical` 13 | 14 | The only definition required in `platform_logger.hpp` is the macro itself: 15 | 16 | ``` 17 | #define logcritical(...) PlatformLogger::inst().log(logger::level::critical, __VA_ARGS__) 18 | ``` 19 | 20 | The framework will take care of compiling-out definitions according to the log level: 21 | 22 | ``` 23 | #if LOG_LEVEL >= LOG_LEVEL_CRITICAL 24 | #ifndef logcritical 25 | #define logcritical(...) PlatformLogger::inst().log(logger::level::critical, __VA_ARGS__) 26 | #endif 27 | #else 28 | #define logcritical(...) 29 | #endif 30 | ``` 31 | -------------------------------------------------------------------------------- /templates/driver/i2c.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_I2C_DRIVER_HPP_ 2 | #define TEMPLATE_I2C_DRIVER_HPP_ 3 | 4 | #include 5 | 6 | namespace embdrv 7 | { 8 | /** Document class 9 | */ 10 | class TemplateI2CMaster final : public embvm::i2c::master 11 | { 12 | public: 13 | explicit TemplateI2CMaster() noexcept : embvm::i2c::master("Template I2C (Master)") {} 14 | 15 | explicit TemplateI2CMaster(const char* name) noexcept : embvm::i2c::master(name) {} 16 | 17 | /// Default destructor 18 | ~TemplateI2CMaster() noexcept final; 19 | 20 | private: 21 | void configure_(embvm::i2c::pullups pullup) noexcept final; 22 | embvm::i2c::status transfer_(const embvm::i2c::op_t& op, 23 | const embvm::i2c::master::cb_t& cb) noexcept final; 24 | embvm::i2c::baud baudrate_(embvm::i2c::baud baud) noexcept final; 25 | embvm::i2c::pullups setPullups_(embvm::i2c::pullups pullups) noexcept final; 26 | void start_() noexcept final; 27 | void stop_() noexcept final; 28 | }; 29 | 30 | } // namespace embdrv 31 | 32 | #endif // TEMPLATE_I2C_DRIVER_HPP_ 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The [Embedded VM core project](https://github.com/embvm/embvm-core) (`embvm-core`) is dual-licensed. The open-source version of the core project is released under GPLv3. [A commercial license](https://embeddedartistry.com/product/embedded-virtual-machine-commercial-license), which provides holders with the ability to create and distribute software without open-source obligations, can be purchased in the [Embedded Artistry store](https://embeddedartistry.com/store). This enables companies with a no-open-source or no-GPLv3 policy to use this project, since you will not be using an open-source license. 2 | 3 | This project uses [SPDX license IDs](https://spdx.dev/ids/) to indicate the specific license used. 4 | 5 | Licenses for any third-party software included in this repository can be found in the [Software Inventory](docs/software_inventory.xlsx). 6 | 7 | For additional information or assistance, you can contact Embedded Artistry via: 8 | 9 | - [Our Website](https://embeddedartistry.com/contact/) 10 | - [Via email](mailto:contact@embeddedartistry.com) 11 | -------------------------------------------------------------------------------- /docs/architecture/principles/0007-dont_hack_refactor.md: -------------------------------------------------------------------------------- 1 | # Principle: Don't Hack, Refactor 2 | 3 | **Name:** Don't hack, refactor 4 | 5 | Don't hack, patch, or bolt something on. Refactor and make the change properly. 6 | 7 | ## Description 8 | 9 | * Statement of the principle 10 | * Clearly state the chosen direction 11 | 12 | ## Rationale/Benefits 13 | 14 | * Describe the reasoning behind the principle 15 | * Where appicable, provide traceability to business or architectural objectives 16 | 17 | ## Implications 18 | 19 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 20 | 21 | ## Counterforces 22 | 23 | What forces will push against this principle? 24 | 25 | * Speed 26 | * schedule pressure 27 | * avoiding extreme changes 28 | * convenience 29 | * abstractions are not obvious or easy to find 30 | 31 | ## Counterarguments 32 | 33 | * Describe the reasonable counter to this principle 34 | 35 | ## Scope 36 | 37 | * (Optional) 38 | * Indicate teh scope where this principle needs ot be applied 39 | -------------------------------------------------------------------------------- /docs/architecture/use_cases/0003-user_stories_ci_server.md: -------------------------------------------------------------------------------- 1 | # User Story: CI Server Group 2 | 3 | * Name: CI Server User Story Group 4 | * Category: Group 5 | * Reference Number: 0003 6 | 7 | **Table of Contents:** 8 | * [Story List](#story-list) 9 | * [Acceptance Criteria](#acceptance-criteria) 10 | * [Comments](#comments) 11 | 12 | ## Story List 13 | 14 | * As a build server, I want to compile software so I can ensure that there are no build problems. 15 | * As a build server, I want to run tests and collect the test results so I can: 16 | * ensure there are no build problems 17 | * provide a report of test results to users 18 | * Report the proper failure mode 19 | * As a build server, I want to control the output location of a build (i.e., out-of-source) so I can build multiple configurations while only checking out the repository once. 20 | 21 | ## Acceptance Criteria 22 | 23 | TBD 24 | 25 | ## Associated Mechanisms 26 | 27 | * Build system 28 | * Unit test framework 29 | * Static analysis framework 30 | * Access control 31 | * Configuration management 32 | -------------------------------------------------------------------------------- /templates/driver/time_of_flight.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_TOF_DRIVER_HPP_ 2 | #define TEMPLATE_TOF_DRIVER_HPP_ 3 | 4 | #include 5 | 6 | namespace embdrv 7 | { 8 | /** Document class 9 | */ 10 | class TemplateToFSensor final : public embvm::tof::sensor 11 | { 12 | public: 13 | explicit TemplateToFSensor() noexcept : embvm::tof::sensor("Template ToF"), {} 14 | 15 | void read() noexcept final; 16 | void reset() noexcept final; 17 | 18 | [[nodiscard]] embvm::tof::distance_t 19 | getMaxRangeForModeDark(embvm::tof::mode m) const noexcept final; 20 | [[nodiscard]] embvm::tof::distance_t 21 | getMaxRangeForModeStrongLight(embvm::tof::mode m) const noexcept final; 22 | embvm::tof::mode mode(embvm::tof::mode m) noexcept final; 23 | 24 | void registerReadCallback(const read_cb_t& cb) noexcept final; 25 | void registerReadCallback(read_cb_t&& cb) noexcept final; 26 | 27 | private: 28 | void start_() noexcept final; 29 | void stop_() noexcept final; 30 | }; 31 | 32 | } // namespace embdrv 33 | 34 | #endif // TEMPLATE_TOF_DRIVER_HPP_ 35 | -------------------------------------------------------------------------------- /templates/driver/spi.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEMPLATE_SPI_DRIVER_HPP_ 2 | #define TEMPLATE_SPI_DRIVER_HPP_ 3 | 4 | #include 5 | 6 | namespace embdrv 7 | { 8 | /** Documentation 9 | */ 10 | class TemplateSPIMaster final : public embvm::spi::master 11 | { 12 | public: 13 | explicit TemplateSPIMaster() noexcept : embvm::spi::master("Template SPI (Master)") {} 14 | 15 | explicit TemplateSPIMaster(const char* name) noexcept : embvm::spi::master(name) {} 16 | 17 | /// Default destructor. 18 | ~TemplateSPIMaster() noexcept final; 19 | 20 | private: 21 | void start_() noexcept final; 22 | void stop_() noexcept final; 23 | void configure_() noexcept final; 24 | uint32_t baudrate_(uint32_t baud) noexcept final; 25 | embvm::comm::status transfer_(const embvm::spi::op_t& op, 26 | const embvm::spi::master::cb_t& cb) noexcept final; 27 | void setMode_(embvm::spi::mode mode) noexcept final; 28 | void setOrder_(embvm::spi::order order) noexcept final; 29 | 30 | private: 31 | }; 32 | 33 | } // namespace embdrv 34 | 35 | #endif // TEMPLATE_SPI_DRIVER_HPP_ 36 | -------------------------------------------------------------------------------- /docs/development/reference/abi_register_cheatsheet.md: -------------------------------------------------------------------------------- 1 | # ABI Register Cheat Sheets 2 | 3 | The following are ABI register usage notes accumulated with development and porting of musl to various archs: 4 | 5 | # aarch64 6 | 7 | * x30 lr 8 | * x31 zr or pc 9 | 10 | # arm 11 | 12 | * r0-r3 args/ret 13 | * r4-r11 saved 14 | * r12 temp (ip scratch) 15 | * r13 sp 16 | * r14 lr 17 | * r15 pc 18 | 19 | # mips 20 | 21 | * $0 zero 22 | * $1 at (assembler temp) 23 | * $2-$3 ret (aka v0-v1) 24 | * $4-$7 args (aka a0-a3) 25 | * $8-$15 temp (aka t0-t7) 26 | * $16-$23 saved (aka s0-s7) 27 | * $24 temp (aka t8) 28 | * $25 function call addr (aka t9) 29 | * $26-$27 kernel use 30 | * $28 gp, call-clobbered 31 | * $29 sp 32 | * $30 fp 33 | * $31 ra 34 | 35 | Source: http://www.inf.ed.ac.uk/teaching/courses/car/Notes/slide03.pdf 36 | 37 | # or1k (OpenRISC) 38 | 39 | * r0 zero 40 | * r1 sp 41 | * r2 fp 42 | * r3-r8 args 43 | * r9 lr 44 | * r11,r12 retval (lo,hi) 45 | * r10 thread pointer 46 | * r14-r30(even) saved 47 | * r13-r31(odd) temp 48 | 49 | Source: openrisc-arch-1.1-rev0.pdf, p.335 50 | -------------------------------------------------------------------------------- /templates/driver/meson.build: -------------------------------------------------------------------------------- 1 | # meson build for Driver 2 | 3 | # To get this into the build, go up one level in the directory tree and add 4 | # a `subdir(your_hw_platform_dir)` command to the subdir group 5 | 6 | # Drivers should be typically build as dependencies and added into the HW Platform or Platform 7 | # dependency list. If the driver has items (such as include paths) which should not be leaked into 8 | # other layers, then build the drier as a static library. Create a dependency which includes 9 | # safe include paths and links against the library. The platform will still reference the dependency. 10 | 11 | # This dependency is meant to be used by platforms built with this driver 12 | template_driver_dep = declare_dependency( 13 | include_directories: include_directories('.'), 14 | sources: [files('your_driver.cpp')], 15 | dependencies: [ 16 | # Put build dependencies for your processor and drivers here 17 | ] 18 | ) 19 | 20 | # This should be added to the containing build file's test file list 21 | template_driver_test_files = files('template_driver_tests.cpp') 22 | -------------------------------------------------------------------------------- /templates/driver/driver_base.cpp: -------------------------------------------------------------------------------- 1 | #include "driver.hpp" 2 | #include "driver_registry.hpp" 3 | #include // For the definition of VirtualPlatform & PlatformDriverRegistry 4 | 5 | using namespace embvm; 6 | 7 | /* 8 | * VirtualPlatform is defined in each platform's platform.hpp file. 9 | * This file is not actually compiled as part of libcore, but instead 10 | * makes its way into the build as part of the platform's build. 11 | */ 12 | 13 | embvm::DriverBase::DriverBase(const char* name, uint32_t c) noexcept : name_(name), type_(c) 14 | { 15 | VirtualPlatform::registerDriver(name_, this); 16 | } 17 | 18 | embvm::DriverBase::DriverBase(const std::string& name, uint32_t c) noexcept : name_(name), type_(c) 19 | { 20 | VirtualPlatform::registerDriver(name_, this); 21 | } 22 | 23 | embvm::DriverBase::DriverBase(const std::string_view& name, uint32_t c) noexcept 24 | : name_(name), type_(c) 25 | { 26 | VirtualPlatform::registerDriver(name_, this); 27 | } 28 | 29 | embvm::DriverBase::~DriverBase() noexcept 30 | { 31 | VirtualPlatform::unregisterDriver(name_, this); 32 | } 33 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0021-eliminate-name-variables-from-core-base-classes.md: -------------------------------------------------------------------------------- 1 | # 21. Eliminate name variables from Core base classes 2 | 3 | Date: 2020-10-22 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | Under the initial design of the `embvm-core`, the following types stored a name in the base class: 12 | 13 | - Driver 14 | - Processor 15 | - Hardware Platform 16 | - Platform 17 | 18 | In some cases, like drivers, this data was duplicated (through the driver registry) or unnecessary (because you use the default name and provide the system name in the driver registry). We don't need to store two different instances of the same name! 19 | 20 | In other cases, like the processor and platforms, these names were never used. 21 | 22 | ## Decision 23 | 24 | These names will no longer be required by the base classes. 25 | 26 | ## Consequences 27 | 28 | - Reducing storage overhead per-class 29 | - Users can still specify names for their objects, but they must do it on their own 30 | - Canonical names for public drivers are handled through the Driver Registry (as the key) 31 | -------------------------------------------------------------------------------- /docs/templates/architecture/constraints.md: -------------------------------------------------------------------------------- 1 | # Constraint: Template 2 | 3 | * Name: 4 | * Reference Number: 5 | 6 | Constraints are special class of requirements that are not negotiable. The system *must* comply with these requirements, and so they are constraints. 7 | 8 | **Table of Contents:** 9 | 10 | 1. [Description](#description) 11 | 2. [Rationale](#rationale) 12 | 3. [Source](#source) 13 | 4. [Notes](#notes) 14 | 15 | ## Description 16 | 17 | * Description of the constraint 18 | 19 | Examples: 20 | * The application shall run on the existing network of personal computers 21 | * The application shall interface with the existing accounts payable system. 22 | * The application will comply with the HL7 standards 23 | 24 | ## Rationale 25 | 26 | * Why is this a constraint on the architecture? 27 | 28 | ## Source 29 | 30 | * Who surfaced this as a constraint 31 | 32 | ## Notes 33 | 34 | * Is it a run-time or development-time constraint? 35 | * What is its scope of impact? 36 | * What functionality is impacted? 37 | * Over what set of products/timeframe? 38 | * What are the implications? 39 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/new_project_guide.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ## New Project Checklist 6 | 7 | 8 | ## Using the Project Skeleton 9 | 10 | ## Including the `embvm-core` 11 | 12 | 13 | 14 | For detailed customization of your new project, you can refer to our developer guides. If you come across a question that isn't answered in the documentation, please file an issue. 15 | 16 | - [Adding a New Application](adding_an_application.md) 17 | - [Adding a New Platform](adding_new_platform.md) 18 | - [Adding a New Hardware Platform](adding_new_hw_platform.md) 19 | - [Adding a New Boot Sequence](adding_new_boot_sequence.md) 20 | - [Adding a New Driver Type](adding_new_driver_type.md) 21 | - [Adding a New Driver](adding_new_driver.md) 22 | - [Adding a New OS](adding_new_os.md) 23 | - [Adding a New Processor](adding_new_processor.md) 24 | - [Supporting Libraries](supporting_libraries.md) describes the supporting libraries that are made available to you through the `embvm-core` project. 25 | - [Unit Testing with Catch2](unit_testing_with_catch2.md) explains how to work with the built-in Catch2 testing target. 26 | -------------------------------------------------------------------------------- /src/utilities/tuple_array/tuple_array_tests.cpp: -------------------------------------------------------------------------------- 1 | #include "tuple_array.hpp" 2 | #include 3 | 4 | using namespace embutil; 5 | 6 | static auto generate_tuple(void) 7 | { 8 | auto my_tuple = std::make_tuple(int{10}, int{100}); 9 | 10 | return std::tuple_cat(my_tuple, std::make_tuple(int{104848})); 11 | } 12 | 13 | TEST_CASE("Check tuple to array conversion", "[util/tuple_array]") 14 | { 15 | using array_t = std::array; 16 | array_t reference{200, 100, static_cast('z')}; 17 | array_t val = 18 | tuple_to_array(std::tuple{200, 100, 'z'}); 19 | 20 | for(size_t i = 0; i < val.size(); i++) 21 | { 22 | CHECK(reference.at(i) == val.at(i)); 23 | } 24 | } 25 | 26 | TEST_CASE("Check tuple to array conversion with a concat tuple", "[util/tuple_array]") 27 | { 28 | using array_t = std::array; 29 | array_t reference{10, 100, 104848}; 30 | 31 | auto val = tuple_to_array(generate_tuple()); 32 | 33 | for(size_t i = 0; i < val.size(); i++) 34 | { 35 | CHECK(reference.at(i) == val.at(i)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/templated_buffer_pool.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Templated Buffer Pool 2 | 3 | **Table of Contents:** 4 | 5 | 1. [Responsibilities](#responsibilities) 6 | 2. [Requirements](#requirements) 7 | 3. [Collaborators](#collaborators) 8 | 4. [Rationale](#rationale) 9 | 5. [Source Links](#source-links) 10 | 6. [Related Documents](#related-documents) 11 | 7. [Notes](#notes) 12 | 13 | ## Responsibilities 14 | 15 | * Manage a pool of buffers 16 | * Recycle buffers when they are no longer needed by the consumer 17 | * Allocate new buffers when needed (if not using static allocation) 18 | 19 | ## Requirements 20 | 21 | * Support static and dynamic memory schemes 22 | 23 | ## Collaborators 24 | 25 | * Buffer pools manage [Buffers](templated_buffer.md) 26 | 27 | ## Rationale 28 | 29 | Memory pools are frequently used in embedded systems to provide a fixed memory capacity while still supporting dynamic-esque allocations (e.g., event pools). The buffer pool serves that need. 30 | 31 | ## Source Links 32 | 33 | TBD 34 | 35 | ## Related Documents 36 | 37 | N/A 38 | 39 | ## Notes 40 | 41 | N/A 42 | -------------------------------------------------------------------------------- /templates/hw_platform/template_hw_platform.cpp: -------------------------------------------------------------------------------- 1 | #include "template_hw_platform.hpp" 2 | 3 | TemplateHWPlatform::TemplateHWPlatform() noexcept {} 4 | 5 | TemplateHWPlatform::~TemplateHWPlatform() noexcept {} 6 | 7 | void TemplateHWPlatform::earlyInitHook_() noexcept 8 | { 9 | // Should anything happen for this hardware platform before we initialize the 10 | // processor, the OS, and the board? 11 | // Such an example might include setting up DRAM (needed before libc++ calls constructors) 12 | } 13 | 14 | void TemplateHWPlatform::soft_reset_() noexcept 15 | { 16 | // You will likely want to do this: 17 | processor_.reset(); 18 | } 19 | 20 | void TemplateHWPlatform::hard_reset_() noexcept 21 | { 22 | // Default to a soft reset if your system doesn't have hard reset capabilities 23 | soft_reset_(); 24 | } 25 | 26 | void TemplateHWPlatform::initProcessor_() noexcept 27 | { 28 | // You probably want to call this at a bare minimum: 29 | processor_.init(); 30 | } 31 | 32 | void TemplateHWPlatform::init_() noexcept 33 | { 34 | // What should happen during the boot process for your hardware platform? 35 | } 36 | -------------------------------------------------------------------------------- /docs/architecture/principles/0008-honor_the_contracts.md: -------------------------------------------------------------------------------- 1 | # Principle: Honor the Contracts 2 | 3 | **Name:** Honor the Contracts 4 | 5 | API Contracts are honored. Enhancements/additions don't break existing functionality. Breaking changes are announced 6-12 months in advance. 6 | 7 | ## Description 8 | 9 | * Statement of the principle 10 | * Clearly state the chosen direction 11 | 12 | ## Rationale/Benefits 13 | 14 | * Describe the reasoning behind the principle 15 | * Where appicable, provide traceability to business or architectural objectives 16 | 17 | ## Implications 18 | 19 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 20 | 21 | ## Counterforces 22 | 23 | What forces will push against this principle? 24 | 25 | * Speed 26 | * schedule pressure 27 | * avoiding extreme changes 28 | * convenience 29 | * abstractions are not obvious or easy to find 30 | 31 | ## Counterarguments 32 | 33 | * Describe the reasonable counter to this principle 34 | 35 | ## Scope 36 | 37 | * (Optional) 38 | * Indicate teh scope where this principle needs ot be applied 39 | -------------------------------------------------------------------------------- /docs/architecture/principles/0006-fix_the_painful_things.md: -------------------------------------------------------------------------------- 1 | # Principle: Fix the Painful Things 2 | 3 | **Name:** Fix the Painful Things 4 | 5 | When something is painful to use / causing pain: fix it! do somethign! Don't just let it keep bothering you. 6 | 7 | We want usability. 8 | 9 | ## Description 10 | 11 | * Statement of the principle 12 | * Clearly state the chosen direction 13 | 14 | ## Rationale/Benefits 15 | 16 | * Describe the reasoning behind the principle 17 | * Where appicable, provide traceability to business or architectural objectives 18 | 19 | ## Implications 20 | 21 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 22 | 23 | ## Counterforces 24 | 25 | What forces will push against this principle? 26 | 27 | * Speed 28 | * schedule pressure 29 | * avoiding extreme changes 30 | * convenience 31 | * abstractions are not obvious or easy to find 32 | 33 | ## Counterarguments 34 | 35 | * Describe the reasonable counter to this principle 36 | 37 | ## Scope 38 | 39 | * (Optional) 40 | * Indicate teh scope where this principle needs ot be applied 41 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0022-unified-gpio-base-class.md: -------------------------------------------------------------------------------- 1 | # 22. Unified GPIO base class 2 | 3 | Date: 2020-10-28 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | The issue motivating this decision, and any context that influences or constrains the decision. 12 | 13 | ## Decision 14 | 15 | To simplify the implementation for drivers, we will create a "unified" GPIO base class, which provides the standard interfaces that can be used to set the mode (input, output, special function). This will provide a single class to implement for GPIO support, rather than one class for each mode. 16 | 17 | Ideally, we will find a way to zero-overhead create wrapper classes that constrain the interface appropriately, so we can mark pins as `GPIOInput` or `GPIOOutput` and have the compiler report an error if we try to do an invalid operation for the given type. 18 | 19 | ## Consequences 20 | 21 | - Simplified implementation for porting purposes - we only need to implement one class. 22 | - We lose type safety with the default base class; there's no way to generate a compiler error if `set()` is being called on an input GPIO pin. 23 | -------------------------------------------------------------------------------- /docs/templates/architecture/architecture_decision.md: -------------------------------------------------------------------------------- 1 | # Architecture Decision: Template 2 | 3 | * **Title:** 4 | * **AD ID:** 5 | * **Subject Area:** e.g., Process & service layer design 6 | * **Topic:** e.g., Integration 7 | * **Date:** 8 | 9 | ## Status 10 | 11 | ## Context 12 | 13 | What is the issue or problem? 14 | 15 | e.g., how should process activities and underlying services communicate 16 | 17 | ## Decision 18 | 19 | What decision was made? 20 | 21 | ## Assumptions 22 | 23 | ## Rationale 24 | 25 | * What is the motivation for the decision? 26 | * e.g., if logical layers are physically distributed, they must be integrated 27 | 28 | ## Alternatives 29 | 30 | ## Justification 31 | 32 | e.g., need to select, install, and configure a message-oriented middleware 33 | 34 | ## Implications 35 | 36 | ## Derived Requirements 37 | 38 | Derived requirements (finer-grained patterns are now eligible and need to be decided on: message construction, channel design, message routing, message transormatoin, system management) 39 | 40 | ## Related Decisions 41 | 42 | * Related decisions 43 | * What needs to be decided on next? 44 | -------------------------------------------------------------------------------- /src/drivers/unit_test/gpio.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef UNIT_TEST_GPIO_HPP_ 5 | #define UNIT_TEST_GPIO_HPP_ 6 | 7 | #include 8 | #include 9 | 10 | namespace test 11 | { 12 | /** Unit Test GPIO Driver 13 | * 14 | * @ingroup TestDrivers 15 | */ 16 | class UnitTestGPIO final : public embvm::gpio::base 17 | { 18 | public: 19 | UnitTestGPIO() noexcept : mode_(embvm::gpio::mode::output) {} 20 | explicit UnitTestGPIO(embvm::gpio::mode mode) noexcept : mode_(mode) {} 21 | ~UnitTestGPIO() noexcept = default; 22 | bool get() noexcept final; 23 | void set(bool v) noexcept final; 24 | void toggle() noexcept final; 25 | void setMode(embvm::gpio::mode mode) noexcept final; 26 | embvm::gpio::mode mode() noexcept final; 27 | 28 | protected: 29 | void start_() noexcept final; 30 | void stop_() noexcept final; 31 | 32 | private: 33 | embvm::gpio::mode mode_; 34 | bool value_ = false; 35 | }; 36 | 37 | } // namespace test 38 | 39 | #endif // UNIT_TEST_GPIO_HPP_ 40 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/adding_a_new_library_target.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Adding a New Static Library Build Target 4 | 5 | #TODO: UPDATE THIS TO USE THE LATEST DEPENDENCY 6 | 7 | When creating static library or executable targets, you need to specify `libc_header_include` as an `include_directories` entry and `libcxx_header_include_dep` as a `dependencies` entry: 8 | 9 | ``` 10 | nrf52840 = static_library('nrf52840', 11 | [ 12 | 'nrf52840.cpp', 13 | '../mdk/gcc_startup_nrf52840.S', 14 | '../mdk/system_nrf52840.c', 15 | ], 16 | include_directories: [ 17 | nordic_include_dirs, 18 | cmsis_corem_include, 19 | framework_includes, 20 | libc_header_include, # <----- libc header include 21 | ], 22 | c_args: [ 23 | '-DCONFIG_GPIO_AS_PINRESET', 24 | '-DNRF52840_XXAA', 25 | ], 26 | cpp_args: [ 27 | '-DNRF52840_XXAA', 28 | '-DDEBUG_ASSERT_NO_STDIO', 29 | ], 30 | dependencies: [ 31 | nrf_common_drivers_dep, 32 | libcxx_header_include_dep, # <----- libcpp header dep 33 | arm_dep, 34 | ], 35 | native: false 36 | ) 37 | ``` 38 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0011-generic-startup-library.md: -------------------------------------------------------------------------------- 1 | # 11. Generic Startup Library 2 | 3 | Date: 2018-07-06 4 | 5 | ## Status 6 | 7 | Proposed 8 | 9 | ## Context 10 | 11 | Systems go through a predictable set of boot behaviors, which we can commonize: 12 | 13 | * Relocate 14 | * zero data in the .bss section 15 | * Call constructors 16 | * Initialize RTOS 17 | * Set default hardware pin states 18 | * Create drivers 19 | * Configure system 20 | 21 | ## Decision 22 | 23 | We will provide a generic startup library which manages the initial boot sequence in a predictable manner. 24 | 25 | The library will gain control from the processor startup sequence and transition the boot control process to the platform layer. It will call pre-defined platform APIs to initialize the RTOS, board, etc. 26 | 27 | We will call the same order ever time, but allow the platform to define actions that occur at each stage. 28 | 29 | ## Consequences 30 | 31 | * Boot process needs to be well-defined in order to apply across the board 32 | * Proper extension points need to be added to maintain design flexibility 33 | * Boot Sequencer must be made with a strategy pattern to allow users to override the behavior 34 | -------------------------------------------------------------------------------- /docs/architecture/principles/0003-keep_it_simple.md: -------------------------------------------------------------------------------- 1 | # Principle: Keep it Simple 2 | 3 | **Name:** Keep it Simple 4 | 5 | Keep the framework simple and EASY TO USE. We do not want to build a system that only experts can use successfully. 6 | 7 | The framework can be complicated on the inside, but using it should be straightforward and EASY TO GET RIGHT 8 | 9 | ## Description 10 | 11 | * Statement of the principle 12 | * Clearly state the chosen direction 13 | 14 | ## Rationale/Benefits 15 | 16 | * Describe the reasoning behind the principle 17 | * Where appicable, provide traceability to business or architectural objectives 18 | 19 | ## Implications 20 | 21 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 22 | 23 | ## Counterforces 24 | 25 | What forces will push against this principle? 26 | 27 | * Speed 28 | * schedule pressure 29 | * avoiding extreme changes 30 | * convenience 31 | * abstractions are not obvious or easy to find 32 | 33 | ## Counterarguments 34 | 35 | * Describe the reasonable counter to this principle 36 | 37 | ## Scope 38 | 39 | * (Optional) 40 | * Indicate teh scope where this principle needs ot be applied 41 | -------------------------------------------------------------------------------- /docs/templates/business/differentiation_strategy.md: -------------------------------------------------------------------------------- 1 | # Differentiation Strategy 2 | 3 | Finding opportunity: 4 | 5 | * What is desired? 6 | * What are customers' goals and activities? 7 | * What are their dreams, hopes, passions, aspirations, sources of joy and delight? 8 | * What are their fears, concerns, frustrations, aversions, or hassles? 9 | * What is possible? 10 | * What are our capabilities and resources? 11 | * What does new (uses of) technology make possible? 12 | * The intersection of these two provides opportunities to add value 13 | * Differentiating value includes the intersection of desired + possible + how we can beat our competitiors 14 | 15 | ## How We Will Compete 16 | 17 | How will we compete? 18 | 19 | * Cost, efficiency 20 | * Innovation, speed to market, 21 | * Cusotmer intimacy, customization 22 | 23 | ## Strategic Advantages of Our Architecture 24 | 25 | How will our architecture be a source of strategic advantage? 26 | 27 | * Where will we differentiate? 28 | * Where will we need to only be at parity? 29 | * Where can we adopt external standards/technologies 30 | 31 | ## Where Will We Focus Effort and Investment? 32 | 33 | To help apply the strategy and competitive areas. 34 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/boot_flags.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Boot Flags 2 | 3 | **Status:** Not started 4 | 5 | **Table of Contents:** 6 | 7 | 1. [Responsibilities](#responsibilities) 8 | 2. [Requirements](#requirements) 9 | 3. [Collaborators](#collaborators) 10 | 4. [Rationale](#rationale) 11 | 5. [Source Links](#source-links) 12 | 6. [Related Documents](#related-documents) 13 | 7. [Notes](#notes) 14 | 15 | ## Responsibilities 16 | 17 | * Set flags while running (e.g., prior to reboot) 18 | * Check flags during boot 19 | * Clear flags 20 | 21 | ## Requirements 22 | 23 | TBD 24 | 25 | ## Collaborators 26 | 27 | TBD 28 | 29 | ## Rationale 30 | 31 | We often need to set various flags to indicate our intentions during a reboot/boot process. By setting flags, we can know: 32 | 33 | * Whether we've booted successfully or not 34 | * Whether a crash occurred 35 | * Whether a firmware update failed 36 | * Whether a panic occurred 37 | 38 | We can check for these flags and implement specific behaviors after booting. 39 | 40 | ## Source Links 41 | 42 | TBD 43 | 44 | ## Notes 45 | 46 | We can handle specific flags & behaviors within the platsform file. Perhaps we call platform_init() with boot args supplied? 47 | -------------------------------------------------------------------------------- /docs/patterns/iterator.md: -------------------------------------------------------------------------------- 1 | # Pattern: Iterator 2 | 3 | Provide a way to access the elements of an aggregate object sequentially without exposing its underlying implementation 4 | 5 | * **Classification:** TBD 6 | 7 | ## Diagrams 8 | 9 | * Include / link to visual representations of this pattern 10 | 11 | ## Context 12 | 13 | * How does this pattern help to complete larger patterns? 14 | * What is the intent of this pattern? 15 | 16 | ## Problem 17 | 18 | * Two sentence description 19 | * Include example/motivation 20 | * Include the forces at play (applicability) 21 | * Follow with empirical background for the pattern 22 | * Evidence for validity 23 | * Range of valididty 24 | 25 | ## Solution 26 | 27 | * Stated as an instruction 28 | * Describe the structure, dynamics, and implementation heuristics 29 | 30 | ## Consequences 31 | 32 | * What are the benefits of using this pattern? 33 | * What are the liabilities with using this pattern? 34 | 35 | ## Known Uses 36 | 37 | * Describe known applications for this pattern 38 | * Link to uses of the pattern within the source code 39 | 40 | ## Variants 41 | 42 | Link to any patterns that are varients of this 43 | 44 | ## Related Patterns 45 | 46 | Link to any related patterns 47 | -------------------------------------------------------------------------------- /src/utilities/endian/endian_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "endian.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | 9 | TEST_CASE("testing SwapEndian", "[utility/endian]") 10 | { 11 | uint8_t a = 0xA5; 12 | SwapEndian(a); 13 | CHECK(a == 0xA5); 14 | 15 | uint16_t b = 0x5AA5; 16 | SwapEndian(b); 17 | CHECK(b == 0xA55A); 18 | 19 | uint32_t c = 0xFFBBEEAA; 20 | SwapEndian(c); 21 | CHECK(c == 0xAAEEBBFF); 22 | } 23 | 24 | TEST_CASE("testing byteswap (constant)", "[utility/endian]") 25 | { 26 | const uint8_t a = 0xA5; 27 | STATIC_REQUIRE(byteswap(a) == 0xA5); 28 | 29 | const uint16_t b = 0x5AA5; 30 | STATIC_REQUIRE(byteswap(b) == 0xA55A); 31 | 32 | const uint32_t c = 0xFFBBEEAA; 33 | STATIC_REQUIRE(byteswap(c) == 0xAAEEBBFF); 34 | } 35 | 36 | TEST_CASE("testing SwapEndianUB", "[utility/endian]") 37 | { 38 | uint8_t a = 0xA5; 39 | SwapEndian_UB(a); 40 | CHECK(a == 0xA5); 41 | 42 | uint16_t b = 0x5AA5; 43 | SwapEndian_UB(b); 44 | CHECK(b == 0xA55A); 45 | 46 | uint32_t c = 0xFFBBEEAA; 47 | SwapEndian_UB(c); 48 | CHECK(c == 0xAAEEBBFF); 49 | } 50 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/static_function.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Static Function 2 | 3 | Static implementation of `std::function` (no dynamic allocation, no exceptions). 4 | 5 | **Status:** Completed 6 | 7 | **Table of Contents:** 8 | 9 | 1. [Responsibilities](#responsibilities) 10 | 2. [Requirements](#requirements) 11 | 3. [Collaborators](#collaborators) 12 | 4. [Rationale](#rationale) 13 | 5. [Source Links](#source-links) 14 | 6. [Related Documents](#related-documents) 15 | 7. [Notes](#notes) 16 | 17 | ## Responsibilities 18 | 19 | * Operate like `std::function`, as a container for a callable object 20 | 21 | ## Requirements 22 | 23 | * No dynamic memory allocation 24 | * No exceptions 25 | * Cannot grow past fixed-size limit 26 | 27 | ## Collaborators 28 | 29 | N/A 30 | 31 | ## Rationale 32 | 33 | Embedded systems often do not utilize dynamic memory allocation. An equivalent structure using static memory should be provided. 34 | 35 | ## Source Links 36 | 37 | The inplace_function library has been used to satisfy this requirement: 38 | 39 | * [inplace_function.hpp](../../../../src/stdlibs/libcpp/extensions/inplace_function/inplace_function.hpp) 40 | 41 | ## Related Documents 42 | 43 | N/A 44 | 45 | ## Notes 46 | 47 | N/A 48 | -------------------------------------------------------------------------------- /src/core/driver/internal/i2c.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include 5 | 6 | constexpr uint8_t I2C_ADDR_MAX = 127; 7 | 8 | void embvm::i2c::master::sweep(sweep_list_t& found_list, const sweep_cb_t& cb) noexcept 9 | { 10 | i2c::op_t xact; 11 | xact.op = i2c::operation::ping; 12 | embvm::i2c::status status; 13 | 14 | auto callback = [&](i2c::op_t op, i2c::status s) { 15 | if(s == i2c::status::ok) 16 | { 17 | found_list.push_back(op.address); 18 | } 19 | }; 20 | 21 | for(uint8_t i = 0; i < I2C_ADDR_MAX; i++) 22 | { 23 | xact.address = i; 24 | do 25 | { 26 | // TODO: sleep if threading? 27 | status = transfer(xact, callback); 28 | } while(status == embvm::i2c::status::busy); 29 | } 30 | 31 | // The final sweep address will trigger the client callback 32 | xact.address = I2C_ADDR_MAX; 33 | do 34 | { 35 | // TODO: sleep if threading? 36 | status = transfer(xact, [&](i2c::op_t op, i2c::status s) { 37 | if(s == i2c::status::ok) 38 | { 39 | found_list.push_back(op.address); 40 | } 41 | 42 | cb(); 43 | }); 44 | } while(status == embvm::i2c::status::busy); 45 | } 46 | -------------------------------------------------------------------------------- /docs/architecture/principles/0001-get_abstractions_right.md: -------------------------------------------------------------------------------- 1 | # Principle: Get the Abstractions Right 2 | 3 | **Name:** Get the Abstractions Right 4 | 5 | They are the core piece of the framework. Spend time getting abstractions and APIs correct. Research, study,, model, and prototype before committing to an abstraction or interface. Don't use the first idea/implementation/version. Refactor and improve. 6 | 7 | ## Description 8 | 9 | * Statement of the principle 10 | * Clearly state the chosen direction 11 | 12 | ## Rationale/Benefits 13 | 14 | * Describe the reasoning behind the principle 15 | * Where appicable, provide traceability to business or architectural objectives 16 | 17 | ## Implications 18 | 19 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 20 | 21 | ## Counterforces 22 | 23 | What forces will push against this principle? 24 | 25 | * Speed 26 | * schedule pressure 27 | * avoiding extreme changes 28 | * convenience 29 | * abstractions are not obvious or easy to find 30 | 31 | ## Counterarguments 32 | 33 | * Describe the reasonable counter to this principle 34 | 35 | ## Scope 36 | 37 | * (Optional) 38 | * Indicate teh scope where this principle needs ot be applied 39 | -------------------------------------------------------------------------------- /src/platforms/unit_test/platform.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef UNIT_TEST_PLATFORM_HPP_ 5 | #define UNIT_TEST_PLATFORM_HPP_ 6 | 7 | #include 8 | #include 9 | 10 | /// This platform exists for use in the framework unit tests 11 | class UnitTestPlatform : public embvm::VirtualPlatformBase, 12 | public embvm::PlatformDispatcher 13 | { 14 | using VirtualPlatform = embvm::VirtualPlatformBase; 15 | 16 | public: 17 | /// Default constructor 18 | UnitTestPlatform() noexcept {} 19 | 20 | /// Default destructor 21 | ~UnitTestPlatform() noexcept {} 22 | 23 | static void earlyInitHook_() noexcept 24 | { 25 | UnitTestHWPlatform::earlyInitHook(); 26 | } 27 | 28 | void init_() noexcept {} 29 | 30 | void initProcessor_() noexcept 31 | { 32 | hw_platform_.initProcessor(); 33 | } 34 | 35 | void initHWPlatform_() noexcept 36 | { 37 | hw_platform_.init(); 38 | } 39 | }; 40 | 41 | using VirtualPlatform = UnitTestPlatform; 42 | 43 | #endif // UNIT_TEST_PLATFORM_HPP_ 44 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0005-provide-non-blocking-interfaces.md: -------------------------------------------------------------------------------- 1 | # 5. Provide Non-Blocking Interfaces by Default 2 | 3 | Date: 2018-07-06 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | Blocking interfaces are those that only return when an operation has been completed. 12 | 13 | Non-blocking interfaces initiate a request and return when the request is submitted. Completion is annouced via a callback or by checking the status through another interface. 14 | 15 | Non-blocking interfaces provide a more flexible implementation route. 16 | 17 | Blocking implementations are typically avoided on embedded systems. Typically, a thread should sleep while waiting for an action to complete, rather than hogging processor resources. 18 | 19 | ## Decision 20 | 21 | Interfaces provided by the framework will be non-blocking. Users can write their own blocking wrappers if blocking code is needed. 22 | 23 | ## Consequences 24 | 25 | * Enables high flexibility in implementations 26 | * Prevents wasted cycles within an operation 27 | * Users can still create blocking interfaces if they need them. But they *must* create blocking interfaces. 28 | * We can potentially supply decorators to create blocking functions if this is a major pain point 29 | -------------------------------------------------------------------------------- /docs/development/developer_documentation.md: -------------------------------------------------------------------------------- 1 | # Developer Documentation 2 | 3 | The documentation in this repository is useful for developers who are working on the Embedded VM, or who want to use Embedded VM contentions in their projects. 4 | 5 | Documentation includes: 6 | 7 | * [Developer Guide](developer_guide.md) contains guidelines for developers working on the project 8 | * [C++ Guidelines](cpp_guidelines.md) contains guidelines for the C++ code used in the framework 9 | * [Documentation Guidelines](documentation.md) clarify documentation practices for framework modules 10 | * [Error Model](error_model.md) describes the framework's approach to error handling 11 | * [Namespaces.xlsx](namespaces.xlsx) contains a list of namespaces defined by the framework 12 | * [Refactoring](refactoring.md) provides guidelines for cleaning up existing code 13 | * The [Patterns/](patterns/) directory contains notes about patterns used throughout the framework 14 | * The [Reference/](reference/) directory contains useful references for developers. 15 | * The [Development Logs](development_logs) directory is used to archive notes and logs from past development efforts. These files may provide additional context for users who are wondering why specific decisions were made. 16 | -------------------------------------------------------------------------------- /src/utilities/sbrm/csbrm_test.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "csbrm.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | 9 | namespace 10 | { 11 | struct CSBRM_tester 12 | { 13 | bool initialized_ = false; 14 | bool deleted_ = false; 15 | }; 16 | 17 | CSBRM_tester* create(CSBRM_tester* t) 18 | { 19 | t->initialized_ = true; 20 | return t; 21 | } 22 | 23 | void destroy(CSBRM_tester* t) 24 | { 25 | t->deleted_ = true; 26 | } 27 | 28 | } // namespace 29 | 30 | TEST_CASE("unique_resource", "[utilities/csbrm]") 31 | { 32 | CSBRM_tester test_val; 33 | auto resource = unique_resource(create, destroy, &test_val); 34 | CHECK(test_val.initialized_); 35 | resource.reset(); 36 | CHECK(test_val.deleted_); 37 | } 38 | 39 | TEST_CASE("shared_resource", "[utilities/csbrm]") 40 | { 41 | CSBRM_tester test_val; 42 | auto resource = shared_resource(create, destroy, &test_val); 43 | CHECK(test_val.initialized_); 44 | 45 | auto resource2 = resource; 46 | resource.reset(); 47 | CHECK(test_val.deleted_ == false); 48 | 49 | resource2.reset(); 50 | CHECK(test_val.deleted_); 51 | } 52 | -------------------------------------------------------------------------------- /src/drivers/unit_test/spi.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "spi.hpp" 5 | 6 | using namespace test; 7 | 8 | spiTestDriver::~spiTestDriver() noexcept {} 9 | 10 | void spiTestDriver::start_() noexcept {} 11 | 12 | void spiTestDriver::stop_() noexcept {} 13 | 14 | void spiTestDriver::configure_() noexcept {} 15 | 16 | void spiTestDriver::setMode_(embvm::spi::mode mode) noexcept 17 | { 18 | (void)mode; 19 | } 20 | 21 | void spiTestDriver::setOrder_(embvm::spi::order order) noexcept 22 | { 23 | (void)order; 24 | } 25 | 26 | uint32_t spiTestDriver::baudrate_(uint32_t baud) noexcept 27 | { 28 | return baud; 29 | } 30 | 31 | embvm::comm::status spiTestDriver::transfer_(const embvm::spi::op_t& op, 32 | const embvm::spi::master::cb_t& cb) noexcept 33 | { 34 | (void)cb; 35 | 36 | for(size_t i = 0; i < op.length; i++) 37 | { 38 | if(op.tx_buffer) 39 | { 40 | txBuffer_.push_back(op.tx_buffer[i]); 41 | } 42 | else 43 | { 44 | txBuffer_.push_back(0); 45 | } 46 | 47 | if(op.rx_buffer) 48 | { 49 | op.rx_buffer[i] = rxBuffer_.front(); 50 | rxBuffer_.pop(); 51 | } 52 | } 53 | 54 | return embvm::comm::status::ok; 55 | } 56 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0010-dispatch-callbacks.md: -------------------------------------------------------------------------------- 1 | # 10. Dispatch Callbacks 2 | 3 | Date: 2018-07-06 4 | 5 | This relates to decision [0009: Event Driven Framework Design](0009-event-driven-framework-design.md) 6 | 7 | ## Status 8 | 9 | Proposed 10 | 11 | ## Context 12 | 13 | Because we are building an [event-driven framework], we need to think about how to handle callback functions. We want to use them without causing threads/functions to block unexpectedly while executing callbacks. 14 | 15 | ## Decision 16 | 17 | We will dispatch callbacks to a global dispatch queue which will execute them as processing time is available. 18 | 19 | ## Consequences 20 | 21 | * A system will always need a dispatch queue to handle callbacks 22 | * Callbacks will not cause threads/functions to block unexpectedly while executing the callbacks 23 | * High-priority threads can still execute ahead of the callbacks, ensuring that we meet our real-time guarantees 24 | * We need to make sure the dispatched functions have operating time 25 | 26 | ## Issues 27 | 28 | * A system will always need a dispatch queue to handle callbacks 29 | * TBD: How can we enforce this? 30 | 31 | ## Further Reading 32 | 33 | * [Decision 0009: Event Driven Framework Design](0009-event-driven-framework-design.md) 34 | -------------------------------------------------------------------------------- /src/utilities/time/time_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "time.hpp" 5 | #include 6 | #include 7 | 8 | using namespace embutil; 9 | 10 | // TODO: add time point tests 11 | 12 | TEST_CASE("timespecToDuration conversion tests", "[util/time]") 13 | { 14 | constexpr timespec ts = {0, 100}; 15 | STATIC_REQUIRE(std::chrono::nanoseconds(100) == timespecToDuration(ts)); 16 | 17 | timespec ts2 = {3, 100}; 18 | CHECK((std::chrono::seconds(3) + std::chrono::nanoseconds(100)) == timespecToDuration(ts2)); 19 | } 20 | 21 | TEST_CASE("durationToTimespec conversion tests", "[util/time]") 22 | { 23 | auto dur = std::chrono::nanoseconds(100); 24 | auto ts = durationToTimespec(dur); 25 | CHECK(((ts.tv_sec == 0) && (ts.tv_nsec == 100))); 26 | 27 | dur += std::chrono::seconds(1); 28 | ts = durationToTimespec(dur); 29 | CHECK(((ts.tv_sec == 1) && (ts.tv_nsec == 100))); 30 | } 31 | 32 | #ifdef UTIL_TIME_INCLUDE_TIMEVAL 33 | TEST_CASE("timevalToDuration conversion tests", "[util/time]") 34 | { 35 | timeval tv = {0, 100}; 36 | auto dur = timevalToDuration(tv); 37 | CHECK(std::chrono::microseconds(100) == dur); 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /docs/UsingTheFramework/adding_new_driver.md: -------------------------------------------------------------------------------- 1 | # Developing a New Device Driver 2 | 3 | ## Embedded VM Driver Ethos 4 | 5 | 6 | 7 | ## Template Files 8 | 9 | ## Process 10 | 11 | Users also need to write their own drivers in their source without messing with the framework. Make templates + examples for this. 12 | 13 | 14 | Drivers use multiple inheritence to compose functionality: 15 | Unfortunately, misguided usage has made this once popular feature almost completely disappear. On the other hand, sometimes you want to inherit from parents that are completely separate from each other. This is where multiple inheritance can become productive. Classes that have orthogonal behaviors are the best case scenario for multiple inheritance. 16 | 17 | 18 | * The kernel is a slave to the application. Code in the kernel (such as in a driver) is passive in that it only reacts to requests from processes in user space. Drivers should not initiate any I/O activity on their own. 19 | * User processes cannot take direct interrupts. As a corollary to the previous point, kernel interrupt threads cannot jump to user space. Instead, if your application must be made aware of interrupts, it should provide a thread on which to deliver a notification of them. 20 | 21 | start() should begin operation + initiate HW 22 | -------------------------------------------------------------------------------- /docs/architecture/components/core/interrupt_manager.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Interrupt Manager 2 | 3 | Central location to manage interrupts & interrupt handlers. 4 | 5 | **Status:** Completed 6 | 7 | ## Responsibilities 8 | 9 | * Enable and disable interrupts globally 10 | * Configure interrupt handlers 11 | * Configure interrupts and priorities 12 | 13 | ## Requirements 14 | 15 | Interrupt manager handles registering interrupt handler functions, enabling/disabling interrupts, and managing interrupt priorities. 16 | 17 | ## Collaborators 18 | 19 | * Works with the [Interrupt Queue](../utilities/interrupt_queue.md) 20 | * Part of the [Virtual Processor](virtual_processor.md) 21 | 22 | ## Rationale 23 | 24 | The processor has one global interrupt table and one global interrupt state. Additionally, interrupts can be configured individually and given differing priorities. There should be one location in the system which manages the processor's interrupts. 25 | 26 | The interrupt manager handles interrupts directly. Interrupts are forwarded to registered handlers. Any function should be able to serve as a top-half of the interrupt handler (lambda, C-linkage function, class member). 27 | 28 | ## Source Links 29 | 30 | * [Virtual interrupt manager](../../../../src/core/processor/interrupt_manager.hpp) 31 | 32 | ## Notes 33 | 34 | N/A 35 | -------------------------------------------------------------------------------- /src/utilities/sbrm/scope_guard_tests.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #include "scope_guard.hpp" 5 | #include 6 | 7 | using namespace embutil; 8 | 9 | static volatile bool test_flag_ = false; 10 | 11 | static void test_guard() 12 | { 13 | test_flag_ = true; 14 | } 15 | 16 | TEST_CASE("Create a scope_guard class", "[utility/scope_guard]") 17 | { 18 | auto guard = makeScopeGuard([]() {}); 19 | 20 | CHECK(false == guard.isReleased()); 21 | } 22 | 23 | TEST_CASE("Release a scope_guard class", "[utility/scope_guard]") 24 | { 25 | auto guard = makeScopeGuard([]() {}); 26 | 27 | guard.release(); 28 | CHECK(true == guard.isReleased()); 29 | } 30 | 31 | TEST_CASE("Scope guard is called on scope exit", "[utility/scope_guard]") 32 | { 33 | test_flag_ = false; 34 | 35 | { 36 | auto guard = makeScopeGuard(&test_guard); 37 | (void)guard; // silence cppcheck 38 | } 39 | 40 | CHECK(true == test_flag_); 41 | } 42 | 43 | TEST_CASE("Scope guard is not called on scope exit after release", "[utility/scope_guard]") 44 | { 45 | test_flag_ = false; 46 | 47 | { 48 | auto guard = makeScopeGuard(&test_guard); 49 | guard.release(); 50 | } 51 | 52 | CHECK(false == test_flag_); 53 | } 54 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0009-event-driven-framework-design.md: -------------------------------------------------------------------------------- 1 | # 9. Event Driven Framework Design 2 | 3 | Date: 2018-07-06 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | * Embedded systems are highly event-driven, as they are responding to external stimuli and reacting in a planned way 12 | * Event-driven APIs reduce coupling, as the various objects don't need to know anything about other objects that they work with 13 | * We can reduce the number of threads used by relying on event-driven behavior 14 | 15 | ## Decision 16 | 17 | The framework will be defined with interfaces and processing models that support event-driven development (callbacks, events, register/unregister for events). 18 | 19 | Dispatch queues will be provided to assist with the event driven model. 20 | 21 | Platform examples will default to dispatch-based processing models. 22 | 23 | ## Consequences 24 | 25 | * All of our APIs should support an event driven interface 26 | * Consideration of callback functions & notification registering needs to be included at all stages 27 | * Threading will still be allowed and usable, maintaining flexibility 28 | * Dispatch queues will be used to handle generic callbacks without blocking high-priority operations 29 | 30 | ## Further Reading 31 | 32 | * [Observer Pattern](../../patterns/observer.md) 33 | -------------------------------------------------------------------------------- /docs/patterns/mediator.md: -------------------------------------------------------------------------------- 1 | # Pattern: Mediator 2 | 3 | Template for documenting architectural patterns used in this repository. Replace "Template" in the title with the pattern name 4 | 5 | * Include a summary description of this pattern 6 | * Include a brief classification of this pattern (Structural, Decoupling, etc.) 7 | 8 | ## Diagrams 9 | 10 | * Include / link to visual representations of this pattern 11 | 12 | ## Context 13 | 14 | * How does this pattern help to complete larger patterns? 15 | * What is the intent of this pattern? 16 | 17 | ## Problem 18 | 19 | * Two sentence description 20 | * Include example/motivation 21 | * Include the forces at play (applicability) 22 | * Follow with empirical background for the pattern 23 | * Evidence for validity 24 | * Range of valididty 25 | 26 | ## Solution 27 | 28 | * Stated as an instruction 29 | * Describe the structure, dynamics, and implementation heuristics 30 | 31 | ## Consequences 32 | 33 | * What are the benefits of using this pattern? 34 | * What are the liabilities with using this pattern? 35 | 36 | ## Known Uses 37 | 38 | * Describe known applications for this pattern 39 | * Link to uses of the pattern within the source code 40 | 41 | ## Variants 42 | 43 | Link to any patterns that are varients of this 44 | 45 | ## Related Patterns 46 | 47 | Link to any related patterns 48 | -------------------------------------------------------------------------------- /docs/patterns/monitor.md: -------------------------------------------------------------------------------- 1 | # Pattern: Template 2 | 3 | Template for documenting architectural patterns used in this repository. Replace "Template" in the title with the pattern name 4 | 5 | * Include a summary description of this pattern 6 | * Include a brief classification of this pattern (Structural, Decoupling, etc.) 7 | 8 | ## Diagrams 9 | 10 | * Include / link to visual representations of this pattern 11 | 12 | ## Context 13 | 14 | * How does this pattern help to complete larger patterns? 15 | * What is the intent of this pattern? 16 | 17 | ## Problem 18 | 19 | * Two sentence description 20 | * Include example/motivation 21 | * Include the forces at play (applicability) 22 | * Follow with empirical background for the pattern 23 | * Evidence for validity 24 | * Range of valididty 25 | 26 | ## Solution 27 | 28 | * Stated as an instruction 29 | * Describe the structure, dynamics, and implementation heuristics 30 | 31 | ## Consequences 32 | 33 | * What are the benefits of using this pattern? 34 | * What are the liabilities with using this pattern? 35 | 36 | ## Known Uses 37 | 38 | * Describe known applications for this pattern 39 | * Link to uses of the pattern within the source code 40 | 41 | ## Variants 42 | 43 | Link to any patterns that are varients of this 44 | 45 | ## Related Patterns 46 | 47 | Link to any related patterns 48 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/static_queue.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Static Queue 2 | 3 | Static (fixed size) queue for use on systems without dynamic memory allocation. 4 | 5 | **Status:** Completed 6 | 7 | **Table of Contents:** 8 | 9 | 1. [Responsibilities](#responsibilities) 10 | 2. [Requirements](#requirements) 11 | 3. [Collaborators](#collaborators) 12 | 4. [Rationale](#rationale) 13 | 5. [Source Links](#source-links) 14 | 6. [Related Documents](#related-documents) 15 | 7. [Notes](#notes) 16 | 17 | ## Responsibilities 18 | 19 | * Operate like `std::queue`, as a FIFO queue 20 | * Manage a fixed-size data buffer 21 | 22 | ## Requirements 23 | 24 | * Memory is statically allocated during creation 25 | * Cannot grow past the fixed-size limit 26 | * No exceptions 27 | 28 | ## Collaborators 29 | 30 | N/A 31 | 32 | ## Rationale 33 | 34 | Embedded systems often do not utilize dynamic memory allocation. An equivalent structure using static memory should be provided. 35 | 36 | ## Source Links 37 | 38 | This requirement is satisfied by the ETL datatypes: 39 | 40 | * [`etl::queue`](../../../../src/stdlibs/etl/include/etl/queue.h) 41 | * [`etl::list`](../../../../src/stdlibs/etl/include/etl/list.h) 42 | * [`etl::vector`](../../../../src/stdlibs/etl/include/etl/vector.h) 43 | 44 | ## Related Documents 45 | 46 | N/A 47 | 48 | ## Notes 49 | 50 | N/A 51 | -------------------------------------------------------------------------------- /docs/architecture/principles/0005-defend_the_decoupling_mechanisms.md: -------------------------------------------------------------------------------- 1 | # Principle: Defend the Decoupling Mechanisms 2 | 3 | **Name:** Defend the Decoupling Mechanisms 4 | 5 | Maintain the abstractions/layers. By preserving the separation of layers and using abstractions we maximize usability, portability, nad potential for reuse of our embedded software 6 | 7 | Preserve the platform as the mediator between hardware and software 8 | Tight coupling between HW/SW should be kept in the virtual platform abstraction 9 | 10 | ## Description 11 | 12 | * Statement of the principle 13 | * Clearly state the chosen direction 14 | 15 | ## Rationale/Benefits 16 | 17 | * Describe the reasoning behind the principle 18 | * Where appicable, provide traceability to business or architectural objectives 19 | 20 | ## Implications 21 | 22 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 23 | 24 | ## Counterforces 25 | 26 | What forces will push against this principle? 27 | 28 | * Speed 29 | * schedule pressure 30 | * avoiding extreme changes 31 | * convenience 32 | * abstractions are not obvious or easy to find 33 | 34 | ## Counterarguments 35 | 36 | * Describe the reasonable counter to this principle 37 | 38 | ## Scope 39 | 40 | * (Optional) 41 | * Indicate teh scope where this principle needs ot be applied 42 | -------------------------------------------------------------------------------- /docs/architecture/components/core/event.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Event 2 | 3 | Basic object prototype for a system event. 4 | 5 | **Status:** Completed, issues exist for dynamic memory allocations 6 | 7 | **Table of Contents:** 8 | 9 | 1. [Responsibilities](#responsibilities) 10 | 2. [Requirements](#requirements) 11 | 3. [Collaborators](#collaborators) 12 | 4. [Rationale](#rationale) 13 | 5. [Source Links](#source-links) 14 | 6. [Related Documents](#related-documents) 15 | 7. [Notes](#notes) 16 | 17 | ## Responsibilities 18 | 19 | * Represent an event in the system 20 | 21 | ## Requirements 22 | 23 | * Extensible so that users can derive additional types of events 24 | 25 | ## Collaborators 26 | 27 | * Events can be consumed by [Active Objects](active_object.md) and the [Event Center](../core/event_center.md) 28 | * Any part of the system can generate and post an event 29 | 30 | ## Rationale 31 | 32 | A central event representation is needed to represent signals with & without data. 33 | 34 | Event categories are unique and created according to a system's purpose. The event type should be extensible so that users can provide their own event definitions. 35 | 36 | ## Source Links 37 | 38 | * [event.hpp](../../../../src/core/platform/event.hpp) 39 | * [Unit Tests](../../../../src/core/platform/event_tests.cpp) 40 | 41 | ## Related Documents 42 | 43 | N/A 44 | 45 | ## Notes 46 | 47 | N/A 48 | -------------------------------------------------------------------------------- /src/utilities/tuple_array/tuple_array.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TUPLE_ARRAY_HPP_ 2 | #define TUPLE_ARRAY_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | namespace embutil 8 | { 9 | /** \defgroup Tuple-Array Conversion Utilities 10 | * 11 | * Functions that can be used to convert between tuples and arrays. 12 | * 13 | * @ingroup FrameworkUtils 14 | * @{ 15 | */ 16 | 17 | ///@name Tuple-Array Conversion Functions 18 | /// @brief Convert between tuples and arrays 19 | 20 | /** The implementation function that handles the actual conversion. 21 | * 22 | */ 23 | template 24 | auto tuple_to_array_impl(Tuple&& tup, std::integer_sequence) 25 | -> std::array 26 | { 27 | return {static_cast(std::get(tup))...}; 28 | } 29 | 30 | /** Convert a tuple into a std::array 31 | * 32 | * This function is the interface used to convert a std::tuple into a std::array. 33 | * 34 | * @returns an array containing the tuple elements. 35 | */ 36 | template 37 | auto tuple_to_array(std::tuple&& tup) -> std::array 38 | { 39 | return tuple_to_array_impl(std::move(tup), std::make_index_sequence{}); 40 | } 41 | 42 | /// @} 43 | // End tuple/array conversion module 44 | 45 | }; // end namespace embutil 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /docs/patterns/facade.md: -------------------------------------------------------------------------------- 1 | # Pattern: Façade 2 | 3 | Provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use. 4 | 5 | * **Classification:** TBD 6 | 7 | Gamma, Erich. Design Patterns: Elements of Reusable Object-Oriented Software (Addison-Wesley Professional Computing Series), pg 185 8 | 9 | ## Diagrams 10 | 11 | * Include / link to visual representations of this pattern 12 | 13 | ## Context 14 | 15 | * How does this pattern help to complete larger patterns? 16 | * What is the intent of this pattern? 17 | 18 | ## Problem 19 | 20 | * Two sentence description 21 | * Include example/motivation 22 | * Include the forces at play (applicability) 23 | * Follow with empirical background for the pattern 24 | * Evidence for validity 25 | * Range of valididty 26 | 27 | ## Solution 28 | 29 | * Stated as an instruction 30 | * Describe the structure, dynamics, and implementation heuristics 31 | 32 | ## Consequences 33 | 34 | * What are the benefits of using this pattern? 35 | * What are the liabilities with using this pattern? 36 | 37 | ## Known Uses 38 | 39 | * Describe known applications for this pattern 40 | * Link to uses of the pattern within the source code 41 | 42 | ## Variants 43 | 44 | Link to any patterns that are varients of this 45 | 46 | ## Related Patterns 47 | 48 | Link to any related patterns 49 | -------------------------------------------------------------------------------- /src/core/namespace_documentation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | /// Embedded framework core interfaces, classes, and definitions 5 | namespace embvm 6 | { 7 | /** @defgroup FrameworkCore Framework Core Components 8 | * 9 | * Classes, interfaces, and definitions related to the framework core components. 10 | */ 11 | 12 | /** @defgroup FrameworkDriver Framework Driver Infrastructure 13 | * 14 | * Driver base classes & definitions. 15 | * 16 | * @ingroup FrameworkCore 17 | */ 18 | 19 | /** @defgroup FrameworkHwPlatform Framework Hardware Platform Infrastructure 20 | * 21 | * Interfaces and components for building a virtual hardware platform. 22 | * 23 | * @ingroup FrameworkCore 24 | */ 25 | 26 | /** @defgroup FrameworkPlatform Framework Platform Infrastructure 27 | * 28 | * Interfaces and components for building a virtual platform. 29 | * 30 | * @ingroup FrameworkCore 31 | */ 32 | 33 | /** @defgroup FrameworkProcessor Framework Processor Infrastructure 34 | * 35 | * Interfaces and components for building a processor interface. 36 | * 37 | * @ingroup FrameworkCore 38 | */ 39 | 40 | /** @defgroup FrameworkOS Framework OS Infrastructure 41 | * 42 | * Interfaces and components for building a virtual OS 43 | * 44 | * @ingroup FrameworkCore 45 | */ 46 | 47 | } // namespace embvm 48 | -------------------------------------------------------------------------------- /docs/architecture/components/core/c_cpp_runtime.md: -------------------------------------------------------------------------------- 1 | # CRC-R: C/C++ Runtime 2 | 3 | The C/C++ runtime handles the setup of the C and C++ runtime environment and provides standard library functions expected by C and C++ developers. 4 | 5 | **Status:** Complete 6 | 7 | ## Responsibilities 8 | 9 | * Perform setup required by the C/C++ languages: 10 | * Clear `.bss` section contents 11 | * Call constructors & initializers 12 | * Initialize `argc` and `argv` (in our case, to 0 and `NULL`) 13 | * Provide runtime functionality required by the C/C++ library 14 | 15 | ## Requirements 16 | 17 | 1. Handle memory relocations 18 | 2. Zero-initialize the `.bss` section 19 | 3. Initialize the standard library runtime 20 | 5. Call constructors in the constructor segment 21 | 22 | ## Collaborators 23 | 24 | * The [Boot Sequencer](boot_sequencer.md) invokes C/C++ Runtime Startup process 25 | 26 | ## Rationale 27 | 28 | C and C++ applications require memory relocations, zero-initialization, and invoking static constructors prior to entering the `main()` function. Rather than making this part of the Boot Sequencer, it should be kept within the runtime to decouple the Boot Sequencer from the language runtime. 29 | 30 | ## Source Links 31 | 32 | * [libc](src/stdlibs/libc) 33 | * [libmemory](src/stdlibs/libmemory) 34 | * [libcpp](src/stdlibs/libcpp) - contains `libcxx` and `libcxxabi` 35 | 36 | ## Notes 37 | 38 | N/A 39 | -------------------------------------------------------------------------------- /docs/patterns/bridge.md: -------------------------------------------------------------------------------- 1 | # Pattern: Bridge 2 | 3 | Template for documenting architectural patterns used in this repository. Replace "Template" in the title with the pattern name 4 | 5 | * Include a summary description of this pattern 6 | * Include a brief classification of this pattern (Structural, Decoupling, etc.) 7 | 8 | 9 | We use the bridge pattern for our processor & OS abstractions 10 | 11 | 12 | ## Diagrams 13 | 14 | * Include / link to visual representations of this pattern 15 | 16 | ## Context 17 | 18 | * How does this pattern help to complete larger patterns? 19 | * What is the intent of this pattern? 20 | 21 | ## Problem 22 | 23 | * Two sentence description 24 | * Include example/motivation 25 | * Include the forces at play (applicability) 26 | * Follow with empirical background for the pattern 27 | * Evidence for validity 28 | * Range of valididty 29 | 30 | ## Solution 31 | 32 | * Stated as an instruction 33 | * Describe the structure, dynamics, and implementation heuristics 34 | 35 | ## Consequences 36 | 37 | * What are the benefits of using this pattern? 38 | * What are the liabilities with using this pattern? 39 | 40 | ## Known Uses 41 | 42 | * Describe known applications for this pattern 43 | * Link to uses of the pattern within the source code 44 | 45 | ## Variants 46 | 47 | Link to any patterns that are varients of this 48 | 49 | ## Related Patterns 50 | 51 | Link to any related patterns 52 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ISSUE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Report 3 | about: Use this template to report a problem 4 | title: "[VERSION] [PROBLEM SUMMARY]" 5 | labels: bug 6 | assignees: phillipjohnston 7 | --- 8 | 9 | ## Expected Behavior 10 | 11 | Please describe the behavior you are expecting 12 | 13 | ## Current Behavior 14 | 15 | What is the current behavior? 16 | 17 | ## Context 18 | 19 | Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions. 20 | 21 | * Project Version: 22 | * Operating System: 23 | * Toolchain: 24 | * Toolchain version: 25 | 26 | ## Failure Information (for bugs) 27 | 28 | Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template. 29 | 30 | ### Steps to Reproduce 31 | 32 | Please provide detailed steps for reproducing the issue. 33 | 34 | 1. step 1 35 | 2. step 2 36 | 3. you get it... 37 | 38 | ### Failure Logs 39 | 40 | Please include any relevant log snippets or files here. 41 | 42 | ## Checklist 43 | 44 | - [ ] I am running the latest version 45 | - [ ] I checked the documentation and found no answer 46 | - [ ] I checked to make sure that this issue has not already been filed 47 | - [ ] I'm reporting the issue to the correct repository (for multi-repository projects) 48 | - [ ] I have provided sufficient information for the team 49 | -------------------------------------------------------------------------------- /docs/architecture/principles/0004-avoid_closing_doors.md: -------------------------------------------------------------------------------- 1 | # Principle: Avoid Closing Doors 2 | 3 | **Name:** Avoid Closing Doors 4 | 5 | Prefer decisions which do not reduce the possible actions that can be taken in the future. This is not always possible, but we want to deliberate if a choice cuts off future decisions. 6 | 7 | We do not want to reduce the actions our client can take, or force them into a particular style. We want clients to be able to work in thier own style and as their system design dictacts. 8 | 9 | Our architectural decisiosn should not hinder our clients. 10 | 11 | ## Description 12 | 13 | * Statement of the principle 14 | * Clearly state the chosen direction 15 | 16 | ## Rationale/Benefits 17 | 18 | * Describe the reasoning behind the principle 19 | * Where appicable, provide traceability to business or architectural objectives 20 | 21 | ## Implications 22 | 23 | * Identify implications such as actions that need to be undertaken, and constrains implied by the principle 24 | 25 | ## Counterforces 26 | 27 | What forces will push against this principle? 28 | 29 | * Speed 30 | * schedule pressure 31 | * avoiding extreme changes 32 | * convenience 33 | * abstractions are not obvious or easy to find 34 | 35 | ## Counterarguments 36 | 37 | * Describe the reasonable counter to this principle 38 | 39 | ## Scope 40 | 41 | * (Optional) 42 | * Indicate teh scope where this principle needs ot be applied 43 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/transports.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Transports 2 | 3 | ## Responsibilities 4 | 5 | TBD 6 | 7 | ## Requirements 8 | 9 | TBD 10 | 11 | ## Collaborators 12 | 13 | TBD 14 | 15 | ## Rationale 16 | 17 | TBD 18 | 19 | ## Source Links 20 | 21 | TBD 22 | 23 | ## Notes 24 | 25 | Do transports and streams need to be split up? 26 | 27 | 28 | Transport = the mechanism of moving data across the buses. Hardware level. 29 | 30 | Stream - the data format as it's going across the transport 31 | Bytestream 32 | Datagram 33 | UDPErasureEncoding 34 | 35 | Buffered/Non-buffered transport concepts? or stream? 36 | 37 | Transports: 38 | * BytestreamTransport 39 | * UsbBytestream? 40 | * DatagramTransport 41 | * UDPErasureEncodingTransport 42 | * SocketTransport 43 | * BufferedStreamTransport 44 | * BufferedTransport 45 | 46 | Protocols: 47 | * InputBufferedStreamProtocol 48 | 49 | 50 | 51 | * Transport classes: 52 | * UART 53 | * USB 54 | * SPI 55 | * BT 56 | * I2C 57 | * NFC 58 | * Wifi 59 | * RFID 60 | * Buffered Decorator 61 | * Non-buffered decorator 62 | 63 | 64 | * Stream abstract class with subclasses 65 | * Memory stream 66 | * File stream 67 | * byte stream 68 | * Decorators for streams: 69 | * Compress 70 | * Decompress 71 | * Base64 encode / decode 72 | * Encrypt/decrypt 73 | 74 | 75 | Byte transport/stream (other transports/serializers?) 76 | -------------------------------------------------------------------------------- /docs/templates/architecture/pattern.md: -------------------------------------------------------------------------------- 1 | # Pattern: Template 2 | 3 | Template for documenting architectural patterns used in this repository. Replace "Template" in the title with the pattern name 4 | 5 | * Include a summary description of this pattern 6 | * Include a brief classification of this pattern (Structural, Decoupling, etc.) 7 | 8 | ## Diagrams 9 | 10 | * Include / link to visual representations of this pattern 11 | 12 | ## Context 13 | 14 | * How does this pattern help to complete larger patterns? 15 | * What is the intent of this pattern? 16 | 17 | ## Problem 18 | 19 | * Two sentence description 20 | * Include example/motivation 21 | * Include the forces at play (applicability) 22 | * Follow with empirical background for the pattern 23 | * Evidence for validity 24 | * Range of valididty 25 | 26 | ## Solution 27 | 28 | * Stated as an instruction 29 | * Describe the structure, dynamics, and implementation heuristics 30 | 31 | ## Consequences 32 | 33 | * What are the benefits of using this pattern? 34 | * What are the liabilities with using this pattern? 35 | 36 | ## Known Uses 37 | 38 | * Describe known applications for this pattern 39 | * Link to uses of the pattern within the source code 40 | 41 | ## Variants 42 | 43 | Link to any patterns that are varients of this 44 | 45 | ## Related Patterns 46 | 47 | Link to any related patterns 48 | 49 | ## References 50 | 51 | Where can readers find more information about this pattern or principle? 52 | 53 | ## Notes 54 | -------------------------------------------------------------------------------- /docs/architecture/components/utilities/interrupt_lock.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Interrupt Lock 2 | 3 | A locking object type which disables and enables interrupts. 4 | 5 | **Status:** Completed 6 | 7 | **Table of Contents:** 8 | 9 | 1. [Responsibilities](#responsibilities) 10 | 2. [Requirements](#requirements) 11 | 3. [Collaborators](#collaborators) 12 | 4. [Rationale](#rationale) 13 | 5. [Source Links](#source-links) 14 | 6. [Related Documents](#related-documents) 15 | 7. [Notes](#notes) 16 | 17 | ## Responsibilities 18 | 19 | * Disable and enable interrupts using a `BasicLockable` interface 20 | 21 | ## Requirements 22 | 23 | * `lock()` disables interrupts 24 | * `unlock()` enables interrupts 25 | * Users can supply enable/disable functions for use across a variety of platforms 26 | 27 | ## Collaborators 28 | 29 | * The [Interrupt Queue](interrupt_queue.md) uses an Interrupt Lock rather than a standard mutex 30 | 31 | ## Rationale 32 | 33 | C++ supplies nice locking types, such as `std::unique_lock`. Creating a `BasicLockable` class which can enable and disable interrupts allows us to take advantage of some of these types. 34 | 35 | ## Source Links 36 | 37 | * [Interrupt Lock Folder](../../../../src/utilities/interrupt_lock) 38 | * Interrupt Lock 39 | * [interrupt_lock_test.cpp](../../../../src/utilities/interrupt_lock/interrupt_lock_test.cpp) 40 | * [interrupt_lock.hpp](../../../../src/utilities/interrupt_lock/interrupt_lock.hpp) 41 | 42 | ## Related Documents 43 | 44 | N/A 45 | 46 | ## Notes 47 | 48 | N/A 49 | -------------------------------------------------------------------------------- /docs/architecture/decisions/0017-virtual-destructor-usage.md: -------------------------------------------------------------------------------- 1 | # 2. Virtual Destructor Usage 2 | 3 | Date: 2020-10-19 4 | 5 | ## Status 6 | 7 | Accepted 8 | 9 | ## Context 10 | 11 | When trying to link an embvm application that did not use any dynamic memory allocations, we failed to link because of a missing `free` symbol. This is because a virtual destructor in a base class was causing the compiler to generate a deleting destructor. 12 | 13 | ## Decision 14 | 15 | By default, make destructors in abstract classes protected and non-virtual. 16 | 17 | If you encounter a situation where you need to provide a virtual destructor (because you are destroying an object with a base class pointer), then you need to implement a default `operator delete` in your final class if dynamic memory management isn't used. 18 | 19 | If you don't expect a deleting destructor to be called (you would need to manually call `delete` on the base class), then trigger an assertion in case it is called. 20 | 21 | ``` 22 | void operator delete(void* p) 23 | { 24 | assert(0); // should not be called 25 | } 26 | ``` 27 | 28 | ## Consequences 29 | 30 | You cannot delete derived objects through base class interface pointers under the default case. 31 | 32 | ## Further Reading 33 | 34 | * [Herb Sutter: Virtuality](http://www.gotw.ca/publications/mill18.htm) 35 | * [Eli Bendersky: Deleting Destructors and Virtual `operator delete`](https://eli.thegreenplace.net/2015/c-deleting-destructors-and-virtual-operator-delete/) 36 | -------------------------------------------------------------------------------- /src/core/driver/hal_driver.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | #ifndef HAL_DRIVER_H_ 5 | #define HAL_DRIVER_H_ 6 | 7 | #include 8 | 9 | /// @addtogroup FrameworkDriver 10 | /// @{ 11 | 12 | namespace embvm 13 | { 14 | class HALDriverBase 15 | { 16 | public: 17 | void setBottomHalfDispatcher(const embutil::IRQDispatcherFunc_t& dispatcher) noexcept 18 | { 19 | dispatcher_ = dispatcher; 20 | } 21 | 22 | template 23 | void invokeCallback(TCallback& cb) noexcept 24 | { 25 | if(cb) 26 | { 27 | if(dispatcher_) 28 | { 29 | dispatcher_(cb); 30 | } 31 | else 32 | { 33 | cb(); 34 | } 35 | } 36 | } 37 | 38 | template 39 | void invokeCallback(TCallback& cb, TArgs&... args) noexcept 40 | { 41 | if(cb) 42 | { 43 | if(dispatcher_) 44 | { 45 | dispatcher_(std::bind(cb, args...)); 46 | } 47 | else 48 | { 49 | cb(args...); 50 | } 51 | } 52 | } 53 | 54 | virtual void enableInterrupts() noexcept = 0; 55 | virtual void disableInterrupts() noexcept = 0; 56 | 57 | protected: 58 | HALDriverBase() = default; 59 | virtual ~HALDriverBase() = default; 60 | 61 | embutil::IRQDispatcherFunc_t dispatcher_{}; // TODO: can we make this a reference somehow? 62 | }; 63 | 64 | } // namespace embvm 65 | 66 | /// @} 67 | // End Group 68 | 69 | #endif // HAL_DRIVER_H_ 70 | -------------------------------------------------------------------------------- /docs/architecture/use_cases/0010-compile_in_simulator_mode.md: -------------------------------------------------------------------------------- 1 | # Use Case: Compile in Simulator Mode 2 | 3 | * Name: Compile in Simulator Mode 4 | * Number: 0010 5 | 6 | **Table of Contents:** 7 | 1. [Description](#description) 8 | 2. [Actors](#actors) 9 | 3. [Preconditions](#preconditions) 10 | 4. [Postconditions](#postconditions) 11 | 5. [Assumptions](#assumptions) 12 | 6. [Steps](#steps) 13 | 7. [Variations](#variations) 14 | 8. [Non-functionals](#non-functionals) 15 | 9. [Business Rules](#business-rules) 16 | 10. [Architectural Mechanisms](#architectural-mechanisms) 17 | 11. [Issues](#issues) 18 | 12. [Related Use Cases](#related-use-cases) 19 | 20 | ## Description 21 | 22 | Developers should be able to select a subset of software to run in simulator mode on their host machine 23 | 24 | ## Actors 25 | 26 | * Developer 27 | 28 | ## Preconditions 29 | 30 | TBD 31 | 32 | ## Post-conditions 33 | 34 | * A binary is produced which will run the framework software on a host machine 35 | 36 | ## Assumptions 37 | 38 | TBD 39 | 40 | ## Steps 41 | 42 | TBD 43 | 44 | ## Variations 45 | 46 | TBD 47 | 48 | ## Non-functionals 49 | 50 | * [Extensibility](../qualities/0004-extensibility.md): 51 | * Developers should be able to add or remove software components that are executed on the host machine 52 | 53 | ## Business Rules 54 | 55 | N/A 56 | 57 | ## Architectural Mechanisms 58 | 59 | * [Build System](../components/build_system.md) 60 | * [Simulator Processor](../components/core/simulator_processor.md) 61 | 62 | ## Issues 63 | 64 | TBD 65 | 66 | ## Related Use Cases 67 | 68 | TBD 69 | -------------------------------------------------------------------------------- /docs/architecture/components/subsystems/logger.md: -------------------------------------------------------------------------------- 1 | # CRC-R: Logger 2 | 3 | **Status:** Completed 4 | 5 | **Table of Contents:** 6 | 7 | 1. [Responsibilities](#responsibilities) 8 | 2. [Requirements](#requirements) 9 | 3. [Collaborators](#collaborators) 10 | 4. [Rationale](#rationale) 11 | 5. [Source Links](#source-links) 12 | 6. [Related Documents](#related-documents) 13 | 7. [Notes](#notes) 14 | 15 | ## Responsibilities 16 | 17 | * Log data requested by a user to a specified location 18 | * Filter log calls by level 19 | 20 | ## Requirements 21 | 22 | * Logging level configurable at compile time 23 | * Logging level configurable at run-time (within compile-time limits) 24 | * Provide a way for users to specify a custom logging strategy (e.g., file, buffer, UART + buffer) 25 | 26 | ## Collaborators 27 | 28 | N/A 29 | 30 | ## Rationale 31 | 32 | Logging is a common debugging requirement in embedded systems. Why should we make developers spin their own loggers? 33 | 34 | In order to allow users to implement their own logging methods, the Logger will be implemented using the [Factory Method Pattern](../../patterns/factory_method.md) and the [Strategy Pattern](../../patterns/strategy.md). 35 | 36 | ## Source Links 37 | 38 | TBD 39 | 40 | ## Related Documents 41 | 42 | * [Factory Method Pattern](../../patterns/factory_method.md) 43 | * [Strategy Pattern](../../patterns/strategy.md) 44 | 45 | ## Notes 46 | 47 | Can we take advantage of Aspect Oriented Programming to insert logger code? 48 | 49 | 50 | Make log_if_true() and log_if_false() macros for my framework. make the logic disabled. 51 | -------------------------------------------------------------------------------- /src/os/posix/posix_os.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Embedded Artistry LLC 2 | // SPDX-License-Identifier: GPL-3.0-only OR Embedded Virtual Machine Commercial License 3 | 4 | // clang-format off 5 | #include // We need time.h before os.hpp for Linux builds because of system header types... 6 | // clang-format on 7 | #include "os.hpp" 8 | #include